static void locate_pointer_paint (GsdLocatePointerData *data, cairo_t *cr, gboolean composite) { GdkRGBA color; gdouble progress, circle_progress; gint width, height, i; GtkStyleContext *context; progress = data->progress; width = gdk_window_get_width (data->window); height = gdk_window_get_height (data->window); context = gtk_widget_get_style_context (data->widget); gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED, &color); cairo_set_source_rgba (cr, 1., 1., 1., 0.); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); for (i = 0; i <= N_CIRCLES; i++) { if (progress < 0.) break; circle_progress = MIN (1., (progress * 2)); progress -= CIRCLES_PROGRESS_INTERVAL; if (circle_progress >= 1.) continue; if (composite) { cairo_set_source_rgba (cr, color.red, color.green, color.blue, 1 - circle_progress); cairo_arc (cr, width / 2, height / 2, circle_progress * width / 2, 0, 2 * G_PI); cairo_fill (cr); } else { cairo_set_source_rgb (cr, 0., 0., 0.); cairo_set_line_width (cr, 3.); cairo_arc (cr, width / 2, height / 2, circle_progress * width / 2, 0, 2 * G_PI); cairo_stroke (cr); cairo_set_source_rgb (cr, 1., 1., 1.); cairo_set_line_width (cr, 1.); cairo_arc (cr, width / 2, height / 2, circle_progress * width / 2, 0, 2 * G_PI); cairo_stroke (cr); } } }
static void clearlooks_glossy_draw_progressbar_fill (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *params, const ProgressBarParameters *progressbar, int x, int y, int width, int height, gint offset) { boolean is_horizontal = progressbar->orientation < 2; double tile_pos = 0; double stroke_width; double radius; int x_step; cairo_pattern_t *pattern; CairoColor a; CairoColor b; CairoColor e; CairoColor border; CairoColor shadow; radius = MAX (0, params->radius - params->xthickness); cairo_save (cr); if (!is_horizontal) ge_cairo_exchange_axis (cr, &x, &y, &width, &height); if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP)) ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height); /* Clamp the radius so that the _height_ fits ... */ radius = MIN (radius, height / 2.0); stroke_width = height*2; x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */ cairo_translate (cr, x, y); cairo_save (cr); /* This is kind of nasty ... Clip twice from each side in case the length * of the fill is smaller than twice the radius. */ ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); cairo_clip (cr); ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); cairo_clip (cr); /* Draw the background gradient */ ge_shade_color (&colors->spot[1], 1.16, &a); ge_shade_color (&colors->spot[1], 1.08, &b); ge_shade_color (&colors->spot[1], 1.08, &e); pattern = cairo_pattern_create_linear (0, 0, 0, height); cairo_pattern_add_color_stop_rgb (pattern, 0.0, a.r, a.g, a.b); cairo_pattern_add_color_stop_rgb (pattern, 0.5, b.r, b.g, b.b); cairo_pattern_add_color_stop_rgb (pattern, 0.5, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b); cairo_pattern_add_color_stop_rgb (pattern, 1.0, e.r, e.g, e.b); cairo_set_source (cr, pattern); cairo_paint (cr); cairo_pattern_destroy (pattern); /* Draw the Strokes */ while (stroke_width > 0 && tile_pos <= width+x_step) { cairo_move_to (cr, stroke_width/2-x_step, 0); cairo_line_to (cr, stroke_width-x_step, 0); cairo_line_to (cr, stroke_width/2-x_step, height); cairo_line_to (cr, -x_step, height); cairo_translate (cr, stroke_width, 0); tile_pos += stroke_width; } cairo_set_source_rgba (cr, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0.15); cairo_fill (cr); cairo_restore (cr); /* rounded clip region */ /* inner highlight border * This is again kinda ugly. Draw once from each side, clipping away the other. */ cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.3); /* left side */ cairo_save (cr); cairo_rectangle (cr, 0, 0, width / 2, height); cairo_clip (cr); if (progressbar->pulsing) ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); else ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); cairo_stroke (cr); cairo_restore (cr); /* clip */ /* right side */ cairo_save (cr); cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height); cairo_clip (cr); if (progressbar->value < 1.0 || progressbar->pulsing) ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); else ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); cairo_stroke (cr); cairo_restore (cr); /* clip */ /* Draw the dark lines and the shadow */ cairo_save (cr); /* Again, this weird clip area. */ ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); cairo_clip (cr); ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); cairo_clip (cr); border = colors->spot[2]; border.a = 0.5; ge_shade_color (&colors->shade[6], 0.92, &shadow); shadow.a = 0.2; if (progressbar->pulsing) { /* At the beginning of the bar. */ cairo_move_to (cr, 0.5 + radius, height + 0.5); ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); ge_cairo_set_color (cr, &border); cairo_stroke (cr); cairo_move_to (cr, -0.5 + radius, height + 0.5); ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); ge_cairo_set_color (cr, &shadow); cairo_stroke (cr); } if (progressbar->value < 1.0 || progressbar->pulsing) { /* At the end of the bar. */ cairo_move_to (cr, width - 0.5 - radius, -0.5); ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); ge_cairo_set_color (cr, &border); cairo_stroke (cr); cairo_move_to (cr, width + 0.5 - radius, -0.5); ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); ge_cairo_set_color (cr, &shadow); cairo_stroke (cr); } cairo_restore (cr); cairo_restore (cr); /* rotation, mirroring */ }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* cr = context->platformContext(); cairo_save(cr); cairo_set_scaled_font(cr, font->platformData().scaledFont()); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); float offset = 0.0f; for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = 0.0f; offset += glyphBuffer.advanceAt(from + i); } Color fillColor = context->fillColor(); // Synthetic Oblique if(font->platformData().syntheticOblique()) { cairo_matrix_t mat = {1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, point.x(), point.y()}; cairo_transform(cr, &mat); } else { cairo_translate(cr, point.x(), point.y()); } // Text shadow, inspired by FontMac IntSize shadowSize; int shadowBlur = 0; Color shadowColor; bool hasShadow = context->textDrawingMode() == cTextFill && context->getShadow(shadowSize, shadowBlur, shadowColor); // TODO: Blur support if (hasShadow) { // Disable graphics context shadows (not yet implemented) and paint them manually context->clearShadow(); Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); cairo_save(cr); float red, green, blue, alpha; shadowFillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); #if ENABLE(FILTERS) cairo_text_extents_t extents; cairo_scaled_font_glyph_extents(font->platformData().scaledFont(), glyphs, numGlyphs, &extents); FloatRect rect(FloatPoint(), FloatSize(extents.width, extents.height)); IntSize shadowBufferSize; FloatRect shadowRect; float kernelSize = 0.f; GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur); // Draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); GraphicsContext* shadowContext = shadowBuffer->context(); cairo_t* shadowCr = shadowContext->platformContext(); cairo_translate(shadowCr, kernelSize, extents.height + kernelSize); cairo_set_scaled_font(shadowCr, font->platformData().scaledFont()); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(shadowCr); cairo_translate(shadowCr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); cairo_restore(shadowCr); } cairo_translate(cr, 0.0, -extents.height); context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize); #else cairo_translate(cr, shadowSize.width(), shadowSize.height()); cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } #endif cairo_restore(cr); } if (context->textDrawingMode() & cTextFill) { if (context->fillGradient()) { cairo_set_source(cr, context->fillGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->fillPattern()) { AffineTransform affine; cairo_set_source(cr, context->fillPattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { float red, green, blue, alpha; fillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } } if (context->textDrawingMode() & cTextStroke) { if (context->strokeGradient()) { cairo_set_source(cr, context->strokeGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->strokePattern()) { AffineTransform affine; cairo_set_source(cr, context->strokePattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { Color strokeColor = context->strokeColor(); float red, green, blue, alpha; strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_glyph_path(cr, glyphs, numGlyphs); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Re-enable the platform shadow we disabled earlier if (hasShadow) context->setShadow(shadowSize, shadowBlur, shadowColor, DeviceColorSpace); cairo_restore(cr); }
static void expose_filemanager (dt_view_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_library_t *lib = (dt_library_t *)self->data; gboolean offset_changed = FALSE; /* query new collection count */ lib->collection_count = dt_collection_get_count (darktable.collection); if(darktable.gui->center_tooltip == 1) darktable.gui->center_tooltip = 2; /* get grid stride */ const int iir = dt_conf_get_int("plugins/lighttable/images_in_row"); /* get image over id */ lib->image_over = DT_VIEW_DESERT; int32_t mouse_over_id, mouse_over_group = -1; DT_CTL_GET_GLOBAL(mouse_over_id, lib_image_mouse_over_id); /* fill background */ cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); if(lib->first_visible_zoomable >= 0) { lib->offset = lib->first_visible_zoomable; } lib->first_visible_zoomable = -1; /* check if offset has been changed */ if(lib->track > 2) lib->offset += iir; if(lib->track < -2) lib->offset -= iir; lib->track = 0; if(lib->center) lib->offset = 0; lib->center = 0; int offset = lib->offset; /* if offset differs then flag as changed */ if (offset != lib->first_visible_filemanager) offset_changed = TRUE; lib->first_visible_filemanager = offset; static int oldpan = 0; const int pan = lib->pan; const float wd = width/(float)iir; const float ht = width/(float)iir; int pi = pointerx / (float)wd; int pj = pointery / (float)ht; if(pointerx < 0 || pointery < 0) pi = pj = -1; //const int pidx = grid_to_index(pj, pi, iir, offset); const int img_pointerx = iir == 1 ? pointerx : fmodf(pointerx, wd); const int img_pointery = iir == 1 ? pointery : fmodf(pointery, ht); const int max_rows = 1 + (int)((height)/ht + .5); const int max_cols = iir; int id; int clicked1 = (oldpan == 0 && pan == 1 && lib->button == 1); /* get the count of current collection */ if(lib->collection_count == 0) { const float fs = 15.0f; const float ls = 1.5f*fs; const float offy = height*0.2f; const float offx = 60; const float at = 0.3f; cairo_set_font_size(cr, fs); cairo_set_source_rgba(cr, .7, .7, .7, 1.0f); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_move_to(cr, offx, offy); cairo_show_text(cr, _("there are no images in this collection")); cairo_move_to(cr, offx, offy + 2*ls); cairo_show_text(cr, _("if you have not imported any images yet")); cairo_move_to(cr, offx, offy + 3*ls); cairo_show_text(cr, _("you can do so in the import module")); cairo_move_to(cr, offx - 10.0f, offy + 3*ls - ls*.25f); cairo_line_to(cr, 0.0f, 10.0f); cairo_set_source_rgba(cr, .7, .7, .7, at); cairo_stroke(cr); cairo_move_to(cr, offx, offy + 5*ls); cairo_set_source_rgba(cr, .7, .7, .7, 1.0f); cairo_show_text(cr, _("try to relax the filter settings in the top panel")); cairo_rel_move_to(cr, 10.0f, -ls*.25f); cairo_line_to(cr, width*0.5f, 0.0f); cairo_set_source_rgba(cr, .7, .7, .7, at); cairo_stroke(cr); cairo_move_to(cr, offx, offy + 6*ls); cairo_set_source_rgba(cr, .7, .7, .7, 1.0f); cairo_show_text(cr, _("or add images in the collection module in the left panel")); cairo_move_to(cr, offx - 10.0f, offy + 6*ls - ls*0.25f); cairo_rel_line_to(cr, - offx + 10.0f, 0.0f); cairo_set_source_rgba(cr, .7, .7, .7, at); cairo_stroke(cr); return; } /* do we have a main query collection statement */ if(!lib->statements.main_query) return; if(offset < 0) lib->offset = offset = 0; while(offset >= lib->collection_count) lib->offset = (offset -= iir); /* update scroll borders */ dt_view_set_scrollbar(self, 0, 1, 1, offset, lib->collection_count, max_rows*iir); /* let's reset and reuse the main_query statement */ DT_DEBUG_SQLITE3_CLEAR_BINDINGS(lib->statements.main_query); DT_DEBUG_SQLITE3_RESET(lib->statements.main_query); /* setup offset and row for the main query */ DT_DEBUG_SQLITE3_BIND_INT(lib->statements.main_query, 1, offset); DT_DEBUG_SQLITE3_BIND_INT(lib->statements.main_query, 2, max_rows*iir); if(mouse_over_id != -1) { const dt_image_t *mouse_over_image = dt_image_cache_read_get(darktable.image_cache, mouse_over_id); mouse_over_group = mouse_over_image->group_id; dt_image_cache_read_release(darktable.image_cache, mouse_over_image); DT_DEBUG_SQLITE3_CLEAR_BINDINGS(lib->statements.is_grouped); DT_DEBUG_SQLITE3_RESET(lib->statements.is_grouped); DT_DEBUG_SQLITE3_BIND_INT(lib->statements.is_grouped, 1, mouse_over_group); DT_DEBUG_SQLITE3_BIND_INT(lib->statements.is_grouped, 2, mouse_over_id); if(sqlite3_step(lib->statements.is_grouped) != SQLITE_ROW) mouse_over_group = -1; } // prefetch the ids so that we can peek into the future to see if there are adjacent images in the same group. int *query_ids = (int*)calloc(max_rows*max_cols, sizeof(int)); if(!query_ids) goto after_drawing; for(int row = 0; row < max_rows; row++) { for(int col = 0; col < max_cols; col++) { if(sqlite3_step(lib->statements.main_query) == SQLITE_ROW) query_ids[row*iir+col] = sqlite3_column_int(lib->statements.main_query, 0); else goto end_query_cache; } } end_query_cache: cairo_save(cr); for(int row = 0; row < max_rows; row++) { for(int col = 0; col < max_cols; col++) { //curidx = grid_to_index(row, col, iir, offset); id = query_ids[row*iir+col]; if(id > 0) { if (iir == 1 && row) continue; /* set mouse over id if pointer is in current row / col */ if(pi == col && pj == row) { mouse_over_id = id; DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, mouse_over_id); } /* handle mouse click on current row / col this could easily and preferable be moved to button_pressed() */ if (clicked1 && (pi == col && pj == row)) { if ((lib->modifiers & (GDK_SHIFT_MASK|GDK_CONTROL_MASK)) == 0) dt_selection_select_single(darktable.selection, id); else if ((lib->modifiers & (GDK_CONTROL_MASK)) == GDK_CONTROL_MASK) dt_selection_toggle(darktable.selection, id); else if ((lib->modifiers & (GDK_SHIFT_MASK)) == GDK_SHIFT_MASK) dt_selection_select_range(darktable.selection, id); } cairo_save(cr); // if(iir == 1) dt_image_prefetch(image, DT_IMAGE_MIPF); dt_view_image_expose(&(lib->image_over), id, cr, wd, iir == 1 ? height : ht, iir, img_pointerx, img_pointery); cairo_restore(cr); } else goto escape_image_loop; cairo_translate(cr, wd, 0.0f); } cairo_translate(cr, -max_cols*wd, ht); } escape_image_loop: cairo_restore(cr); // and now the group borders cairo_save(cr); for(int row = 0; row < max_rows; row++) { for(int col = 0; col < max_cols; col++) { id = query_ids[row*iir+col]; if(id > 0) { const dt_image_t *image = dt_image_cache_read_get(darktable.image_cache, id); int group_id = -1; if(image) group_id = image->group_id; dt_image_cache_read_release(darktable.image_cache, image); if (iir == 1 && row) continue; cairo_save(cr); gboolean paint_border = FALSE; // regular highlight border if(group_id != -1) { if(mouse_over_group == group_id && iir > 1 && ((!darktable.gui->grouping && dt_conf_get_bool("plugins/lighttable/draw_group_borders")) || group_id == darktable.gui->expanded_group_id)) { cairo_set_source_rgb(cr, 1, 0.8, 0); paint_border = TRUE; } // border of expanded group else if(darktable.gui->grouping && group_id == darktable.gui->expanded_group_id && iir > 1) { cairo_set_source_rgb(cr, 0, 0, 1); paint_border = TRUE; } } if(paint_border) { int neighbour_group = -1; // top border if(row > 0) { int _id = query_ids[(row-1)*iir+col]; if(_id > 0) { const dt_image_t *_img = dt_image_cache_read_get(darktable.image_cache, _id); neighbour_group = _img->group_id; dt_image_cache_read_release(darktable.image_cache, _img); } } if(neighbour_group != group_id) { cairo_move_to(cr, 0, 0); cairo_line_to(cr, wd, 0); } // left border neighbour_group = -1; if(col > 0) { int _id = query_ids[row*iir+(col-1)]; if(_id > 0) { const dt_image_t *_img = dt_image_cache_read_get(darktable.image_cache, _id); neighbour_group = _img->group_id; dt_image_cache_read_release(darktable.image_cache, _img); } } if(neighbour_group != group_id) { cairo_move_to(cr, 0, 0); cairo_line_to(cr, 0, ht); } // bottom border neighbour_group = -1; if(row < max_rows-1) { int _id = query_ids[(row+1)*iir+col]; if(_id > 0) { const dt_image_t *_img = dt_image_cache_read_get(darktable.image_cache, _id); neighbour_group = _img->group_id; dt_image_cache_read_release(darktable.image_cache, _img); } } if(neighbour_group != group_id) { cairo_move_to(cr, 0, ht); cairo_line_to(cr, wd, ht); } // right border neighbour_group = -1; if(col < max_cols-1) { int _id = query_ids[row*iir+(col+1)]; if(_id > 0) { const dt_image_t *_img = dt_image_cache_read_get(darktable.image_cache, _id); neighbour_group = _img->group_id; dt_image_cache_read_release(darktable.image_cache, _img); } } if(neighbour_group != group_id) { cairo_move_to(cr, wd, 0); cairo_line_to(cr, wd, ht); } cairo_set_line_width(cr, 0.01*wd); cairo_stroke(cr); } cairo_restore(cr); } else goto escape_border_loop; cairo_translate(cr, wd, 0.0f); } cairo_translate(cr, -max_cols*wd, ht); } escape_border_loop: cairo_restore(cr); after_drawing: /* check if offset was changed and we need to prefetch thumbs */ if (offset_changed) { int32_t imgids_num = 0; const int prefetchrows = .5*max_rows+1; int32_t imgids[prefetchrows*iir]; /* clear and reset main query */ DT_DEBUG_SQLITE3_CLEAR_BINDINGS(lib->statements.main_query); DT_DEBUG_SQLITE3_RESET(lib->statements.main_query); /* setup offest and row for prefetch */ DT_DEBUG_SQLITE3_BIND_INT(lib->statements.main_query, 1, offset + max_rows*iir); DT_DEBUG_SQLITE3_BIND_INT(lib->statements.main_query, 2, prefetchrows*iir); // prefetch jobs in inverse order: supersede previous jobs: most important last while(sqlite3_step(lib->statements.main_query) == SQLITE_ROW && imgids_num < prefetchrows*iir) imgids[imgids_num++] = sqlite3_column_int(lib->statements.main_query, 0); float imgwd = iir == 1 ? 0.97 : 0.8; dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size( darktable.mipmap_cache, imgwd*wd, imgwd*(iir==1?height:ht)); while(imgids_num > 0) { imgids_num --; dt_mipmap_buffer_t buf; dt_mipmap_cache_read_get( darktable.mipmap_cache, &buf, imgids[imgids_num], mip, DT_MIPMAP_PREFETCH); } } if(query_ids) free(query_ids); oldpan = pan; if(darktable.unmuted & DT_DEBUG_CACHE) dt_mipmap_cache_print(darktable.mipmap_cache); if(darktable.gui->center_tooltip == 1) // set in this round { char* tooltip = dt_history_get_items_as_string(mouse_over_id); if(tooltip != NULL) { g_object_set(G_OBJECT(dt_ui_center(darktable.gui->ui)), "tooltip-text", tooltip, (char *)NULL); g_free(tooltip); } } else if(darktable.gui->center_tooltip == 2) // not set in this round { darktable.gui->center_tooltip = 0; g_object_set(G_OBJECT(dt_ui_center(darktable.gui->ui)), "tooltip-text", "", (char *)NULL); } }
static void clearlooks_glossy_draw_list_view_header (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *params, const ListViewHeaderParameters *header, int x, int y, int width, int height) { /* CairoColor *border = !params->prelight? (CairoColor*)&colors->shade[4] : (CairoColor*)&colors->spot[1]; */ const CairoColor *border = &colors->shade[4]; const CairoColor *fill = &colors->bg[params->state_type]; CairoColor hilight; CairoColor shade1, shade2, shade3; cairo_pattern_t *pattern; ge_shade_color (fill, 1.2, &hilight); ge_shade_color (fill, 1.08, &shade1); ge_shade_color (fill, 1.04, &shade2); ge_shade_color (fill, 1.04, &shade3); cairo_translate (cr, x, y); cairo_set_line_width (cr, 1.0); /* Draw the fill */ pattern = cairo_pattern_create_linear (0, 0, 0, height); cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b); cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, shade3.r, shade3.g, shade3.b); cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, border->r, border->g, border->b); cairo_pattern_add_color_stop_rgb (pattern, 1.0, border->r, border->g, border->b); cairo_set_source (cr, pattern); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); cairo_pattern_destroy (pattern); /* Draw highlight */ if (header->order & CL_ORDER_FIRST) { cairo_move_to (cr, 0.5, height-1); cairo_line_to (cr, 0.5, 0.5); } else cairo_move_to (cr, 0.0, 0.5); cairo_line_to (cr, width, 0.5); cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); cairo_stroke (cr); /* Draw resize grip */ if ((params->ltr && !(header->order & CL_ORDER_LAST)) || (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable) { SeparatorParameters separator; separator.horizontal = FALSE; if (params->ltr) params->style_functions->draw_separator (cr, colors, params, &separator, width-1.5, 4.0, 2, height-8.0); else params->style_functions->draw_separator (cr, colors, params, &separator, 1.5, 4.0, 2, height-8.0); } }
imageObj* createImageCairo(int width, int height, outputFormatObj *format,colorObj* bg) { imageObj *image = NULL; cairo_renderer *r=NULL; if (format->imagemode != MS_IMAGEMODE_RGB && format->imagemode!= MS_IMAGEMODE_RGBA) { msSetError(MS_MISCERR, "Cairo driver only supports RGB or RGBA pixel models.","msImageCreateCairo()"); return image; } if (width > 0 && height > 0) { image = (imageObj *) calloc(1, sizeof(imageObj)); r = (cairo_renderer*)calloc(1,sizeof(cairo_renderer)); if(!strcasecmp(format->driver,"cairo/pdf")) { r->outputStream = (bufferObj*)malloc(sizeof(bufferObj)); msBufferInit(r->outputStream); r->surface = cairo_pdf_surface_create_for_stream( _stream_write_fn, r->outputStream, width,height); } else if(!strcasecmp(format->driver,"cairo/svg")) { r->outputStream = (bufferObj*)malloc(sizeof(bufferObj)); msBufferInit(r->outputStream); r->surface = cairo_svg_surface_create_for_stream( _stream_write_fn, r->outputStream, width,height); } else if(!strcasecmp(format->driver,"cairo/winGDI") && format->device) { #if CAIRO_HAS_WIN32_SURFACE r->outputStream = NULL; r->surface = cairo_win32_surface_create(format->device); #else msSetError(MS_RENDERERERR, "Cannot create cairo image. Cairo was not compiled with support for the win32 backend.", "msImageCreateCairo()"); #endif } else if(!strcasecmp(format->driver,"cairo/winGDIPrint") && format->device) { #if CAIRO_HAS_WIN32_SURFACE r->outputStream = NULL; r->surface = cairo_win32_printing_surface_create(format->device); #else msSetError(MS_RENDERERERR, "Cannot create cairo image. Cairo was not compiled with support for the win32 backend.", "msImageCreateCairo()"); #endif } else { r->outputStream = NULL; r->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); } r->cr = cairo_create(r->surface); if(format->transparent || !bg || !MS_VALID_COLOR(*bg)) { r->use_alpha = 1; cairo_set_source_rgba (r->cr, 0,0,0,0); } else { r->use_alpha = 0; msCairoSetSourceColor(r->cr,bg); } cairo_save (r->cr); cairo_set_operator (r->cr, CAIRO_OPERATOR_SOURCE); cairo_paint (r->cr); cairo_restore (r->cr); cairo_set_line_cap (r->cr,CAIRO_LINE_CAP_ROUND); cairo_set_line_join(r->cr,CAIRO_LINE_JOIN_ROUND); image->img.plugin = (void*)r; } else { msSetError(MS_RENDERERERR, "Cannot create cairo image of size %dx%d.", "msImageCreateCairo()", width, height); } return image; }
void cairo_context::set_color(double r, double g, double b, double opacity) { // http://lists.cairographics.org/archives/cairo/2008-August/014759.html cairo_set_source_rgba(cairo_.get(), r, g, b, opacity); check_object_status_and_throw_exception(*this); }
static void set_translucent_pattern (cairo_t *cr, int x, int y) { cairo_set_source_rgba (cr, 1, 0, 0, 0.5); }
/* * 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 flush() { cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_A8, _totalWidth, _maxHeight); cairo_t *cr = cairo_create(surface); int pos = 0; cairo_set_source_rgba (cr, 0., 0., 0., 0); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_font_options_t *fontOptions = cairo_font_options_create(); cairo_get_font_options(cr, fontOptions); cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL); cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_GRAY); cairo_set_font_options(cr, fontOptions); cairo_font_options_destroy(fontOptions); cairo_set_source_rgba(cr, 1, 1, 1, 1); for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end(); ++it) { cairo_move_to(cr, pos - it->xBearing, -it->yBearing); cairo_set_font_size(cr, it->fontSize); cairo_set_font_face(cr, it->fontFace); cairo_show_text(cr, it->text.c_str()); cairo_font_face_destroy(it->fontFace); pos += it->width; } cairo_destroy(cr); //setup matrices GLint matrixMode; GLuint textureId; glGetIntegerv (GL_MATRIX_MODE, &matrixMode); glMatrixMode (GL_PROJECTION); glPushMatrix(); glLoadIdentity (); glMatrixMode (GL_MODELVIEW); glPushMatrix(); glLoadIdentity (); float winw = Fl_Window::current()->w(); float winh = Fl_Window::current()->h(); glScalef (2.0f / winw, 2.0f / winh, 1.0f); glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f); //write the texture on screen glEnable(GL_TEXTURE_RECTANGLE_ARB); glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureId); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA, cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface), 0, GL_ALPHA, GL_UNSIGNED_BYTE, cairo_image_surface_get_data(surface)); //glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SRC0_ALPHA); //printf("error %i %s\n", __LINE__, gluErrorString(glGetError())); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pos = 0; for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end(); ++it) { glTranslatef(it->x, it->y, it->z); glColor4f(it->r, it->g, it->b, it->alpha); int Lx = it->width; int Ly = it->height; glBegin (GL_QUADS); glTexCoord2f (pos, 0); glVertex2f (0.0f, Ly); glTexCoord2f (pos + Lx, 0); glVertex2f (Lx, Ly); glTexCoord2f (pos + Lx, Ly); glVertex2f (Lx, 0.0f); glTexCoord2f (pos, Ly); glVertex2f (0.0f, 0.0f); glEnd (); pos += Lx; glTranslatef(-it->x, -it->y, -it->z); } glDeleteTextures(1, &textureId); glPopAttrib(); // reset original matrices glPopMatrix(); // GL_MODELVIEW glMatrixMode (GL_PROJECTION); glPopMatrix(); glMatrixMode (matrixMode); _elements.clear(); _maxHeight = 0; _totalWidth = 0; cairo_surface_destroy(surface); }
static gboolean lowlight_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_lowlight_gui_data_t *c = (dt_iop_lowlight_gui_data_t *)self->gui_data; dt_iop_lowlight_params_t p = *(dt_iop_lowlight_params_t *)self->params; dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); const int inset = DT_IOP_LOWLIGHT_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); cairo_set_source_rgb(cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2 * inset; height -= 2 * inset; cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0)); cairo_set_source_rgb(cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); cairo_set_source_rgb(cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); // draw grid cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(.4)); cairo_set_source_rgb(cr, .1, .1, .1); dt_draw_grid(cr, 8, 0, 0, width, height); if(c->mouse_y > 0 || c->dragging) { // draw min/max curves: dt_iop_lowlight_get_params(&p, c->mouse_x, 1., c->mouse_radius); dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_min_xs, c->draw_min_ys); p = *(dt_iop_lowlight_params_t *)self->params; dt_iop_lowlight_get_params(&p, c->mouse_x, .0, c->mouse_radius); dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_max_xs, c->draw_max_ys); } cairo_save(cr); // draw x positions cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); const float arrw = DT_PIXEL_APPLY_DPI(7.0f); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) { cairo_move_to(cr, width * p.transition_x[k], height + inset - DT_PIXEL_APPLY_DPI(1)); cairo_rel_line_to(cr, -arrw * .5f, 0); cairo_rel_line_to(cr, arrw * .5f, -arrw); cairo_rel_line_to(cr, arrw * .5f, arrw); cairo_close_path(cr); if(c->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } // draw selected cursor cairo_translate(cr, 0, height); // cairo_set_operator(cr, CAIRO_OPERATOR_ADD); // cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.)); cairo_set_source_rgba(cr, .7, .7, .7, 1.0); p = *(dt_iop_lowlight_params_t *)self->params; dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_xs, c->draw_ys); cairo_move_to(cr, 0 * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[0]); for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[k]); cairo_stroke(cr); // draw dots on knots cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) { cairo_arc(cr, width * p.transition_x[k], -height * p.transition_y[k], DT_PIXEL_APPLY_DPI(3.0), 0.0, 2.0 * M_PI); if(c->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } if(c->mouse_y > 0 || c->dragging) { // draw min/max, if selected cairo_set_source_rgba(cr, .7, .7, .7, .6); cairo_move_to(cr, 0, -height * c->draw_min_ys[0]); for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_min_ys[k]); for(int k = DT_IOP_LOWLIGHT_RES - 1; k >= 0; k--) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_max_ys[k]); cairo_close_path(cr); cairo_fill(cr); // draw mouse focus circle cairo_set_source_rgba(cr, .9, .9, .9, .5); const float pos = DT_IOP_LOWLIGHT_RES * c->mouse_x; int k = (int)pos; const float f = k - pos; if(k >= DT_IOP_LOWLIGHT_RES - 1) k = DT_IOP_LOWLIGHT_RES - 2; float ht = -height * (f * c->draw_ys[k] + (1 - f) * c->draw_ys[k + 1]); cairo_arc(cr, c->mouse_x * width, ht, c->mouse_radius * width, 0, 2. * M_PI); cairo_stroke(cr); } cairo_restore(cr); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // draw labels: PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); pango_font_description_set_absolute_size(desc,(.06 * height) * PANGO_SCALE); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, desc); cairo_set_source_rgb(cr, .1, .1, .1); pango_layout_set_text(layout, _("dark"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .02 * width - ink.y, .5 * (height + ink.width)); cairo_save(cr); cairo_rotate(cr, -M_PI * .5f); pango_cairo_show_layout(cr, layout); cairo_restore(cr); pango_layout_set_text(layout, _("bright"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .98 * width - ink.height, .5 * (height + ink.width)); cairo_save(cr); cairo_rotate(cr, -M_PI * .5f); pango_cairo_show_layout(cr, layout); cairo_restore(cr); pango_layout_set_text(layout, _("day vision"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .5 * (width - ink.width), .08 * height - ink.height); pango_cairo_show_layout(cr, layout); pango_layout_set_text(layout, _("night vision"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .5 * (width - ink.width), .97 * height - ink.height); pango_cairo_show_layout(cr, layout); pango_font_description_free(desc); g_object_unref(layout); cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
static void osd_render_toggle(osm_gps_map_osd_t *osd) { osd_priv_t *priv = (osd_priv_t*)osd->priv; g_assert(priv->select_toggle.surface); /* first fill with transparency */ cairo_t *cr = cairo_create(priv->select_toggle.surface); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0); cairo_paint(cr); /* now start painting on top */ cairo_set_operator(cr, CAIRO_OPERATOR_OVER); /* draw dark transparent background for right border */ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.5); cairo_move_to (cr, OSD_W, 0); cairo_line_to (cr, CRAD, 0); cairo_arc_negative (cr, CRAD, CRAD, CRAD, -M_PI/2, M_PI); cairo_line_to (cr, 0, OSD_H-CRAD); cairo_arc_negative (cr, CRAD, OSD_H-CRAD, CRAD, M_PI, M_PI/2); cairo_line_to (cr, OSD_W, OSD_H); cairo_close_path (cr); cairo_fill(cr); #if 0 #define IBORDER (ICON_BORDER/2) #define IRAD (CRAD/2) /* highlight one icon */ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5); cairo_move_to (cr, IBORDER+IRAD, (priv->select_toggle.state?OSD_W:0)+IBORDER); cairo_line_to (cr, OSD_W-IBORDER-IRAD, (priv->select_toggle.state?OSD_W:0)+IBORDER); cairo_arc (cr, OSD_W-IBORDER-IRAD, (priv->select_toggle.state?OSD_W:0)+IBORDER+IRAD, IRAD, -M_PI/2, 0); cairo_line_to (cr, OSD_W-IBORDER, (priv->select_toggle.state?OSD_W:0)+OSD_W-IBORDER-IRAD); cairo_arc (cr, OSD_W-IBORDER-IRAD, (priv->select_toggle.state?OSD_W:0)+OSD_W-IBORDER-IRAD, IRAD, 0, M_PI/2); cairo_line_to (cr, IBORDER+IRAD, (priv->select_toggle.state?OSD_W:0)+OSD_W-IBORDER); cairo_arc (cr, IBORDER+IRAD, (priv->select_toggle.state?OSD_W:0)+OSD_W-IBORDER-IRAD, IRAD, M_PI/2, M_PI); cairo_line_to (cr, IBORDER, (priv->select_toggle.state?OSD_W:0)+OSD_W-IBORDER-IRAD); cairo_arc (cr, IBORDER+IRAD, (priv->select_toggle.state?OSD_W:0)+IBORDER+IRAD, IRAD, M_PI, -M_PI/2); cairo_close_path (cr); cairo_fill(cr); #endif /* draw select icon on top */ cairo_set_line_width (cr, ICON_LINE_W); float bright = priv->select_toggle.state?0.5:1.0; cairo_set_source_rgb(cr, bright, bright, bright); cairo_rectangle(cr, ICON_BORDER, ICON_BORDER, ICON_SIZE-ICON_BORDER, ICON_SIZE-ICON_BORDER); cairo_stroke(cr); double dash[] = { ICON_LINE_W, ICON_LINE_W }; cairo_set_dash(cr, dash, 2, 0.0); cairo_rectangle(cr, ICON_BORDER, ICON_BORDER, ICON_SIZE, ICON_SIZE); cairo_stroke(cr); /* draw drag icon below */ bright = priv->select_toggle.state?1.0:0.5; cairo_set_source_rgb(cr, bright, bright, bright); cairo_set_dash(cr, NULL, 0, 0.0); render_arrow(cr, 1*OSD_W/4, 3*OSD_H/4, 0); render_arrow(cr, 3*OSD_W/4, 3*OSD_H/4, M_PI); render_arrow(cr, OSD_W/2, 3*OSD_H/4-OSD_W/4, -M_PI/2); render_arrow(cr, OSD_W/2, 3*OSD_H/4+OSD_W/4, M_PI/2); cairo_destroy(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; }
/* 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); }
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 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); } }
static gboolean colorzones_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_colorzones_gui_data_t *c = (dt_iop_colorzones_gui_data_t *)self->gui_data; dt_iop_colorzones_params_t p = *(dt_iop_colorzones_params_t *)self->params; int ch = (int)c->channel; if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-2]); else dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][0]); for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) dt_draw_curve_set_point(c->minmax_curve, k+1, p.equalizer_x[ch][k], p.equalizer_y[ch][k]); if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][1]); else dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-1]); const int inset = DT_IOP_COLORZONES_INSET; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // clear bg, match color of the notebook tabs: GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(c->channel_tabs)); cairo_set_source_rgb (cr, style->bg[GTK_STATE_NORMAL].red/65535.0f, style->bg[GTK_STATE_NORMAL].green/65535.0f, style->bg[GTK_STATE_NORMAL].blue/65535.0f); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2*inset; height -= 2*inset; cairo_set_line_width(cr, 1.0); cairo_set_source_rgb (cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); cairo_set_source_rgb (cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); if(c->mouse_y > 0 || c->dragging) { // draw min/max curves: dt_iop_colorzones_get_params(&p, c->channel, c->mouse_x, 1., c->mouse_radius); if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-2]); else dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][0]); for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) dt_draw_curve_set_point(c->minmax_curve, k+1, p.equalizer_x[ch][k], p.equalizer_y[ch][k]); if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][1]); else dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-1]); dt_draw_curve_calc_values(c->minmax_curve, 0.0, 1.0, DT_IOP_COLORZONES_RES, c->draw_min_xs, c->draw_min_ys); p = *(dt_iop_colorzones_params_t *)self->params; dt_iop_colorzones_get_params(&p, c->channel, c->mouse_x, .0, c->mouse_radius); if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-2]); else dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][0]); for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) dt_draw_curve_set_point(c->minmax_curve, k+1, p.equalizer_x[ch][k], p.equalizer_y[ch][k]); if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][1]); else dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-1]); dt_draw_curve_calc_values(c->minmax_curve, 0.0, 1.0, DT_IOP_COLORZONES_RES, c->draw_max_xs, c->draw_max_ys); } if(self->picked_color[0] == 0.0) { self->picked_color[0] = 50.0f; self->picked_color[1] = 0.0f; self->picked_color[2] = -5.0f; } const float pickC = sqrtf(self->picked_color[1]*self->picked_color[1] + self->picked_color[2]*self->picked_color[2]); const int cellsi = 16, cellsj = 9; for(int j=0; j<cellsj; j++) for(int i=0; i<cellsi; i++) { double rgb[3] = {0.5, 0.5, 0.5}; float jj = 1.0 - (j-.5)/(cellsj-1.), ii = (i+.5)/(cellsi-1.); cmsCIELab Lab; switch(p.channel) { // select by channel, abscissa: case DT_IOP_COLORZONES_L: Lab.L = ii * 100.0; Lab.a = self->picked_color[1]; Lab.b = self->picked_color[2]; break; case DT_IOP_COLORZONES_C: Lab.L = 50.0; Lab.a = 64.0*ii*self->picked_color[1]/pickC; Lab.b = 64.0*ii*self->picked_color[2]/pickC; break; default: // case DT_IOP_COLORZONES_h: Lab.L = 50.0; Lab.a = cosf(2.0*M_PI*ii) * 64.0f; Lab.b = sinf(2.0*M_PI*ii) * 64.0f; break; } const float L0 = Lab.L; const float angle = atan2f(Lab.b, Lab.a); switch(c->channel) { // channel to be altered: case DT_IOP_COLORZONES_L: Lab.L += - 50.0 + 100.0*jj; break; case DT_IOP_COLORZONES_C: Lab.a *= 2.0f*jj; Lab.b *= 2.0f*jj; break; default: // DT_IOP_COLORZONES_h Lab.a = cosf(angle + 2.0*M_PI*(jj-.5f)) * 64.0; Lab.b = sinf(angle + 2.0*M_PI*(jj-.5f)) * 64.0; if(p.channel == DT_IOP_COLORZONES_C) { Lab.a *= ii; Lab.b *= ii; } break; } // gammut mapping magic from iop/exposure.c: const float Lwhite = 100.0f, Lclip = 20.0f; const float Lcap = fminf(100.0, Lab.L); const float clip = 1.0 - (Lcap - L0)*(1.0/100.0)*fminf(Lwhite-Lclip, fmaxf(0.0, Lab.L - Lclip))/(Lwhite-Lclip); const float clip2 = clip*clip*clip; Lab.a *= Lab.L/L0 * clip2; Lab.b *= Lab.L/L0 * clip2; cmsDoTransform(c->xform, &Lab, rgb, 1); cairo_set_source_rgb (cr, rgb[0], rgb[1], rgb[2]); cairo_rectangle(cr, width*i/(float)cellsi, height*j/(float)cellsj, width/(float)cellsi-1, height/(float)cellsj-1); cairo_fill(cr); } // draw marker for currently selected color: float picked_i = -1.0; switch(p.channel) { // select by channel, abscissa: case DT_IOP_COLORZONES_L: picked_i = self->picked_color[0]/100.0; break; case DT_IOP_COLORZONES_C: picked_i = pickC / 128.0; break; default: // case DT_IOP_COLORZONES_h: picked_i = fmodf(atan2f(self->picked_color[2], self->picked_color[1]) + 2.0*M_PI, 2.0*M_PI)/(2.0*M_PI); break; } cairo_save(cr); cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); cairo_set_operator(cr, CAIRO_OPERATOR_XOR); cairo_set_line_width(cr, 2.); cairo_move_to(cr, width*picked_i, 0.0); cairo_line_to(cr, width*picked_i, height); cairo_stroke(cr); cairo_restore(cr); // draw x positions cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_set_line_width(cr, 1.); const float arrw = 7.0f; for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) { cairo_move_to(cr, width*p.equalizer_x[c->channel][k], height+inset-1); cairo_rel_line_to(cr, -arrw*.5f, 0); cairo_rel_line_to(cr, arrw*.5f, -arrw); cairo_rel_line_to(cr, arrw*.5f, arrw); cairo_close_path(cr); if(c->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } // draw selected cursor cairo_translate(cr, 0, height); // cairo_set_operator(cr, CAIRO_OPERATOR_ADD); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_line_width(cr, 2.); for(int i=0; i<3; i++) { // draw curves, selected last. int ch = ((int)c->channel+i+1)%3; if(i == 2) cairo_set_source_rgba(cr, .7, .7, .7, 1.0); else cairo_set_source_rgba(cr, .7, .7, .7, 0.3); p = *(dt_iop_colorzones_params_t *)self->params; if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-2]); else dt_draw_curve_set_point(c->minmax_curve, 0, p.equalizer_x[ch][DT_IOP_COLORZONES_BANDS-2]-1.0, p.equalizer_y[ch][0]); for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) dt_draw_curve_set_point(c->minmax_curve, k+1, p.equalizer_x[ch][k], p.equalizer_y[ch][k]); if(p.channel == DT_IOP_COLORZONES_h) dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][1]); else dt_draw_curve_set_point(c->minmax_curve, DT_IOP_COLORZONES_BANDS+1, p.equalizer_x[ch][1]+1.0, p.equalizer_y[ch][DT_IOP_COLORZONES_BANDS-1]); dt_draw_curve_calc_values(c->minmax_curve, 0.0, 1.0, DT_IOP_COLORZONES_RES, c->draw_xs, c->draw_ys); cairo_move_to(cr, 0*width/(float)(DT_IOP_COLORZONES_RES-1), - height*c->draw_ys[0]); for(int k=1; k<DT_IOP_COLORZONES_RES; k++) cairo_line_to(cr, k*width/(float)(DT_IOP_COLORZONES_RES-1), - height*c->draw_ys[k]); cairo_stroke(cr); } // draw dots on knots cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_set_line_width(cr, 1.); for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) { cairo_arc(cr, width*p.equalizer_x[c->channel][k], - height*p.equalizer_y[c->channel][k], 3.0, 0.0, 2.0*M_PI); if(c->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } if(c->mouse_y > 0 || c->dragging) { // draw min/max, if selected cairo_set_source_rgba(cr, .7, .7, .7, .6); cairo_move_to(cr, 0, - height*c->draw_min_ys[0]); for(int k=1; k<DT_IOP_COLORZONES_RES; k++) cairo_line_to(cr, k*width/(float)(DT_IOP_COLORZONES_RES-1), - height*c->draw_min_ys[k]); for(int k=DT_IOP_COLORZONES_RES-1; k>=0; k--) cairo_line_to(cr, k*width/(float)(DT_IOP_COLORZONES_RES-1), - height*c->draw_max_ys[k]); cairo_close_path(cr); cairo_fill(cr); // draw mouse focus circle cairo_set_source_rgba(cr, .9, .9, .9, .5); const float pos = DT_IOP_COLORZONES_RES * c->mouse_x; int k = (int)pos; const float f = k - pos; if(k >= DT_IOP_COLORZONES_RES-1) k = DT_IOP_COLORZONES_RES - 2; float ht = -height*(f*c->draw_ys[k] + (1-f)*c->draw_ys[k+1]); cairo_arc(cr, c->mouse_x*width, ht, c->mouse_radius*width, 0, 2.*M_PI); cairo_stroke(cr); } cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 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; }
static gboolean zoom_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data) { CompositedZoomData *zoom; zoom = user_data; if (zoom->size >= zoom->size_end) { if (zoom->timeout_id) g_source_remove (zoom->timeout_id); zoom->timeout_id = 0; gtk_widget_hide (widget); g_idle_add (idle_destroy, widget); g_object_unref (zoom->pixbuf); zoom->pixbuf = NULL; g_slice_free (CompositedZoomData, zoom); } else { GdkPixbuf *scaled; int width, height; int x = 0, y = 0; gtk_window_get_size (GTK_WINDOW (widget), &width, &height); zoom->size += MAX ((zoom->size_end - zoom->size_start) / ZOOM_STEPS, 1); zoom->opacity -= 1.0 / ((double) ZOOM_STEPS + 1); scaled = gdk_pixbuf_scale_simple (zoom->pixbuf, zoom->size, zoom->size, GDK_INTERP_BILINEAR); switch (zoom->orientation) { case PANEL_ORIENTATION_TOP: x = (width - gdk_pixbuf_get_width (scaled)) / 2; y = 0; break; case PANEL_ORIENTATION_RIGHT: x = width - gdk_pixbuf_get_width (scaled); y = (height - gdk_pixbuf_get_height (scaled)) / 2; break; case PANEL_ORIENTATION_BOTTOM: x = (width - gdk_pixbuf_get_width (scaled)) / 2; y = height - gdk_pixbuf_get_height (scaled); break; case PANEL_ORIENTATION_LEFT: x = 0; y = (height - gdk_pixbuf_get_height (scaled)) / 2; break; default: break; } cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (cr, 0, 0, 0, 0.0); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); gdk_cairo_set_source_pixbuf (cr, scaled, x, y); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint_with_alpha (cr, MAX (zoom->opacity, 0)); g_object_unref (scaled); } return FALSE; }
static inline void setColor(cairo_t* cr, const Color& col) { float red, green, blue, alpha; col.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); }
static void render (cairo_t *pCairoContext, CairoDesklet *pDesklet) { CDSlideParameters *pSlide = (CDSlideParameters *) pDesklet->pRendererData; //g_print ("%s(%x)\n", __func__, pSlide); if (pSlide == NULL) return ; double fRadius = pSlide->iRadius; double fLineWidth = pSlide->iLineWidth; // le cadre. cairo_set_line_width (pCairoContext, pSlide->iLineWidth); if (pSlide->bRoundedRadius) { cairo_translate (pCairoContext, 0., .5 * fLineWidth); cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, pDesklet->container.iWidth - 2 * fRadius - fLineWidth, pDesklet->container.iHeight - 2*fLineWidth); } else { cairo_move_to (pCairoContext, 0., 0.); cairo_rel_line_to (pCairoContext, 0., pDesklet->container.iHeight - fRadius - fLineWidth); cairo_rel_line_to (pCairoContext, pSlide->iRadius, pSlide->iRadius); cairo_rel_line_to (pCairoContext, pDesklet->container.iWidth - fRadius - fLineWidth, 0.); } cairo_set_source_rgba (pCairoContext, pSlide->fLineColor[0], pSlide->fLineColor[1], pSlide->fLineColor[2], pSlide->fLineColor[3]); cairo_stroke (pCairoContext); // les icones. double w = pDesklet->container.iWidth - 2 * pSlide->fMargin; double h = pDesklet->container.iHeight - 2 * pSlide->fMargin; int dh = (h - pSlide->iNbLines * (pSlide->iIconSize + myIconsParam.iLabelSize)) / (pSlide->iNbLines != 1 ? pSlide->iNbLines - 1 : 1); // ecart entre 2 lignes. int dw = (w - pSlide->iNbColumns * pSlide->iIconSize) / pSlide->iNbColumns; // ecart entre 2 colonnes. // on determine la 1ere icone a tracer : l'icone suivant l'icone pointee. double x = pSlide->fMargin + dw/2, y = pSlide->fMargin + myIconsParam.iLabelSize; int q = 0; Icon *pIcon; GList *ic; for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) continue; pIcon->fDrawX = x; pIcon->fDrawY = y; x += pSlide->iIconSize + dw; q ++; if (q == pSlide->iNbColumns) { q = 0; x = pSlide->fMargin + dw/2; y += pSlide->iIconSize + myIconsParam.iLabelSize + dh; } } GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDesklet->icons); if (pFirstDrawnElement == NULL) return; ic = pFirstDrawnElement; do { pIcon = ic->data; if (pIcon->image.pSurface != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { cairo_save (pCairoContext); cairo_dock_render_one_icon_in_desklet (pIcon, CAIRO_CONTAINER (pDesklet), pCairoContext, FALSE); cairo_restore (pCairoContext); if (pIcon->label.pSurface != NULL) { cairo_save (pCairoContext); cairo_translate (pCairoContext, pIcon->fDrawX, pIcon->fDrawY); double fOffsetX = 0., fAlpha; if (pIcon->bPointed) { fAlpha = 1.; if (pIcon->fDrawX + pIcon->fWidth/2 + pIcon->label.iWidth/2 > pDesklet->container.iWidth) fOffsetX = pDesklet->container.iWidth - (pIcon->fDrawX + pIcon->fWidth/2 + pIcon->label.iWidth/2); if (pIcon->fDrawX + pIcon->fWidth/2 - pIcon->label.iWidth/2 < 0) fOffsetX = pIcon->label.iWidth/2 - (pIcon->fDrawX + pIcon->fWidth/2); cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX + pIcon->fWidth/2 - pIcon->label.iWidth/2, -myIconsParam.iLabelSize); cairo_paint_with_alpha (pCairoContext, fAlpha); } else { fAlpha = .6; if (pIcon->label.iWidth > pIcon->fWidth + 2 * myIconsParam.iLabelSize) { fOffsetX = - myIconsParam.iLabelSize; cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (fOffsetX, 0., fOffsetX + pIcon->fWidth + 2*myIconsParam.iLabelSize, 0.); cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0., 0., 0., 0., fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.75, 0., 0., 0., fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 1., 0., 0., 0., 0.); cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX, -myIconsParam.iLabelSize); cairo_mask (pCairoContext, pGradationPattern); cairo_pattern_destroy (pGradationPattern); } else { fOffsetX = pIcon->fWidth/2 - pIcon->label.iWidth/2; cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX, -myIconsParam.iLabelSize); cairo_paint_with_alpha (pCairoContext, fAlpha); } } cairo_restore (pCairoContext); } } ic = cairo_dock_get_next_element (ic, pDesklet->icons); } while (ic != pFirstDrawnElement); }
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const { #if USE(FREETYPE) if (!primaryFont()->platformData().m_pattern) { drawSimpleText(context, run, point, from, to); return; } #endif cairo_t* cr = context->platformContext()->cr(); PangoLayout* layout = pango_cairo_create_layout(cr); setPangoAttributes(this, run, layout); gchar* utf8 = convertUniCharToUTF8(run.characters16(), run.length(), 0, run.length()); pango_layout_set_text(layout, utf8, -1); // Our layouts are single line PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0); // Get the region where this text will be laid out. We will use it to clip // the Cairo context, for when we are only painting part of the text run and // to calculate the size of the shadow buffer. PangoRegionType partialRegion = 0; char* start = g_utf8_offset_to_pointer(utf8, from); char* end = g_utf8_offset_to_pointer(start, to - from); int ranges[] = {start - utf8, end - utf8}; #if PLATFORM(GTK) partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1); #else partialRegion = getClipRegionFromPangoLayoutLine(layoutLine, ranges); #endif drawGlyphsShadow(context, point, layoutLine, partialRegion); cairo_save(cr); cairo_translate(cr, point.x(), point.y()); float red, green, blue, alpha; context->fillColor().getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); #if PLATFORM(GTK) gdk_cairo_region(cr, partialRegion); #else appendRegionToCairoContext(cr, partialRegion); #endif cairo_clip(cr); pango_cairo_show_layout_line(cr, layoutLine); if (context->textDrawingMode() & TextModeStroke) { Color strokeColor = context->strokeColor(); strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); pango_cairo_layout_line_path(cr, layoutLine); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Pango sometimes leaves behind paths we don't want cairo_new_path(cr); destroyPangoRegion(partialRegion); g_free(utf8); g_object_unref(layout); cairo_restore(cr); }
void drawPie(cairo_t* c, int w, int h) { double w2 = w / 2.0f; double h2 = h / 2.0f; double r = h2 * 0.8f; double seg = (2.0f * osg::PI) / 8.0f; double top = osg::PI + (osg::PI / 2.0f); // each "tier" or level or an arc double lvl[] = { 0.0f, 0.25f, 0.50f, 0.75f, 1.0f }; const char* atts[] = { "Milk", "Horns", "Beefiness", "Moo/HR", "Grazing", "Sleeping", "Cowpower!", "s p o t s" }; double attl[] = { 0.25f, 0.0f, 0.50f, 1.0f, 0.0f, 0.25f, 0.75f, 1.0f }; cairo_set_line_width(c, ((w + h) / 2.0f) * 0.003f); cairo_select_font_face(c, "SegoeUI", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(c, ((w + h) / 2.0f) * 0.05f); cairo_translate(c, w2, h2); cairo_rotate(c, -seg / 2.0f); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); for(unsigned int i = 0; i < 8; i++) { // Pick a random level... cairo_move_to(c, 0.0f, 0.0f); cairo_line_to(c, 0.0f, -r); cairo_arc(c, 0.0f, 0.0f, attl[i] * r, top, top + seg); cairo_line_to(c, 0.0f, 0.0f); cairo_set_source_rgba(c, 0.2f, 0.8f, 0.2f, 0.5f); cairo_fill(c); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); // Do the various levels... cairo_move_to(c, 0.0f, 0.0f); cairo_line_to(c, 0.0f, -r); cairo_stroke(c); for(unsigned int l = 0; l < 5; l++) { cairo_arc(c, 0.0f, 0.0f, lvl[l] * r, top, top + seg); cairo_stroke(c); } cairo_text_extents_t extents; cairo_text_extents(c, atts[i], &extents); double arcsize = r * seg; // ------------------------------------ cairo_save(c); double tr = extents.width / r; double aa = ((arcsize - extents.width) / 2.0f) / r; cairo_arc(c, 0.0f, 0.0f, h2 * 0.85f, top + aa, top + aa + tr); cairo_set_tolerance(c, 0.01f); cairo_path_t* path = cairo_copy_path_flat(c); cairo_new_path(c); cairo_text_path(c, atts[i]); osgCairo::mapPathOnto(c, path); cairo_path_destroy(path); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); cairo_set_line_width(c, 1.0f); cairo_stroke_preserve(c); cairo_set_source_rgba(c, 0.8f, 0.5f, 0.1f, 0.7f); cairo_fill(c); cairo_restore(c); // ------------------------------------ // Pick a random level... cairo_move_to(c, 0.0f, 0.0f); cairo_line_to(c, 0.0f, -r); cairo_arc(c, 0.0f, 0.0f, r, top, top + seg); cairo_line_to(c, 0.0f, 0.0f); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); cairo_stroke(c); cairo_rotate(c, seg); } }
static gboolean gtk_bubble_window_draw (GtkWidget *widget, cairo_t *cr) { GtkStyleContext *context; GtkAllocation allocation; GtkWidget *child; GtkBorder border; GdkRGBA border_color; gint rect_x1, rect_x2, rect_y1, rect_y2; gint initial_x, initial_y, final_x, final_y; gint gap_start, gap_end; GtkPositionType gap_side; GtkStateFlags state; context = gtk_widget_get_style_context (widget); state = gtk_widget_get_state_flags (widget); gtk_widget_get_allocation (widget, &allocation); if (gtk_widget_is_composited (widget)) { cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (cr, 0, 0, 0, 0); cairo_paint (cr); cairo_restore (cr); } gtk_bubble_window_get_rect_coords (GTK_BUBBLE_WINDOW (widget), &rect_x1, &rect_y1, &rect_x2, &rect_y2); /* Render the rect background */ gtk_render_background (context, cr, rect_x1, rect_y1, rect_x2 - rect_x1, rect_y2 - rect_y1); gtk_bubble_window_get_gap_coords (GTK_BUBBLE_WINDOW (widget), &initial_x, &initial_y, NULL, NULL, &final_x, &final_y, &gap_side); if (POS_IS_VERTICAL (gap_side)) { gap_start = initial_x; gap_end = final_x; } else { gap_start = initial_y; gap_end = final_y; } /* Now render the frame, without the gap for the arrow tip */ gtk_render_frame_gap (context, cr, rect_x1, rect_y1, rect_x2 - rect_x1, rect_y2 - rect_y1, gap_side, gap_start, gap_end); /* Clip to the arrow shape */ cairo_save (cr); gtk_bubble_window_apply_tail_path (GTK_BUBBLE_WINDOW (widget), cr); cairo_clip (cr); /* Render the arrow background */ gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height); /* Render the border of the arrow tip */ gtk_style_context_get_border (context, state, &border); if (border.bottom > 0) { gtk_style_context_get_border_color (context, state, &border_color); gtk_bubble_window_apply_tail_path (GTK_BUBBLE_WINDOW (widget), cr); gdk_cairo_set_source_rgba (cr, &border_color); cairo_set_line_width (cr, border.bottom); cairo_stroke (cr); } /* We're done */ cairo_restore (cr); child = gtk_bin_get_child (GTK_BIN (widget)); if (child) gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr); return TRUE; }
void setSourceRGBAFromColor(cairo_t* context, const Color& color) { float red, green, blue, alpha; color.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(context, red, green, blue, alpha); }
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); } } }
void CanvasCairo::pathFill(const Color4B &fill) { cairo_set_source_rgba(_context, fill.r / 255.0, fill.g / 255.0, fill.b / 255.0, fill.a / 255.0); cairo_fill(_context); }
static void clearlooks_glossy_draw_scrollbar_slider (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *widget, const ScrollBarParameters *scrollbar, int x, int y, int width, int height) { const CairoColor *border = &colors->shade[7]; CairoColor fill = scrollbar->color; CairoColor hilight; CairoColor shade1, shade2, shade3; cairo_pattern_t *pattern; if (scrollbar->junction & CL_JUNCTION_BEGIN) { if (scrollbar->horizontal) { x -= 1; width += 1; } else { y -= 1; height += 1; } } if (scrollbar->junction & CL_JUNCTION_END) { if (scrollbar->horizontal) width += 1; else height += 1; } if (!scrollbar->horizontal) ge_cairo_exchange_axis (cr, &x, &y, &width, &height); cairo_translate (cr, x, y); if (widget->prelight) ge_shade_color (&fill, 1.1, &fill); cairo_set_line_width (cr, 1); ge_shade_color (&fill, 1.25, &hilight); ge_shade_color (&fill, 1.16, &shade1); ge_shade_color (&fill, 1.08, &shade2); ge_shade_color (&fill, 1.08, &shade3); pattern = cairo_pattern_create_linear (1, 1, 1, height-2); cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b); cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); cairo_rectangle (cr, 1, 1, width-2, height-2); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); if (scrollbar->has_color) { cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3); } clearlooks_set_mixed_color (cr, border, &fill, scrollbar->has_color? 0.4 : 0.2); ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); }
void CanvasCairo::pathStroke(const Color4B &stroke) { cairo_set_source_rgba(_context, stroke.r / 255.0, stroke.g / 255.0, stroke.b / 255.0, stroke.a / 255.0); cairo_stroke(_context); }
/* * 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; }
void LcCairoPainter::source_rgba(double r, double g, double b, double a) { cairo_set_source_rgba(_cr, r, g, b, a); }