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);
			}
Example #2
0
void Pattern::setExtendReflect()
{
	cairo_pattern_set_extend( mCairoPattern, CAIRO_EXTEND_REFLECT );
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #5
0
void Pattern::setExtendNone()
{
	cairo_pattern_set_extend( mCairoPattern, CAIRO_EXTEND_NONE );
}
Example #6
0
/*
 * 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;
}
Example #7
0
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);
}
Example #8
0
File: main.c Project: Zeirison/sway
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);
}
Example #9
0
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;
}
Example #10
0
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);
}
Example #11
0
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;
}
Example #13
0
/*
 * 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;
}
Example #14
0
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);
}
Example #15
0
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;
}
Example #16
0
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);
}
Example #18
0
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);
}
Example #21
0
/**
 * 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;
}
Example #22
0
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);
}
Example #23
0
void Pattern::setExtend( int extend )
{
	cairo_pattern_set_extend( mCairoPattern, static_cast<cairo_extend_t>( extend ) );
}
Example #24
0
	void lime_cairo_pattern_set_extend (value handle, int extend) {
		
		cairo_pattern_set_extend ((cairo_pattern_t*)val_data (handle), (cairo_extend_t)extend);
		
	}
Example #25
0
void Pattern::setExtendRepeat()
{
	cairo_pattern_set_extend( mCairoPattern, CAIRO_EXTEND_REPEAT );
}
Example #26
0
/*
 * 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;
}
Example #27
0
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;
}
Example #29
0
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;
}
Example #30
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;
}