void _Cairo_graphics_surfaces <_Graphics_math_float_impl>::surfaces::_Render_to_native_surface < _Cairo::_Cairo_graphics_surfaces <_Graphics_math_float_impl>::surfaces::_Output_surface_data*, basic_output_surface <_Cairo::_Cairo_graphics_surfaces <_Graphics_math_float_impl>> > ( _Cairo::_Cairo_graphics_surfaces <_Graphics_math_float_impl>::surfaces::_Output_surface_data * & osdp, basic_output_surface <_Cairo::_Cairo_graphics_surfaces <_Graphics_math_float_impl>> & sfc ) { auto& osd = *osdp; const cairo_filter_t cairoFilter = CAIRO_FILTER_GOOD; auto& data = osd.data; double displayWidth = static_cast<double>(data.display_dimensions.x()); double displayHeight = static_cast<double>(data.display_dimensions.y()); double backBufferWidth = static_cast<double>(data.back_buffer.dimensions.x()); double backBufferHeight = static_cast<double>(data.back_buffer.dimensions.y()); auto backBufferSfc = data.back_buffer.surface.get(); auto displaySfc = data.display_surface.get(); auto displayContext = data.display_context.get(); cairo_surface_flush(backBufferSfc); cairo_set_operator(displayContext, CAIRO_OPERATOR_SOURCE); if (osd.user_scaling_callback != nullptr) { bool letterbox = false; auto userRect = osd.user_scaling_callback(sfc, letterbox); if (letterbox) { if (data._Letterbox_brush == nullopt) { cairo_set_source_rgb(displayContext, 0.0, 0.0, 0.0); cairo_paint(displayContext); } else { auto pttn = data._Letterbox_brush.value().data().brush.get(); if (data._Letterbox_brush_props == nullopt) { cairo_pattern_set_extend(pttn, CAIRO_EXTEND_NONE); cairo_pattern_set_filter(pttn, CAIRO_FILTER_GOOD); cairo_matrix_t cPttnMatrix; cairo_matrix_init_identity(&cPttnMatrix); cairo_pattern_set_matrix(pttn, &cPttnMatrix); cairo_set_source(displayContext, pttn); cairo_paint(displayContext); } else { const basic_brush_props<_Cairo_graphics_surfaces<std::experimental::io2d::v1::_Graphics_math_float_impl>>& props = data._Letterbox_brush_props.value(); cairo_pattern_set_extend(pttn, _Extend_to_cairo_extend_t(props.wrap_mode())); cairo_pattern_set_filter(pttn, _Filter_to_cairo_filter_t(props.filter())); cairo_matrix_t cPttnMatrix; const auto& m = props.brush_matrix(); cairo_matrix_init(&cPttnMatrix, m.m00(), m.m01(), m.m10(), m.m11(), m.m20(), m.m21()); cairo_pattern_set_matrix(pttn, &cPttnMatrix); cairo_set_source(displayContext, pttn); cairo_paint(displayContext); } } } cairo_matrix_t ctm; cairo_matrix_init_scale(&ctm, 1.0 / displayWidth / static_cast<double>(userRect.width()), 1.0 / displayHeight / static_cast<double>(userRect.height())); cairo_matrix_translate(&ctm, -static_cast<double>(userRect.x()), -static_cast<double>(userRect.y())); unique_ptr<cairo_pattern_t, decltype(&cairo_pattern_destroy)> pat(cairo_pattern_create_for_surface(backBufferSfc), &cairo_pattern_destroy); auto patPtr = pat.get(); cairo_pattern_set_matrix(patPtr, &ctm); cairo_pattern_set_extend(patPtr, CAIRO_EXTEND_NONE); cairo_pattern_set_filter(patPtr, cairoFilter); cairo_set_source(displayContext, patPtr); cairo_paint(displayContext); } else { // Calculate the destRect values. switch (data.scl) { case std::experimental::io2d::scaling::letterbox: { _Render_for_scaling_uniform_or_letterbox(osd); } break; case std::experimental::io2d::scaling::uniform: { _Render_for_scaling_uniform_or_letterbox(osd); } break; case std::experimental::io2d::scaling::fill_uniform: { // Maintain aspect ratio and center, but overflow if needed rather than letterboxing. if (backBufferWidth == displayWidth && backBufferHeight == displayHeight) { cairo_set_source_surface(displayContext, backBufferSfc, 0.0, 0.0); cairo_paint(displayContext); } else { auto widthRatio = displayWidth / backBufferWidth; auto heightRatio = displayHeight / backBufferHeight; if (widthRatio < heightRatio) { cairo_set_source_rgb(displayContext, 0.0, 0.0, 0.0); cairo_paint(displayContext); cairo_matrix_t ctm; cairo_matrix_init_scale(&ctm, 1.0 / heightRatio, 1.0 / heightRatio); cairo_matrix_translate(&ctm, trunc(abs((displayWidth - (backBufferWidth * heightRatio)) / 2.0)), 0.0); unique_ptr<cairo_pattern_t, decltype(&cairo_pattern_destroy)> pat(cairo_pattern_create_for_surface(backBufferSfc), &cairo_pattern_destroy); auto patPtr = pat.get(); cairo_pattern_set_matrix(patPtr, &ctm); cairo_pattern_set_extend(patPtr, CAIRO_EXTEND_NONE); cairo_pattern_set_filter(patPtr, cairoFilter); cairo_set_source(displayContext, patPtr); cairo_paint(displayContext); } else { cairo_set_source_rgb(displayContext, 0.0, 0.0, 0.0); cairo_paint(displayContext); cairo_matrix_t ctm; cairo_matrix_init_scale(&ctm, 1.0 / widthRatio, 1.0 / widthRatio); cairo_matrix_translate(&ctm, 0.0, trunc(abs((displayHeight - (backBufferHeight * widthRatio)) / 2.0))); unique_ptr<cairo_pattern_t, decltype(&cairo_pattern_destroy)> pat(cairo_pattern_create_for_surface(backBufferSfc), &cairo_pattern_destroy); auto patPtr = pat.get(); cairo_pattern_set_matrix(patPtr, &ctm); cairo_pattern_set_extend(patPtr, CAIRO_EXTEND_NONE); cairo_pattern_set_filter(patPtr, cairoFilter); cairo_set_source(displayContext, patPtr); cairo_paint(displayContext); } } } break; case std::experimental::io2d::scaling::fill_exact: { // Maintain aspect ratio and center, but overflow if needed rather than letterboxing. if (backBufferWidth == displayWidth && backBufferHeight == displayHeight) { cairo_set_source_surface(displayContext, backBufferSfc, 0.0, 0.0); cairo_paint(displayContext); } else { auto widthRatio = displayWidth / backBufferWidth; auto heightRatio = displayHeight / backBufferHeight; cairo_matrix_t ctm; cairo_matrix_init_scale(&ctm, 1.0 / widthRatio, 1.0 / heightRatio); unique_ptr<cairo_pattern_t, decltype(&cairo_pattern_destroy)> pat(cairo_pattern_create_for_surface(backBufferSfc), &cairo_pattern_destroy); auto patPtr = pat.get(); cairo_pattern_set_matrix(patPtr, &ctm); cairo_pattern_set_extend(patPtr, CAIRO_EXTEND_NONE); cairo_pattern_set_filter(patPtr, cairoFilter); cairo_set_source(displayContext, patPtr); cairo_paint(displayContext); } } break; case std::experimental::io2d::scaling::none: { cairo_set_source_surface(displayContext, backBufferSfc, 0.0, 0.0); cairo_paint(displayContext); } break; default: { assert("Unexpected _Scaling value." && false); } break; } } // cairo_restore(_Native_context.get()); // This call to cairo_surface_flush is needed for Win32 surfaces to update. cairo_surface_flush(displaySfc); cairo_set_source_rgb(displayContext, 0.0, 0.0, 0.0); SDL_SetRenderDrawColor(data.renderer, 0, 0, 0, 255); if (SDL_RenderClear(data.renderer) != 0) { throw ::std::system_error(::std::make_error_code(::std::errc::io_error), SDL_GetError()); } // Copy Cairo canvas to SDL2 texture unsigned char * src = cairo_image_surface_get_data(displaySfc); // TODO([email protected]): compute the pitch, given const int pitch = (int)backBufferWidth * 4; // '4' == 4 bytes per pixel if (SDL_UpdateTexture(data.texture, nullptr, src, pitch) != 0) { throw ::std::system_error(::std::make_error_code(::std::errc::io_error), SDL_GetError()); } if (SDL_RenderCopy(data.renderer, data.texture, nullptr, nullptr) != 0) { throw ::std::system_error(::std::make_error_code(::std::errc::io_error), SDL_GetError()); } // Present latest image SDL_RenderPresent(data.renderer); }
void Pattern::setExtendReflect() { cairo_pattern_set_extend( mCairoPattern, CAIRO_EXTEND_REFLECT ); }
static void gtk_border_image_render_slice (cairo_t *cr, cairo_surface_t *slice, double slice_width, double slice_height, double x, double y, double width, double height, GtkCssRepeatStyle hrepeat, GtkCssRepeatStyle vrepeat) { double hscale, vscale; double xstep, ystep; cairo_extend_t extend = CAIRO_EXTEND_PAD; cairo_matrix_t matrix; cairo_pattern_t *pattern; /* We can't draw center tiles yet */ g_assert (hrepeat == GTK_CSS_REPEAT_STYLE_STRETCH || vrepeat == GTK_CSS_REPEAT_STYLE_STRETCH); hscale = width / slice_width; vscale = height / slice_height; xstep = width; ystep = height; switch (hrepeat) { case GTK_CSS_REPEAT_STYLE_REPEAT: extend = CAIRO_EXTEND_REPEAT; hscale = vscale; break; case GTK_CSS_REPEAT_STYLE_SPACE: { double space, n; extend = CAIRO_EXTEND_NONE; hscale = vscale; xstep = hscale * slice_width; n = floor (width / xstep); space = (width - n * xstep) / (n + 1); xstep += space; x += space; width -= 2 * space; } break; case GTK_CSS_REPEAT_STYLE_STRETCH: break; case GTK_CSS_REPEAT_STYLE_ROUND: extend = CAIRO_EXTEND_REPEAT; hscale = width / (slice_width * MAX (round (width / (slice_width * vscale)), 1)); break; default: g_assert_not_reached (); break; } switch (vrepeat) { case GTK_CSS_REPEAT_STYLE_REPEAT: extend = CAIRO_EXTEND_REPEAT; vscale = hscale; break; case GTK_CSS_REPEAT_STYLE_SPACE: { double space, n; extend = CAIRO_EXTEND_NONE; vscale = hscale; ystep = vscale * slice_height; n = floor (height / ystep); space = (height - n * ystep) / (n + 1); ystep += space; y += space; height -= 2 * space; } break; case GTK_CSS_REPEAT_STYLE_STRETCH: break; case GTK_CSS_REPEAT_STYLE_ROUND: extend = CAIRO_EXTEND_REPEAT; vscale = height / (slice_height * MAX (round (height / (slice_height * hscale)), 1)); break; default: g_assert_not_reached (); break; } pattern = cairo_pattern_create_for_surface (slice); cairo_matrix_init_translate (&matrix, hrepeat == GTK_CSS_REPEAT_STYLE_REPEAT ? slice_width / 2 : 0, vrepeat == GTK_CSS_REPEAT_STYLE_REPEAT ? slice_height / 2 : 0); cairo_matrix_scale (&matrix, 1 / hscale, 1 / vscale); cairo_matrix_translate (&matrix, hrepeat == GTK_CSS_REPEAT_STYLE_REPEAT ? - width / 2 : 0, vrepeat == GTK_CSS_REPEAT_STYLE_REPEAT ? - height / 2 : 0); cairo_pattern_set_matrix (pattern, &matrix); cairo_pattern_set_extend (pattern, extend); cairo_save (cr); cairo_translate (cr, x, y); for (y = 0; y < height; y += ystep) { for (x = 0; x < width; x += xstep) { cairo_save (cr); cairo_translate (cr, x, y); cairo_set_source (cr, pattern); cairo_rectangle (cr, 0, 0, xstep, ystep); cairo_fill (cr); cairo_restore (cr); } } cairo_restore (cr); cairo_pattern_destroy (pattern); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_surface_t *region, *similar; cairo_t *cr_region, *cr_similar; cairo_set_source_rgb (cr, .5, .5, .5); cairo_paint (cr); similar = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, 20, 20); /* copy the centre */ cr_similar = cairo_create (similar); cairo_surface_destroy (similar); cairo_set_source_surface (cr_similar, cairo_get_target (cr), -20, -20); cairo_paint (cr_similar); similar = cairo_surface_reference (cairo_get_target (cr_similar)); cairo_destroy (cr_similar); /* fill the centre */ region = cairo_surface_create_for_rectangle (cairo_get_target (cr), 20, 20, 20, 20); cr_region = cairo_create (region); cairo_surface_destroy (region); cairo_set_source_rgb (cr_region, 1, 1, 1); cairo_rectangle (cr_region, 0, 0, 10, 10); cairo_fill (cr_region); cairo_set_source_rgb (cr_region, 1, 0, 0); cairo_rectangle (cr_region, 10, 0, 10, 10); cairo_fill (cr_region); cairo_set_source_rgb (cr_region, 0, 1, 0); cairo_rectangle (cr_region, 0, 10, 10, 10); cairo_fill (cr_region); cairo_set_source_rgb (cr_region, 0, 0, 1); cairo_rectangle (cr_region, 10, 10, 10, 10); cairo_fill (cr_region); cairo_destroy (cr_region); /* copy the centre, again */ cr_similar = cairo_create (similar); cairo_surface_destroy (similar); cairo_set_source_surface (cr_similar, cairo_get_target (cr), -20, -20); cairo_paint (cr_similar); similar = cairo_surface_reference (cairo_get_target (cr_similar)); cairo_destroy (cr_similar); /* repeat the pattern around the outside, but do not overwrite...*/ cairo_set_source_surface (cr, similar, 20, 20); cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); cairo_rectangle (cr, 0, 0, width, height); cairo_rectangle (cr, 20, 40, 20, -20); cairo_fill (cr); cairo_surface_destroy (similar); return CAIRO_TEST_SUCCESS; }
void Pattern::setExtendNone() { cairo_pattern_set_extend( mCairoPattern, CAIRO_EXTEND_NONE ); }
/* * 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); 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); } if (unlock_state >= STATE_KEY_PRESSED && unlock_indicator) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 10.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, 0 /* start */, 2 * M_PI /* end */); /* Use the appropriate color for the different PAM states * (currently verifying, wrong password, or default) */ switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, 0, 114.0 / 255, 255.0 / 255, 0.75); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, 250.0 / 255, 0, 0, 0.75); break; default: cairo_set_source_rgba(ctx, 0, 0, 0, 0.75); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgb(ctx, 51.0 / 255, 0, 250.0 / 255); break; case STATE_PAM_WRONG: cairo_set_source_rgb(ctx, 125.0 / 255, 51.0 / 255, 0); break; case STATE_PAM_IDLE: cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS - 5 /* radius */, 0, 2 * M_PI); cairo_stroke(ctx); cairo_set_line_width(ctx, 10.0); /* Display a (centered) text of the current PAM state. */ char *text = NULL; /* We don't want to show more than a 3-digit number. */ char buf[4]; cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_font_size(ctx, 28.0); switch (pam_state) { case STATE_PAM_VERIFY: text = "verifying…"; break; case STATE_PAM_WRONG: text = "wrong!"; break; default: if (show_failed_attempts && failed_attempts > 0) { if (failed_attempts > 999) { text = "> 999"; } else { snprintf(buf, sizeof(buf), "%d", failed_attempts); text = buf; } cairo_set_source_rgb(ctx, 1, 0, 0); cairo_set_font_size(ctx, 32.0); } break; } if (text) { cairo_text_extents_t extents; double x, y; cairo_text_extents(ctx, text, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing); cairo_move_to(ctx, x, y); cairo_show_text(ctx, text); cairo_close_path(ctx); } 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, 51.0 / 255, 219.0 / 255, 0); } else { /* For backspace, we use red. */ cairo_set_source_rgb(ctx, 219.0 / 255, 51.0 / 255, 0); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start /* start */, highlight_start + (M_PI / 128.0) /* end */); cairo_stroke(ctx); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 3.0) /* start */, (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); cairo_stroke(ctx); } } 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 BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) { FloatRect srcRect(src); FloatRect dstRect(dst); if (dstRect.width() == 0.0f || dstRect.height() == 0.0f || srcRect.width() == 0.0f || srcRect.height() == 0.0f) return; startAnimation(); cairo_surface_t* image = frameAtIndex(m_currentFrame); if (!image) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op); return; } IntSize selfSize = size(); cairo_t* cr = context->platformContext(); context->save(); // Set the compositing operation. if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame)) context->setCompositeOperation(CompositeCopy); else context->setCompositeOperation(op); // If we're drawing a sub portion of the image or scaling then create // a pattern transformation on the image and draw the transformed pattern. // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); float scaleX = srcRect.width() / dstRect.width(); float scaleY = srcRect.height() / dstRect.height(); cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() }; cairo_pattern_set_matrix(pattern, &matrix); // Draw the shadow #if ENABLE(FILTERS) FloatSize shadowOffset; float shadowBlur; Color shadowColor; if (context->getShadow(shadowOffset, shadowBlur, shadowColor)) { IntSize shadowBufferSize; FloatRect shadowRect; float radius = 0; context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowOffset, shadowBlur); shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() * context->getAlpha()) / 255.f); //draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); cairo_t* shadowContext = shadowBuffer->context()->platformContext(); cairo_set_source(shadowContext, pattern); cairo_translate(shadowContext, -dstRect.x(), -dstRect.y()); cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height()); cairo_fill(shadowContext); context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); } #endif // Draw the image. cairo_translate(cr, dstRect.x(), dstRect.y()); cairo_set_source(cr, pattern); cairo_pattern_destroy(pattern); cairo_rectangle(cr, 0, 0, dstRect.width(), dstRect.height()); cairo_clip(cr); cairo_paint_with_alpha(cr, context->getAlpha()); context->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) { double width = cairo_image_surface_get_width(image); double height = cairo_image_surface_get_height(image); switch (scaling_mode) { case SCALING_MODE_STRETCH: cairo_scale(window->cairo, (double) window->width / width, (double) window->height / height); cairo_set_source_surface(window->cairo, image, 0, 0); break; case SCALING_MODE_FILL: { double window_ratio = (double) window->width / window->height; double bg_ratio = width / height; if (window_ratio > bg_ratio) { double scale = (double) window->width / width; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, 0, (double) window->height/2 / scale - height/2); } else { double scale = (double) window->height / height; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, (double) window->width/2 / scale - width/2, 0); } break; } case SCALING_MODE_FIT: { double window_ratio = (double) window->width / window->height; double bg_ratio = width / height; if (window_ratio > bg_ratio) { double scale = (double) window->height / height; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, (double) window->width/2 / scale - width/2, 0); } else { double scale = (double) window->width / width; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, 0, (double) window->height/2 / scale - height/2); } break; } case SCALING_MODE_CENTER: cairo_set_source_surface(window->cairo, image, (double) window->width/2 - width/2, (double) window->height/2 - height/2); break; case SCALING_MODE_TILE: { cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); cairo_set_source(window->cairo, pattern); break; } } cairo_paint(window->cairo); }
static gboolean do_pix_draw(GtkWidget *widget, cairo_t *cr, OverlayData *data) { GdkWindow *drawable = gtk_widget_get_window(widget); gint left = 0; gint top = 0; if (data->is_pixmap) { cm_return_val_if_fail(data->base_pixmap != NULL, FALSE); } else { cm_return_val_if_fail(data->base_pixbuf != NULL, FALSE); } if (data->highlight) { MainWindow *mw = NULL; mw = mainwindow_get_mainwindow(); if (mw != NULL && mw->menubar != NULL) { cairo_t *cr; GdkColor color = gtk_widget_get_style(mw->menubar)->base[GTK_STATE_SELECTED]; cr = gdk_cairo_create(drawable); gdk_cairo_set_source_color(cr, &color); cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr, 1.); cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL); cairo_rectangle(cr, data->border_x-2, data->border_y-2, data->base_width+3, data->base_height+3); cairo_stroke(cr); cairo_destroy(cr); } } if (data->is_pixmap) { cairo_set_source_surface(cr, data->base_pixmap, data->border_x, data->border_y); cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); cairo_rectangle(cr, data->border_x, data->border_y, data->base_width, data->base_height); cairo_fill(cr); } else { gdk_cairo_set_source_pixbuf(cr, data->base_pixbuf, data->border_x, data->border_y); cairo_paint(cr); } if (data->position != OVERLAY_NONE) { switch (data->position) { case OVERLAY_TOP_LEFT: case OVERLAY_MID_LEFT: case OVERLAY_BOTTOM_LEFT: left = 0; break; case OVERLAY_TOP_CENTER: case OVERLAY_MID_CENTER: case OVERLAY_BOTTOM_CENTER: left = (data->base_width + data->border_x * 2 - data->overlay_width)/2; break; case OVERLAY_TOP_RIGHT: case OVERLAY_MID_RIGHT: case OVERLAY_BOTTOM_RIGHT: left = data->base_width + data->border_x * 2 - data->overlay_width; break; default: break; } switch (data->position) { case OVERLAY_TOP_LEFT: case OVERLAY_TOP_CENTER: case OVERLAY_TOP_RIGHT: top = 0; break; case OVERLAY_MID_LEFT: case OVERLAY_MID_CENTER: case OVERLAY_MID_RIGHT: top = (data->base_height + data->border_y * 2 - data->overlay_height)/2; break; case OVERLAY_BOTTOM_LEFT: case OVERLAY_BOTTOM_CENTER: case OVERLAY_BOTTOM_RIGHT: top = data->base_height + data->border_y * 2 - data->overlay_height; break; default: break; } } if (data->position != OVERLAY_NONE) { if (data->is_pixmap) { cm_return_val_if_fail(data->overlay_pixmap != NULL, FALSE); cairo_set_source_surface(cr, data->overlay_pixmap, left, top); cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); cairo_rectangle (cr, left, top, data->overlay_width, data->overlay_height); cairo_fill(cr); } else { cm_return_val_if_fail(data->overlay_pixbuf != NULL, FALSE); gdk_cairo_set_source_pixbuf(cr, data->overlay_pixbuf, left, top); cairo_paint(cr); } } return TRUE; }
void gimp_display_shell_render (GimpDisplayShell *shell, cairo_t *cr, gint x, gint y, gint w, gint h) { GimpImage *image; GimpProjection *projection; GeglBuffer *buffer; gdouble scale_x = 1.0; gdouble scale_y = 1.0; gdouble buffer_scale = 1.0; gint viewport_offset_x; gint viewport_offset_y; gint viewport_width; gint viewport_height; gint scaled_x; gint scaled_y; gint scaled_width; gint scaled_height; cairo_surface_t *xfer; gint xfer_src_x; gint xfer_src_y; gint mask_src_x = 0; gint mask_src_y = 0; gint stride; guchar *data; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (cr != NULL); g_return_if_fail (w > 0 && h > 0); image = gimp_display_get_image (shell->display); projection = gimp_image_get_projection (image); buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (projection)); #ifdef GIMP_DISPLAY_RENDER_ENABLE_SCALING /* if we had this future API, things would look pretty on hires (retina) */ scale_x = gdk_window_get_scale_factor (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (shell)))); #endif scale_x = MIN (scale_x, GIMP_DISPLAY_RENDER_MAX_SCALE); scale_y = scale_x; if (shell->scale_x > shell->scale_y) { scale_y *= (shell->scale_x / shell->scale_y); buffer_scale = shell->scale_y * scale_y; } else if (shell->scale_y > shell->scale_x) { scale_x *= (shell->scale_y / shell->scale_x); buffer_scale = shell->scale_x * scale_x; } else { buffer_scale = shell->scale_x * scale_x; } gimp_display_shell_scroll_get_scaled_viewport (shell, &viewport_offset_x, &viewport_offset_y, &viewport_width, &viewport_height); scaled_x = floor ((x + viewport_offset_x) * scale_x); scaled_y = floor ((y + viewport_offset_y) * scale_y); scaled_width = ceil (w * scale_x); scaled_height = ceil (h * scale_y); if (shell->rotate_transform) { xfer = cairo_surface_create_similar_image (cairo_get_target (cr), CAIRO_FORMAT_ARGB32, scaled_width, scaled_height); cairo_surface_mark_dirty (xfer); xfer_src_x = 0; xfer_src_y = 0; } else { xfer = gimp_display_xfer_get_surface (shell->xfer, scaled_width, scaled_height, &xfer_src_x, &xfer_src_y); } stride = cairo_image_surface_get_stride (xfer); data = cairo_image_surface_get_data (xfer); data += xfer_src_y * stride + xfer_src_x * 4; /* apply filters to the rendered projection */ if (shell->filter_stack) { const Babl *filter_format = babl_format ("R'G'B'A float"); if (! shell->filter_buffer) { gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE; gint h = GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE; shell->filter_data = gegl_malloc (w * h * babl_format_get_bytes_per_pixel (filter_format)); shell->filter_stride = w * babl_format_get_bytes_per_pixel (filter_format); shell->filter_buffer = gegl_buffer_linear_new_from_data (shell->filter_data, filter_format, GEGL_RECTANGLE (0, 0, w, h), GEGL_AUTO_ROWSTRIDE, (GDestroyNotify) gegl_free, shell->filter_data); } gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, filter_format, shell->filter_data, shell->filter_stride, GEGL_ABYSS_CLAMP); gimp_color_display_stack_convert_buffer (shell->filter_stack, shell->filter_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height)); gegl_buffer_get (shell->filter_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height), 1.0, babl_format ("cairo-ARGB32"), data, stride, GEGL_ABYSS_CLAMP); } else { gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, babl_format ("cairo-ARGB32"), data, stride, GEGL_ABYSS_CLAMP); } if (shell->mask) { gint mask_height; if (! shell->mask_surface) { shell->mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE, GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE); } cairo_surface_mark_dirty (shell->mask_surface); stride = cairo_image_surface_get_stride (shell->mask_surface); data = cairo_image_surface_get_data (shell->mask_surface); data += mask_src_y * stride + mask_src_x * 4; gegl_buffer_get (shell->mask, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, babl_format ("Y u8"), data, stride, GEGL_ABYSS_CLAMP); /* invert the mask so what is *not* the foreground object is masked */ mask_height = scaled_height; while (mask_height--) { gint mask_width = scaled_width; guchar *d = data; while (mask_width--) { guchar inv = 255 - *d; *d++ = inv; } data += stride; } } /* put it to the screen */ cairo_save (cr); cairo_rectangle (cr, x, y, w, h); cairo_scale (cr, 1.0 / scale_x, 1.0 / scale_y); cairo_set_source_surface (cr, xfer, x * scale_x - xfer_src_x, y * scale_y - xfer_src_y); if (shell->rotate_transform) { cairo_pattern_t *pattern; pattern = cairo_get_source (cr); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_line_width (cr, 1.0); cairo_stroke_preserve (cr); cairo_surface_destroy (xfer); } cairo_clip (cr); cairo_paint (cr); if (shell->mask) { gimp_cairo_set_source_rgba (cr, &shell->mask_color); cairo_mask_surface (cr, shell->mask_surface, (x - mask_src_x) * scale_x, (y - mask_src_y) * scale_y); } cairo_restore (cr); }
static int cairo_pattern_set_extend_l( lua_State* L ) { lua_cairo_pattern_t* lcp = lua_cairo_pattern_check( L, 1 ); cairo_pattern_set_extend(lcp->pattern, luaL_checkoption( L, 2, "none", cairo_pattern_extend_lst )); return 0; }
gboolean cd_drop_indicator_render (gpointer pUserData, CairoDock *pDock, cairo_t *pCairoContext) { CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock); if (pData == NULL) return GLDI_NOTIFICATION_LET_PASS; if (pCairoContext != NULL) { if (pData->fAlpha > 0) { cairo_save (pCairoContext); double fX = pDock->container.iMouseX - myData.dropIndicator.iWidth / 2; if (pDock->container.bIsHorizontal) cairo_rectangle (pCairoContext, (int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2, (int) (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight), (int) myData.dropIndicator.iWidth, (int) (pDock->container.bDirectionUp ? 2*myData.dropIndicator.iHeight : pDock->iActiveHeight)); else cairo_rectangle (pCairoContext, (int) (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iActiveHeight : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight), (int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2, (int) (pDock->container.bDirectionUp ? 2*myData.dropIndicator.iHeight : pDock->iActiveHeight), (int) myData.dropIndicator.iWidth); cairo_clip (pCairoContext); if (pDock->container.bIsHorizontal) cairo_translate (pCairoContext, fX, (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight)); else cairo_translate (pCairoContext, (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight), fX); double fRotationAngle = (pDock->container.bIsHorizontal ? (pDock->container.bDirectionUp ? 0 : G_PI) : (pDock->container.bDirectionUp ? -G_PI/2 : G_PI/2)); cairo_rotate (pCairoContext, fRotationAngle); cairo_translate (pCairoContext, 0, pData->iDropIndicatorOffset); cairo_pattern_t* pPattern = cairo_pattern_create_for_surface (myData.dropIndicator.pSurface); g_return_val_if_fail (cairo_pattern_status (pPattern) == CAIRO_STATUS_SUCCESS, GLDI_NOTIFICATION_LET_PASS); cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_REPEAT); cairo_set_source (pCairoContext, pPattern); cairo_translate (pCairoContext, 0, - pData->iDropIndicatorOffset); cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (0., 0., 0., 2*myData.dropIndicator.iHeight); // de haut en bas. g_return_val_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS, GLDI_NOTIFICATION_LET_PASS); cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0., 0., 0., 0., 0.); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.4, 0., 0., 0., pData->fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.5, 0., 0., 0., pData->fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 1., 0., 0., 0., 0.); cairo_mask (pCairoContext, pGradationPattern); cairo_pattern_destroy (pPattern); cairo_pattern_destroy (pGradationPattern); cairo_restore (pCairoContext); } if (pData->fAlphaHover > 0 && myData.hoverIndicator.pSurface != NULL) { Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons); if (pIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { cairo_save (pCairoContext); if (pDock->container.bIsHorizontal) { cairo_translate (pCairoContext, pIcon->fDrawX + 2./3*pIcon->fWidth*pIcon->fScale, pIcon->fDrawY); // top right corner cairo_scale (pCairoContext, pIcon->fWidth*pIcon->fScale/3 / myData.hoverIndicator.iWidth, pIcon->fHeight*pIcon->fScale/3 / myData.hoverIndicator.iHeight); } else { cairo_translate (pCairoContext, pIcon->fDrawY + 2./3*pIcon->fWidth*pIcon->fScale, pIcon->fDrawX); cairo_scale (pCairoContext, pIcon->fHeight*pIcon->fScale/3 / myData.hoverIndicator.iWidth, pIcon->fWidth*pIcon->fScale/3 / myData.hoverIndicator.iHeight); } cairo_set_source_surface (pCairoContext, myData.hoverIndicator.pSurface, 0., 0.); cairo_paint_with_alpha (pCairoContext, pData->fAlphaHover); cairo_restore (pCairoContext); } } } else { if (pData->fAlpha > 0) { double fX = pDock->container.iMouseX; double fY = (pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : myData.dropIndicator.iHeight); glPushMatrix(); glLoadIdentity(); if (pDock->container.bIsHorizontal) { fX = pDock->container.iMouseX; fY = (pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : myData.dropIndicator.iHeight); glTranslatef (fX, fY, - myData.dropIndicator.iWidth-1.); if (! pDock->container.bDirectionUp) glScalef (1., -1., 1.); } else { fX = pDock->container.iWidth - pDock->container.iMouseX; fY = (! pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : pDock->container.iHeight - pDock->iActiveHeight + myData.dropIndicator.iHeight); glTranslatef (fY, fX, - myData.dropIndicator.iWidth-1.); glRotatef ((pDock->container.bDirectionUp ? 90. : -90.), 0., 0., 1.); } glRotatef (pData->iDropIndicatorRotation, 0., 1., 0.); //\_________________ On decale la texture vers le bas. glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures glPushMatrix(); glLoadIdentity(); // On la reset glTranslatef(.0, - (double)pData->iDropIndicatorOffset / myData.dropIndicator.iHeight, 0.); glScalef (1., -2., 1.); glMatrixMode(GL_MODELVIEW); // On revient sur la matrice d'affichage //\_________________ On dessine l'indicateur. glEnable (GL_BLEND); if (pData->fAlpha != 1) _cairo_dock_set_blend_alpha (); else _cairo_dock_set_blend_over(); //glEnable(GL_DEPTH_TEST); glScalef (myData.dropIndicator.iWidth, myData.dropIndicator.iHeight, myData.dropIndicator.iWidth); glColor4f(1.0f, 1.0f, 1.0f, pData->fAlpha); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_TEXTURE); glActiveTextureARB(GL_TEXTURE0_ARB); // Go pour le multitexturing 1ere passe glEnable(GL_TEXTURE_2D); // On active le texturing sur cette passe glBindTexture(GL_TEXTURE_2D, myData.dropIndicator.iTexture); glActiveTextureARB(GL_TEXTURE1_ARB); // Go pour le texturing 2eme passe glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, myData.iBilinearGradationTexture); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Le mode de combinaison des textures ///glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); // multiplier les alpha. //glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_QUADS); glNormal3f(0,0,1); glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(-0.5, -1., 0.); // Bottom Left Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f( 0.5, -1., 0.); // Bottom Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f( 0.5, 1., 0.); // Top Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(-0.5, 1., 0.); // Top Left Of The Texture and Quad glNormal3f(1,0,0); glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(0., -1., -0.5); // Bottom Left Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f(0., -1., 0.5); // Bottom Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f(0., 1., 0.5); // Top Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(0., 1., -0.5); // Top Left Of The Texture and Quad glEnd(); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE0_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable (GL_BLEND); _cairo_dock_set_blend_alpha (); glPopMatrix(); //\_________________ On remet la matrice des textures. glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } if (pData->fAlphaHover > 0 && myData.hoverIndicator.iTexture != 0) { Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons); if (pIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { _cairo_dock_enable_texture (); _cairo_dock_set_blend_alpha (); glPushMatrix (); if (pDock->container.bIsHorizontal) glTranslatef (pIcon->fDrawX + 5./6*pIcon->fWidth*pIcon->fScale, pDock->iActiveHeight - pIcon->fDrawY - 1./6*pIcon->fHeight*pIcon->fScale, 0.); else glTranslatef (pIcon->fDrawY + 5./6*pIcon->fHeight*pIcon->fScale, pDock->container.iWidth - (pIcon->fDrawX + 1./6*pIcon->fWidth*pIcon->fScale), 0.); _cairo_dock_apply_texture_at_size_with_alpha (myData.hoverIndicator.iTexture, myData.hoverIndicator.iWidth, myData.hoverIndicator.iHeight, pData->fAlphaHover); glPopMatrix (); _cairo_dock_disable_texture (); } } } return GLDI_NOTIFICATION_LET_PASS; }
/* * 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); 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); } if (unlock_indicator) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 3.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) * Basic function so we don't have to use this code * repeatedly for objects of the same color */ void get_color(void) { switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, 68.0/255, 80.0/255, 41.0/255, 0.8); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, 143.0/255, 53.0/255, 53.0/255, 0.8); break; case STATE_PAM_IDLE: if (unlock_state == STATE_BACKSPACE_ACTIVE) { cairo_set_source_rgba(ctx, 143.0/255, 53.0/255, 53.0/255, 0.8); } else { cairo_set_source_rgba(ctx, 1, 1, 1, 0.8); } break; } } /* Circle fill */ switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, 144.0/255, 169.0/255, 89.0/255, 0.2); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, 172.0/255, 65.0/255, 66.0/255, 0.2); break; default: cairo_set_source_rgba(ctx, 0, 0, 0, 0); break; } cairo_fill_preserve(ctx); /* Circle border */ get_color(); cairo_stroke(ctx); /* Display (centered) Time */ char *timetext = malloc(6); time_t curtime = time(NULL); struct tm *tm = localtime(&curtime); strftime(timetext, 100, TIME_FORMAT, tm); /* Color text, same as border */ get_color(); cairo_set_font_size(ctx, 32.0); cairo_text_extents_t time_extents; double time_x, time_y; cairo_text_extents(ctx, timetext, &time_extents); time_x = BUTTON_CENTER - ((time_extents.width / 2) + time_extents.x_bearing); time_y = BUTTON_CENTER - ((time_extents.height / 2) + time_extents.y_bearing); cairo_move_to(ctx, time_x, time_y); cairo_show_text(ctx, timetext); cairo_close_path(ctx); free(timetext); /* 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_set_line_width(ctx, 4); 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 / 2.5)); cairo_set_operator(ctx,CAIRO_OPERATOR_CLEAR); /* Set newly drawn lines to erase what they're drawn over*/ cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_operator(ctx,CAIRO_OPERATOR_OVER); /* back to normal operator */ cairo_set_line_width(ctx, 10); /* Change color of separators based on backspace/active keypress */ get_color(); /* separator 1 */ 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); /* separator 2 */ cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 2.5) /* start */, (highlight_start + (M_PI / 2.5)) + (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 draw_shadow (cairo_t* cr, gdouble width, gdouble height, gint shadow_radius, gint corner_radius) { cairo_surface_t* tmp_surface = NULL; cairo_surface_t* new_surface = NULL; cairo_pattern_t* pattern = NULL; cairo_t* cr_surf = NULL; cairo_matrix_t matrix; raico_blur_t* blur = NULL; tmp_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4 * shadow_radius, 4 * shadow_radius); if (cairo_surface_status (tmp_surface) != CAIRO_STATUS_SUCCESS) return; cr_surf = cairo_create (tmp_surface); if (cairo_status (cr_surf) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); return; } cairo_scale (cr_surf, 1.0f, 1.0f); cairo_set_operator (cr_surf, CAIRO_OPERATOR_CLEAR); cairo_paint (cr_surf); cairo_set_operator (cr_surf, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr_surf, 0.0f, 0.0f, 0.0f, 0.75f); cairo_arc (cr_surf, 2 * shadow_radius, 2 * shadow_radius, 2.0f * corner_radius, 0.0f, 360.0f * (G_PI / 180.f)); cairo_fill (cr_surf); cairo_destroy (cr_surf); // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, shadow_radius); // now blur it raico_blur_apply (blur, tmp_surface); // blur no longer needed raico_blur_destroy (blur); new_surface = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (tmp_surface), cairo_image_surface_get_format (tmp_surface), cairo_image_surface_get_width (tmp_surface) / 2, cairo_image_surface_get_height (tmp_surface) / 2, cairo_image_surface_get_stride (tmp_surface)); pattern = cairo_pattern_create_for_surface (new_surface); if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); return; } // top left cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); cairo_rectangle (cr, 0.0f, 0.0f, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // bottom left cairo_matrix_init_scale (&matrix, 1.0f, -1.0f); cairo_matrix_translate (&matrix, 0.0f, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 0.0f, 2 * shadow_radius, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // top right cairo_matrix_init_scale (&matrix, -1.0f, 1.0f); cairo_matrix_translate (&matrix, -width, 0.0f); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, width - 2 * shadow_radius, 0.0f, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // bottom right cairo_matrix_init_scale (&matrix, -1.0f, -1.0f); cairo_matrix_translate (&matrix, -width, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 2 * shadow_radius, height - 2 * shadow_radius, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // clean up cairo_pattern_destroy (pattern); cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); }
IoObject *IoCairoSurfacePattern_setExtend(IoCairoSurfacePattern *self, IoObject *locals, IoMessage *m) { cairo_pattern_set_extend(PATTERN(self), IoMessage_locals_intArgAt_(m, locals, 0)); CHECK_STATUS(self); return self; }
void gimp_display_shell_render (GimpDisplayShell *shell, cairo_t *cr, gint x, gint y, gint w, gint h) { GimpImage *image; GeglBuffer *buffer; #ifdef USE_NODE_BLIT GeglNode *node; #endif gdouble scale_x = 1.0; gdouble scale_y = 1.0; gdouble buffer_scale = 1.0; gint viewport_offset_x; gint viewport_offset_y; gint viewport_width; gint viewport_height; gint scaled_x; gint scaled_y; gint scaled_width; gint scaled_height; cairo_surface_t *xfer; gint xfer_src_x; gint xfer_src_y; gint mask_src_x = 0; gint mask_src_y = 0; gint cairo_stride; guchar *cairo_data; GeglBuffer *cairo_buffer; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (cr != NULL); g_return_if_fail (w > 0 && h > 0); image = gimp_display_get_image (shell->display); buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (image)); #ifdef USE_NODE_BLIT node = gimp_projectable_get_graph (GIMP_PROJECTABLE (image)); #endif #ifdef GIMP_DISPLAY_RENDER_ENABLE_SCALING /* if we had this future API, things would look pretty on hires (retina) */ scale_x = gdk_window_get_scale_factor (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (shell)))); #endif scale_x = MIN (scale_x, GIMP_DISPLAY_RENDER_MAX_SCALE); scale_y = scale_x; if (shell->scale_x > shell->scale_y) { scale_y *= (shell->scale_x / shell->scale_y); buffer_scale = shell->scale_y * scale_y; } else if (shell->scale_y > shell->scale_x) { scale_x *= (shell->scale_y / shell->scale_x); buffer_scale = shell->scale_x * scale_x; } else { buffer_scale = shell->scale_x * scale_x; } gimp_display_shell_scroll_get_scaled_viewport (shell, &viewport_offset_x, &viewport_offset_y, &viewport_width, &viewport_height); scaled_x = floor ((x + viewport_offset_x) * scale_x); scaled_y = floor ((y + viewport_offset_y) * scale_y); scaled_width = ceil (w * scale_x); scaled_height = ceil (h * scale_y); if (shell->rotate_transform) { xfer = cairo_surface_create_similar_image (cairo_get_target (cr), CAIRO_FORMAT_ARGB32, scaled_width, scaled_height); cairo_surface_mark_dirty (xfer); xfer_src_x = 0; xfer_src_y = 0; } else { xfer = gimp_display_xfer_get_surface (shell->xfer, scaled_width, scaled_height, &xfer_src_x, &xfer_src_y); } cairo_stride = cairo_image_surface_get_stride (xfer); cairo_data = cairo_image_surface_get_data (xfer) + xfer_src_y * cairo_stride + xfer_src_x * 4; cairo_buffer = gegl_buffer_linear_new_from_data (cairo_data, babl_format ("cairo-ARGB32"), GEGL_RECTANGLE (0, 0, scaled_width, scaled_height), cairo_stride, NULL, NULL); if (shell->profile_transform || gimp_display_shell_has_filter (shell)) { gboolean can_convert_to_u8; /* if there is a profile transform or a display filter, we need * to use temp buffers */ can_convert_to_u8 = gimp_display_shell_profile_can_convert_to_u8 (shell); /* create the filter buffer if we have filters */ if ((gimp_display_shell_has_filter (shell) || ! can_convert_to_u8) && ! shell->filter_buffer) { gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE; gint h = GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE; shell->filter_data = gegl_malloc (w * h * babl_format_get_bytes_per_pixel (shell->filter_format)); shell->filter_stride = w * babl_format_get_bytes_per_pixel (shell->filter_format); shell->filter_buffer = gegl_buffer_linear_new_from_data (shell->filter_data, shell->filter_format, GEGL_RECTANGLE (0, 0, w, h), GEGL_AUTO_ROWSTRIDE, (GDestroyNotify) gegl_free, shell->filter_data); } if (shell->profile_transform) { /* if there is a profile transform, load the projection * pixels into the profile_buffer */ #ifndef USE_NODE_BLIT gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, gimp_projectable_get_format (GIMP_PROJECTABLE (image)), shell->profile_data, shell->profile_stride, GEGL_ABYSS_CLAMP); #else gegl_node_blit (node, buffer_scale, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), gimp_projectable_get_format (GIMP_PROJECTABLE (image)), shell->profile_data, shell->profile_stride, GEGL_BLIT_CACHE); #endif if (gimp_display_shell_has_filter (shell) || ! can_convert_to_u8) { /* if there are filters, convert the pixels from the * profile_buffer to the filter_buffer */ gimp_display_shell_profile_convert_buffer (shell, shell->profile_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height), shell->filter_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height)); } else { /* otherwise, convert the profile_buffer directly into * the cairo_buffer */ gimp_display_shell_profile_convert_buffer (shell, shell->profile_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height), cairo_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height)); } } else { /* otherwise, load the projection pixels directly into the * filter_buffer */ #ifndef USE_NODE_BLIT gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, shell->filter_format, shell->filter_data, shell->filter_stride, GEGL_ABYSS_CLAMP); #else gegl_node_blit (node, buffer_scale, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), shell->filter_format, shell->filter_data, shell->filter_stride, GEGL_BLIT_CACHE); #endif } if (gimp_display_shell_has_filter (shell)) { /* convert the filter_buffer in place */ gimp_color_display_stack_convert_buffer (shell->filter_stack, shell->filter_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height)); } if (gimp_display_shell_has_filter (shell) || ! can_convert_to_u8) { /* finally, copy the filter buffer to the cairo-ARGB32 buffer */ gegl_buffer_get (shell->filter_buffer, GEGL_RECTANGLE (0, 0, scaled_width, scaled_height), 1.0, babl_format ("cairo-ARGB32"), cairo_data, cairo_stride, GEGL_ABYSS_CLAMP); } } else { /* otherwise we can copy the projection pixels straight to the * cairo-ARGB32 buffer */ #ifndef USE_NODE_BLIT gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, babl_format ("cairo-ARGB32"), cairo_data, cairo_stride, GEGL_ABYSS_CLAMP); #else gegl_node_blit (node, buffer_scale, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), babl_format ("cairo-ARGB32"), cairo_data, cairo_stride, GEGL_BLIT_CACHE); #endif } g_object_unref (cairo_buffer); if (shell->mask) { if (! shell->mask_surface) { shell->mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE, GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE); } cairo_surface_mark_dirty (shell->mask_surface); cairo_stride = cairo_image_surface_get_stride (shell->mask_surface); cairo_data = cairo_image_surface_get_data (shell->mask_surface) + mask_src_y * cairo_stride + mask_src_x * 4; gegl_buffer_get (shell->mask, GEGL_RECTANGLE (scaled_x - shell->mask_offset_x, scaled_y - shell->mask_offset_y, scaled_width, scaled_height), buffer_scale, babl_format ("Y u8"), cairo_data, cairo_stride, GEGL_ABYSS_NONE); if (shell->mask_inverted) { gint mask_height = scaled_height; while (mask_height--) { gint mask_width = scaled_width; guchar *d = cairo_data; while (mask_width--) { guchar inv = 255 - *d; *d++ = inv; } cairo_data += cairo_stride; } } } /* put it to the screen */ cairo_save (cr); cairo_rectangle (cr, x, y, w, h); cairo_scale (cr, 1.0 / scale_x, 1.0 / scale_y); cairo_set_source_surface (cr, xfer, x * scale_x - xfer_src_x, y * scale_y - xfer_src_y); if (shell->rotate_transform) { cairo_pattern_t *pattern; pattern = cairo_get_source (cr); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_line_width (cr, 1.0); cairo_stroke_preserve (cr); cairo_surface_destroy (xfer); } cairo_clip (cr); cairo_paint (cr); if (shell->mask) { gimp_cairo_set_source_rgba (cr, &shell->mask_color); cairo_mask_surface (cr, shell->mask_surface, (x - mask_src_x) * scale_x, (y - mask_src_y) * scale_y); } cairo_restore (cr); }
void cairo_container::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg ) { cairo_t* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); rounded_rectangle(cr, bg.border_box, bg.border_radius); cairo_clip(cr); cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); cairo_clip(cr); if(bg.color.alpha) { set_color(cr, bg.color); cairo_paint(cr); } std::wstring url; t_make_url(bg.image.c_str(), bg.baseurl.c_str(), url); lock_images_cache(); images_map::iterator img_i = m_images.find(url.c_str()); if(img_i != m_images.end() && img_i->second) { image_ptr bgbmp = img_i->second; image_ptr new_img; if(bg.image_size.width != bgbmp->getWidth() || bg.image_size.height != bgbmp->getHeight()) { new_img = image_ptr(new CTxDIB); bgbmp->resample(bg.image_size.width, bg.image_size.height, new_img.get()); bgbmp = new_img; } cairo_surface_t* img = cairo_image_surface_create_for_data((unsigned char*) bgbmp->getBits(), CAIRO_FORMAT_ARGB32, bgbmp->getWidth(), bgbmp->getHeight(), bgbmp->getWidth() * 4); cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img); cairo_matrix_t flib_m; cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); cairo_pattern_set_matrix (pattern, &flib_m); switch(bg.repeat) { case litehtml::background_repeat_no_repeat: draw_txdib(cr, bgbmp.get(), bg.position_x, bg.position_y, bgbmp->getWidth(), bgbmp->getHeight()); break; case litehtml::background_repeat_repeat_x: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->getHeight()); cairo_fill(cr); break; case litehtml::background_repeat_repeat_y: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->getWidth(), bg.clip_box.height); cairo_fill(cr); break; case litehtml::background_repeat_repeat: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); cairo_fill(cr); break; } cairo_pattern_destroy(pattern); cairo_surface_destroy(img); } unlock_images_cache(); cairo_restore(cr); }
static gboolean gimp_color_bar_expose (GtkWidget *widget, GdkEventExpose *event) { GimpColorBar *bar = GIMP_COLOR_BAR (widget); cairo_t *cr; GtkAllocation allocation; cairo_surface_t *surface; cairo_pattern_t *pattern; guchar *src; guchar *dest; gint x, y; gint width, height; gint i; cr = gdk_cairo_create (event->window); gdk_cairo_region (cr, event->region); cairo_clip (cr); gtk_widget_get_allocation (widget, &allocation); x = y = gtk_container_get_border_width (GTK_CONTAINER (bar)); width = allocation.width - 2 * x; height = allocation.height - 2 * y; if (width < 1 || height < 1) return TRUE; cairo_translate (cr, allocation.x + x, allocation.y + y); cairo_rectangle (cr, 0, 0, width, height); cairo_clip (cr); surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 256, 1); for (i = 0, src = bar->buf, dest = cairo_image_surface_get_data (surface); i < 256; i++, src += 3, dest += 4) { GIMP_CAIRO_RGB24_SET_PIXEL(dest, src[0], src[1], src[2]); } cairo_surface_mark_dirty (surface); pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REFLECT); cairo_surface_destroy (surface); if (bar->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_scale (cr, (gdouble) width / 256.0, 1.0); } else { cairo_translate (cr, 0, height); cairo_scale (cr, 1.0, (gdouble) height / 256.0); cairo_rotate (cr, - G_PI / 2); } cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); cairo_paint (cr); cairo_destroy (cr); return TRUE; }
void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, GraphicsContext* context) { FloatRect srcRect = originalSrcRect; // We need to account for negative source dimensions by flipping the rectangle. if (originalSrcRect.width() < 0) { srcRect.setX(originalSrcRect.x() + originalSrcRect.width()); srcRect.setWidth(std::fabs(originalSrcRect.width())); } if (originalSrcRect.height() < 0) { srcRect.setY(originalSrcRect.y() + originalSrcRect.height()); srcRect.setHeight(std::fabs(originalSrcRect.height())); } // Cairo subsurfaces don't support floating point boundaries well, so we expand the rectangle. IntRect expandedSrcRect(enclosingIntRect(srcRect)); // We use a subsurface here so that we don't end up sampling outside the originalSrcRect rectangle. // See https://bugs.webkit.org/show_bug.cgi?id=58309 RefPtr<cairo_surface_t> subsurface = adoptRef(cairo_surface_create_for_rectangle( surface, expandedSrcRect.x(), expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height())); RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(subsurface.get())); ASSERT(m_state); switch (m_state->m_imageInterpolationQuality) { case InterpolationNone: case InterpolationLow: cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_FAST); break; case InterpolationMedium: case InterpolationHigh: cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR); break; case InterpolationDefault: cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR); break; } cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD); // The pattern transformation properly scales the pattern for when the source rectangle is a // different size than the destination rectangle. We also account for any offset we introduced // by expanding floating point source rectangle sizes. It's important to take the absolute value // of the scale since the original width and height might be negative. float scaleX = std::fabs(srcRect.width() / destRect.width()); float scaleY = std::fabs(srcRect.height() / destRect.height()); float leftPadding = static_cast<float>(expandedSrcRect.x()) - floorf(srcRect.x()); float topPadding = static_cast<float>(expandedSrcRect.y()) - floorf(srcRect.y()); cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding }; cairo_pattern_set_matrix(pattern.get(), &matrix); ShadowBlur& shadow = context->platformContext()->shadowBlur(); if (shadow.type() != ShadowBlur::NoShadow) { if (GraphicsContext* shadowContext = shadow.beginShadowLayer(context, destRect)) { drawPatternToCairoContext(shadowContext->platformContext()->cr(), pattern.get(), destRect, 1); shadow.endShadowLayer(context); } } cairo_save(m_cr.get()); drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, globalAlpha()); cairo_restore(m_cr.get()); }
static void render (cairo_t *pCairoContext, CairoDesklet *pDesklet) { CDPanelParameters *pPanel = (CDPanelParameters *) pDesklet->pRendererData; //g_print ("%s(%x)\n", __func__, pPanel); if (pPanel == NULL) return ; double fRadius = pPanel->iRadius; double fLineWidth = pPanel->iLineWidth; double fOffsetX = fRadius + fLineWidth/2; double fOffsetY = fLineWidth/2; double fFrameWidth = pDesklet->container.iWidth - 2 * fRadius - fLineWidth; double fFrameHeight = pDesklet->container.iHeight - fLineWidth; // le cadre. cairo_set_line_width (pCairoContext, pPanel->iLineWidth); cairo_move_to (pCairoContext, fOffsetX, fOffsetY); cairo_rel_curve_to (pCairoContext, fFrameWidth/2, 0, fFrameWidth/2, pPanel->iMainIconSize, fFrameWidth, pPanel->iMainIconSize); //\_________________ Coin haut droit. cairo_rel_curve_to (pCairoContext, 0, 0, fRadius, 0, fRadius, fRadius); cairo_rel_line_to (pCairoContext, 0, fFrameHeight - fRadius * 2 - pPanel->iMainIconSize); //\_________________ Coin bas droit. cairo_rel_curve_to (pCairoContext, 0, 0, 0, fRadius, -fRadius, fRadius); cairo_rel_line_to (pCairoContext, - fFrameWidth, 0); //\_________________ Coin bas gauche. cairo_rel_curve_to (pCairoContext, 0, 0, -fRadius, 0, -fRadius, - fRadius); cairo_rel_line_to (pCairoContext, 0, - (fFrameHeight - fRadius * 2)); //\_________________ Coin haut gauche. cairo_rel_curve_to (pCairoContext, 0, 0, 0, -fRadius, fRadius, -fRadius); cairo_set_source_rgba (pCairoContext, pPanel->fBgColor[0], pPanel->fBgColor[1], pPanel->fBgColor[2], 1.); cairo_stroke_preserve (pCairoContext); cairo_set_source_rgba (pCairoContext, pPanel->fBgColor[0], pPanel->fBgColor[1], pPanel->fBgColor[2], pPanel->fBgColor[3]); cairo_fill (pCairoContext); // les icones. Icon *pIcon; GList *ic; pIcon = pDesklet->pIcon; if (pIcon && pIcon->image.pSurface != NULL) { cairo_save (pCairoContext); cairo_translate (pCairoContext, pIcon->fDrawX, pIcon->fDrawY); cairo_dock_apply_image_buffer_surface_with_offset (&pIcon->image, pCairoContext, 0, 0, pIcon->fAlpha); cairo_dock_draw_icon_overlays_cairo (pIcon, pDesklet->container.fRatio, pCairoContext); cairo_restore (pCairoContext); } 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_translate (pCairoContext, pIcon->fDrawX, pIcon->fDrawY); cairo_dock_apply_image_buffer_surface_with_offset (&pIcon->image, pCairoContext, 0, 0, pIcon->fAlpha); if (pIcon->label.pSurface != NULL) { cairo_save (pCairoContext); 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_set_source_surface (pCairoContext, pIcon->label.pSurface, 0., -myIconsParam.iLabelSize); cairo_paint_with_alpha (pCairoContext, fAlpha); } else { fAlpha = .6; if (pIcon->label.iWidth > 2*pIcon->fWidth + 0 * myIconsParam.iLabelSize) { ///fOffsetX = - myIconsParam.iLabelSize; cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (fOffsetX, 0., fOffsetX + 2*pIcon->fWidth + 0*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); } cairo_translate (pCairoContext, pIcon->fWidth, - pIcon->fHeight/2); // not ideal, it should be vertically centered. cairo_dock_draw_icon_overlays_cairo (pIcon, pDesklet->container.fRatio, pCairoContext); cairo_restore (pCairoContext); } ic = cairo_dock_get_next_element (ic, pDesklet->icons); } while (ic != pFirstDrawnElement); }
/** * Create a thumbnail of a page. * * \param content content structure to thumbnail * \param bitmap the bitmap to draw to * \param url the URL the thumnail belongs to, or NULL */ bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap, const char *url) { cairo_surface_t *dsurface = bitmap->surface; cairo_surface_t *surface; cairo_t *old_cr; gint dwidth, dheight; int cwidth, cheight; struct redraw_context ctx = { .interactive = false, .background_images = true, .plot = &nsgtk_plotters }; assert(content); assert(bitmap); dwidth = cairo_image_surface_get_width(dsurface); dheight = cairo_image_surface_get_height(dsurface); /* Calculate size of buffer to render the content into */ /* We get the width from the content width, unless it exceeds 1024, * in which case we use 1024. This means we never create excessively * large render buffers for huge contents, which would eat memory and * cripple performance. */ cwidth = min(content_get_width(content), 1024); /* The height is set in proportion with the width, according to the * aspect ratio of the required thumbnail. */ cheight = ((cwidth * dheight) + (dwidth / 2)) / dwidth; /* Create surface to render into */ surface = cairo_surface_create_similar(dsurface, CAIRO_CONTENT_COLOR_ALPHA, cwidth, cheight); if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy(surface); return false; } old_cr = current_cr; current_cr = cairo_create(surface); /* render the content */ thumbnail_redraw(content, cwidth, cheight, &ctx); cairo_destroy(current_cr); current_cr = old_cr; cairo_t *cr = cairo_create(dsurface); /* Scale *before* setting the source surface (1) */ cairo_scale (cr, (double)dwidth / cwidth, (double)dheight / cheight); cairo_set_source_surface (cr, surface, 0, 0); /* To avoid getting the edge pixels blended with 0 alpha, * which would occur with the default EXTEND_NONE. Use * EXTEND_PAD for 1.2 or newer (2) */ cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REFLECT); /* Replace the destination with the source instead of overlaying */ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); /* Do the actual drawing */ cairo_paint(cr); cairo_destroy(cr); cairo_surface_destroy(surface); /* register the thumbnail with the URL */ if (url) urldb_set_thumbnail(url, bitmap); return true; }
static void gtk_css_image_radial_draw (GtkCssImage *image, cairo_t *cr, double width, double height) { GtkCssImageRadial *radial = GTK_CSS_IMAGE_RADIAL (image); cairo_pattern_t *pattern; cairo_matrix_t matrix; double x, y; double radius, yscale; double start, end; double r1, r2, r3, r4, r; double offset; int i, last; x = _gtk_css_position_value_get_x (radial->position, width); y = _gtk_css_position_value_get_y (radial->position, height); if (radial->circle) { switch (radial->size) { case GTK_CSS_EXPLICIT_SIZE: radius = _gtk_css_number_value_get (radial->sizes[0], width); break; case GTK_CSS_CLOSEST_SIDE: radius = MIN (MIN (x, width - x), MIN (y, height - y)); break; case GTK_CSS_FARTHEST_SIDE: radius = MAX (MAX (x, width - x), MAX (y, height - y)); break; case GTK_CSS_CLOSEST_CORNER: case GTK_CSS_FARTHEST_CORNER: r1 = x*x + y*y; r2 = x*x + (height - y)*(height - y); r3 = (width - x)*(width - x) + y*y; r4 = (width - x)*(width - x) + (height - y)*(height - y); if (radial->size == GTK_CSS_CLOSEST_CORNER) r = MIN ( MIN (r1, r2), MIN (r3, r4)); else r = MAX ( MAX (r1, r2), MAX (r3, r4)); radius = sqrt (r); break; default: g_assert_not_reached (); } radius = MAX (1.0, radius); yscale = 1.0; } else { double hradius, vradius; switch (radial->size) { case GTK_CSS_EXPLICIT_SIZE: hradius = _gtk_css_number_value_get (radial->sizes[0], width); vradius = _gtk_css_number_value_get (radial->sizes[1], height); break; case GTK_CSS_CLOSEST_SIDE: hradius = MIN (x, width - x); vradius = MIN (y, height - y); break; case GTK_CSS_FARTHEST_SIDE: hradius = MAX (x, width - x); vradius = MAX (y, height - y); break; case GTK_CSS_CLOSEST_CORNER: hradius = M_SQRT2 * MIN (x, width - x); vradius = M_SQRT2 * MIN (y, height - y); break; case GTK_CSS_FARTHEST_CORNER: hradius = M_SQRT2 * MAX (x, width - x); vradius = M_SQRT2 * MAX (y, height - y); break; default: g_assert_not_reached (); } hradius = MAX (1.0, hradius); vradius = MAX (1.0, vradius); radius = hradius; yscale = vradius / hradius; } gtk_css_image_radial_get_start_end (radial, radius, &start, &end); pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, radius); if (yscale != 1.0) { cairo_matrix_init_scale (&matrix, 1.0, 1.0 / yscale); cairo_pattern_set_matrix (pattern, &matrix); } if (radial->repeating) cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); else cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); offset = start; last = -1; for (i = 0; i < radial->stops->len; i++) { GtkCssImageRadialColorStop *stop; double pos, step; stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, i); if (stop->offset == NULL) { if (i == 0) pos = 0.0; else if (i + 1 == radial->stops->len) pos = 1.0; else continue; } else pos = _gtk_css_number_value_get (stop->offset, radius) / radius; pos = MAX (pos, 0); step = pos / (i - last); for (last = last + 1; last <= i; last++) { const GdkRGBA *rgba; stop = &g_array_index (radial->stops, GtkCssImageRadialColorStop, last); rgba = _gtk_css_rgba_value_get_rgba (stop->color); offset += step; cairo_pattern_add_color_stop_rgba (pattern, (offset - start) / (end - start), rgba->red, rgba->green, rgba->blue, rgba->alpha); } offset = pos; last = i; } cairo_rectangle (cr, 0, 0, width, height); cairo_translate (cr, x, y); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); }
void Pattern::setExtend( int extend ) { cairo_pattern_set_extend( mCairoPattern, static_cast<cairo_extend_t>( extend ) ); }
void lime_cairo_pattern_set_extend (value handle, int extend) { cairo_pattern_set_extend ((cairo_pattern_t*)val_data (handle), (cairo_extend_t)extend); }
void Pattern::setExtendRepeat() { cairo_pattern_set_extend( mCairoPattern, CAIRO_EXTEND_REPEAT ); }
/* * 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); 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); } /* 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], keyhlcolor[1], '\0'}, {keyhlcolor[2], keyhlcolor[3], '\0'}, {keyhlcolor[4], keyhlcolor[5], '\0'}, {keyhlcolor[6], keyhlcolor[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], bshlcolor[1], '\0'}, {bshlcolor[2], bshlcolor[3], '\0'}, {bshlcolor[4], bshlcolor[5], '\0'}, {bshlcolor[6], bshlcolor[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))}; char strgroupss[4][3] = {{separatorcolor[0], separatorcolor[1], '\0'}, {separatorcolor[2], separatorcolor[3], '\0'}, {separatorcolor[4], separatorcolor[5], '\0'}, {separatorcolor[6], separatorcolor[7], '\0'}}; uint32_t sep16[4] = {(strtol(strgroupss[0], NULL, 16)), (strtol(strgroupss[1], NULL, 16)), (strtol(strgroupss[2], NULL, 16)), (strtol(strgroupss[3], NULL, 16))}; /* https://github.com/ravinrabbid/i3lock-clock/commit/0de3a411fa5249c3a4822612c2d6c476389a1297 */ time_t rawtime; struct tm* timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); if (unlock_indicator && (unlock_state >= STATE_KEY_PRESSED || pam_state > STATE_PAM_IDLE || show_clock)) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 7.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: case STATE_PAM_LOCK: 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: case STATE_I3LOCK_LOCK_FAILED: 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: case STATE_PAM_LOCK: cairo_set_source_rgba(ctx, (double)ringver16[0]/255, (double)ringver16[1]/255, (double)ringver16[2]/255, (double)ringver16[3]/255); if (internal_line_source == 1) { line16[0] = ringver16[0]; line16[1] = ringver16[1]; line16[2] = ringver16[2]; line16[3] = ringver16[3]; } break; case STATE_PAM_WRONG: case STATE_I3LOCK_LOCK_FAILED: cairo_set_source_rgba(ctx, (double)ringwrong16[0]/255, (double)ringwrong16[1]/255, (double)ringwrong16[2]/255, (double)ringwrong16[3]/255); if (internal_line_source == 1) { line16[0] = ringwrong16[0]; line16[1] = ringwrong16[1]; line16[2] = ringwrong16[2]; line16[3] = ringwrong16[3]; } 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); if (internal_line_source == 1) { line16[0] = ring16[0]; line16[1] = ring16[1]; line16[2] = ring16[2]; line16[3] = ring16[3]; } break; } cairo_stroke(ctx); /* Draw an inner separator line. */ if (internal_line_source != 2) { //pretty sure this only needs drawn if it's being drawn over the inside? 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; char *date = NULL; char time_text[40] = {0}; char date_text[40] = {0}; /* We don't want to show more than a 3-digit number. */ char buf[4]; cairo_set_source_rgba(ctx, (double)text16[0]/255, (double)text16[1]/255, (double)text16[2]/255, (double)text16[3]/255); //this was moved up to here cairo_select_font_face(ctx, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(ctx, 28.0); switch (pam_state) { case STATE_PAM_VERIFY: text = "verifying…"; break; case STATE_PAM_LOCK: text = "locking…"; break; case STATE_PAM_WRONG: text = "wrong!"; break; case STATE_I3LOCK_LOCK_FAILED: text = "lock failed!"; 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, (double)text16[0]/255, (double)text16[1]/255, (double)text16[2]/255, (double)text16[3]/255); cairo_set_font_size(ctx, 32.0); } else if (show_clock) { strftime(time_text, 40, time_format, timeinfo); strftime(date_text, 40, date_format, timeinfo); text = time_text; date = date_text; } 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); if (date) { y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) - 6; } else { 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 (date) { cairo_text_extents_t extents; double x, y; // TODO: different date/time colors 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, 14.0); cairo_text_extents(ctx, date, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 14; cairo_move_to(ctx, x, y); cairo_show_text(ctx, date); 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_set_line_width(ctx, 7.0); 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. */ //lol no 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. */ //lol no 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)sep16[0]/255, (double)sep16[1]/255, (double)sep16[2]/255, (double)sep16[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. */ // excuse me, just gonna hack something in right here if (screen_number != -1 && screen_number < xr_screens) { int x = (xr_resolutions[screen_number].x + ((xr_resolutions[screen_number].width / 2) - (button_diameter_physical / 2))); int y = (xr_resolutions[screen_number].y + ((xr_resolutions[screen_number].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 { 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 Pattern::setExtendPad() { cairo_pattern_set_extend( mCairoPattern, CAIRO_EXTEND_PAD ); }
bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { m_ownerElement->buildGradient(); cairo_t* cr = context->platformContext(); cairo_pattern_t* pattern; cairo_matrix_t matrix; cairo_matrix_init_identity (&matrix); const cairo_matrix_t gradient_matrix = gradientTransform(); if (this->type() == LinearGradientPaintServer) { const SVGPaintServerLinearGradient* linear = static_cast<const SVGPaintServerLinearGradient*>(this); if (boundingBoxMode()) { FloatRect bbox = object->relativeBBox(false); cairo_matrix_translate(&matrix, bbox.x(), bbox.y()); cairo_matrix_scale(&matrix, bbox.width(), bbox.height()); } double x0 = linear->gradientStart().x(); double y0 = linear->gradientStart().y(); double x1 = linear->gradientEnd().x(); double y1 = linear->gradientEnd().y(); pattern = cairo_pattern_create_linear(x0, y0, x1, y1); } else if (this->type() == RadialGradientPaintServer) { const SVGPaintServerRadialGradient* radial = static_cast<const SVGPaintServerRadialGradient*>(this); if (boundingBoxMode()) { FloatRect bbox = object->relativeBBox(false); cairo_matrix_translate(&matrix, bbox.x(), bbox.y()); cairo_matrix_scale(&matrix, bbox.width(), bbox.height()); } double cx = radial->gradientCenter().x(); double cy = radial->gradientCenter().y(); double radius = radial->gradientRadius(); double fx = radial->gradientFocal().x(); double fy = radial->gradientFocal().y(); fx -= cx; fy -= cy; double fradius = 0.0; if (sqrt(fx * fx + fy * fy) > radius) { double angle = atan2(fy, fx); if ((fx + cx) < cx) fx = int(cos(angle) * radius) + 1; else fx = int(cos(angle) * radius) - 1; if ((fy + cy) < cy) fy = int(sin(angle) * radius) + 1; else fy = int(sin(angle) * radius) - 1; } pattern = cairo_pattern_create_radial(fx + cx, fy + cy, fradius, cx, cy, radius); } else { return false; } cairo_pattern_set_filter(pattern, CAIRO_FILTER_BILINEAR); switch (spreadMethod()) { case SPREADMETHOD_PAD: cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); break; case SPREADMETHOD_REFLECT: cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT); break; case SPREADMETHOD_REPEAT: cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); break; default: cairo_pattern_set_extend(pattern, CAIRO_EXTEND_NONE); break; } cairo_matrix_multiply(&matrix, &matrix, &gradient_matrix); cairo_matrix_invert(&matrix); cairo_pattern_set_matrix(pattern, &matrix); const Vector<SVGGradientStop>& stops = gradientStops(); for (unsigned i = 0; i < stops.size(); ++i) { float offset = stops[i].first; Color color = stops[i].second; cairo_pattern_add_color_stop_rgba(pattern, offset, color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0, color.alpha() / 255.0); } cairo_set_source(cr, pattern); cairo_pattern_destroy(pattern); return true; }
static int gtkDialogSetBackgroundAttrib(Ihandle* ih, const char* value) { if (iupdrvBaseSetBgColorAttrib(ih, value)) { #if GTK_CHECK_VERSION(3, 0, 0) GdkWindow* window = iupgtkGetWindow(ih->handle); if (window) gdk_window_set_background_pattern(window, NULL); #else GtkStyle *style = gtk_widget_get_style(ih->handle); if (style->bg_pixmap[GTK_STATE_NORMAL]) { style = gtk_style_copy(style); style->bg_pixmap[GTK_STATE_NORMAL] = NULL; gtk_widget_set_style(ih->handle, style); } #endif return 1; } else { GdkPixbuf* pixbuf = iupImageGetImage(value, ih, 0); if (pixbuf) { #if GTK_CHECK_VERSION(3, 0, 0) GdkWindow* window = iupgtkGetWindow(ih->handle); if (window) { /* TODO: this is NOT working!!!! */ cairo_pattern_t* pattern; int width = gdk_pixbuf_get_width(pixbuf); int height = gdk_pixbuf_get_height(pixbuf); cairo_surface_t* surface = gdk_window_create_similar_surface(window, CAIRO_CONTENT_COLOR_ALPHA, width, height); cairo_t* cr = cairo_create(surface); gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_destroy(cr); pattern = cairo_pattern_create_for_surface(surface); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); gdk_window_set_background_pattern(window, pattern); cairo_pattern_destroy (pattern); cairo_surface_destroy(surface); } #else GdkPixmap* pixmap; GtkStyle *style = gtk_style_copy(gtk_widget_get_style(ih->handle)); gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 255); style->bg_pixmap[GTK_STATE_NORMAL] = pixmap; gtk_widget_set_style(ih->handle, style); #endif return 1; } } return 0; }
/* * functions to create different wrapmodes. */ static GpStatus draw_tile_texture (cairo_t *ct, GpBitmap *bitmap, GpTexture *brush) { cairo_surface_t *original = NULL; cairo_surface_t *texture; cairo_pattern_t *pat; GpStatus status; GpRect *rect = &brush->rectangle; cairo_t *ct2; BYTE *premul = NULL; if (!rect) return InvalidParameter; gdip_bitmap_ensure_surface (bitmap); if (gdip_bitmap_format_needs_premultiplication (bitmap)) { premul = gdip_bitmap_get_premultiplied_scan0 (bitmap); if (premul) { ActiveBitmapData *data = bitmap->active_bitmap; original = cairo_image_surface_create_for_data (premul, CAIRO_FORMAT_ARGB32, data->width, data->height, data->stride); } } /* if premul isn't required (or couldn't be computed, e.g. out of memory) */ if (!original) original = bitmap->surface; /* Use the original as a pattern */ pat = cairo_pattern_create_for_surface (original); status = gdip_get_pattern_status (pat); if (status != Ok) goto cleanup; cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT); /* texture surface to be created */ texture = cairo_surface_create_similar (original, from_cairoformat_to_content (bitmap->cairo_format), rect->Width, rect->Height); status = gdip_get_status (cairo_surface_status (texture)); if (status != Ok) { cairo_pattern_destroy (pat); goto cleanup; } /* Draw the texture */ ct2 = cairo_create (texture); cairo_set_source (ct2, pat); cairo_rectangle (ct2, 0, 0, rect->Width, rect->Height); cairo_fill (ct2); cairo_destroy (ct2); brush->pattern = cairo_pattern_create_for_surface (texture); status = gdip_get_pattern_status (brush->pattern); if (status == Ok) cairo_pattern_set_extend (brush->pattern, CAIRO_EXTEND_REPEAT); cairo_pattern_destroy (pat); cairo_surface_destroy (texture); status = gdip_get_status (cairo_status (ct)); cleanup: if (premul) { cairo_surface_destroy (original); GdipFree (premul); } return status; }