Ejemplo n.º 1
0
/**
 * Sends the given character to the terminal at the given row and column,
 * rendering the character immediately. This bypasses the guac_terminal_display
 * mechanism and is intended for flushing of updates only.
 */
int __guac_terminal_set(guac_terminal_display* display, int row, int col, int codepoint) {

    int width;

    int bytes;
    char utf8[4];

    /* Use foreground color */
    const guac_terminal_color* color = &display->glyph_foreground;

    /* Use background color */
    const guac_terminal_color* background = &display->glyph_background;

    cairo_surface_t* surface;
    cairo_t* cairo;
    int surface_width, surface_height;
   
    PangoLayout* layout;
    int layout_width, layout_height;
    int ideal_layout_width, ideal_layout_height;

    /* Calculate width in columns */
    width = wcwidth(codepoint);
    if (width < 0)
        width = 1;

    /* Do nothing if glyph is empty */
    if (width == 0)
        return 0;

    /* Convert to UTF-8 */
    bytes = guac_terminal_encode_utf8(codepoint, utf8);

    surface_width = width * display->char_width;
    surface_height = display->char_height;

    ideal_layout_width = surface_width * PANGO_SCALE;
    ideal_layout_height = surface_height * PANGO_SCALE;

    /* Prepare surface */
    surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
                                         surface_width, surface_height);
    cairo = cairo_create(surface);

    /* Fill background */
    cairo_set_source_rgb(cairo,
            background->red   / 255.0,
            background->green / 255.0,
            background->blue  / 255.0);

    cairo_rectangle(cairo, 0, 0, surface_width, surface_height); 
    cairo_fill(cairo);

    /* Get layout */
    layout = pango_cairo_create_layout(cairo);
    pango_layout_set_font_description(layout, display->font_desc);
    pango_layout_set_text(layout, utf8, bytes);
    pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);

    pango_layout_get_size(layout, &layout_width, &layout_height);

    /* If layout bigger than available space, scale it back */
    if (layout_width > ideal_layout_width || layout_height > ideal_layout_height) {

        double scale = fmin(ideal_layout_width  / (double) layout_width,
                            ideal_layout_height / (double) layout_height);

        cairo_scale(cairo, scale, scale);

        /* Update layout to reflect scaled surface */
        pango_layout_set_width(layout, ideal_layout_width / scale);
        pango_layout_set_height(layout, ideal_layout_height / scale);
        pango_cairo_update_layout(cairo, layout);

    }

    /* Draw */
    cairo_set_source_rgb(cairo,
            color->red   / 255.0,
            color->green / 255.0,
            color->blue  / 255.0);

    cairo_move_to(cairo, 0.0, 0.0);
    pango_cairo_show_layout(cairo, layout);

    /* Draw */
    guac_common_surface_draw(display->display_surface,
        display->char_width * col,
        display->char_height * row,
        surface);

    /* Free all */
    g_object_unref(layout);
    cairo_destroy(cairo);
    cairo_surface_destroy(surface);

    return 0;

}
Ejemplo n.º 2
0
void
blur_surface(cairo_surface_t *surface, int margin)
{
	cairo_surface_t *tmp;
	int32_t width, height, stride, x, y, z, w;
	uint8_t *src, *dst;
	uint32_t *s, *d, a, p;
	int i, j, k, size = 17, half;
	uint8_t kernel[100];
	double f;

	width = cairo_image_surface_get_width(surface);
	height = cairo_image_surface_get_height(surface);
	stride = cairo_image_surface_get_stride(surface);
	src = cairo_image_surface_get_data(surface);

	tmp = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
	dst = cairo_image_surface_get_data(tmp);

	half = size / 2;
	a = 0;
	for (i = 0; i < size; i++) {
		f = (i - half);
		kernel[i] = exp(- f * f / 30.0) * 80;
		a += kernel[i];
	}

	for (i = 0; i < height; i++) {
		s = (uint32_t *) (src + i * stride);
		d = (uint32_t *) (dst + i * stride);
		for (j = 0; j < width; j++) {
			if (margin < j && j < width - margin &&
			    margin < i && i < height - margin)
				continue;
			x = 0;
			y = 0;
			z = 0;
			w = 0;
			for (k = 0; k < size; k++) {
				if (j - half + k < 0 || j - half + k >= width)
					continue;
				p = s[j - half + k];

				x += (p >> 24) * kernel[k];
				y += ((p >> 16) & 0xff) * kernel[k];
				z += ((p >> 8) & 0xff) * kernel[k];
				w += (p & 0xff) * kernel[k];
			}
			d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a;
		}
	}

	for (i = 0; i < height; i++) {
		s = (uint32_t *) (dst + i * stride);
		d = (uint32_t *) (src + i * stride);
		for (j = 0; j < width; j++) {
			if (margin <= j && j < width - margin &&
			    margin <= i && i < height - margin)
				continue;
			x = 0;
			y = 0;
			z = 0;
			w = 0;
			for (k = 0; k < size; k++) {
				if (i - half + k < 0 || i - half + k >= height)
					continue;
				s = (uint32_t *) (dst + (i - half + k) * stride);
				p = s[j];

				x += (p >> 24) * kernel[k];
				y += ((p >> 16) & 0xff) * kernel[k];
				z += ((p >> 8) & 0xff) * kernel[k];
				w += (p & 0xff) * kernel[k];
			}
			d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a;
		}
	}

	cairo_surface_destroy(tmp);
}
Ejemplo n.º 3
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_t *ctx1 = 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);



            cairo_text_extents_t extents;
            double x, y;

            cairo_set_source_rgb(ctx1, 0, 0, 0);
            cairo_set_font_size(ctx1, 12.0);

            cairo_text_extents(ctx1, flg_string, &extents);
            x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing) - 12;
            y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 75 ;

            cairo_move_to(ctx1, x, y);
            cairo_show_text(ctx1, flg_string);
            cairo_close_path(ctx1);





    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;
        switch (pam_state) {
            case STATE_PAM_VERIFY:
                text = "verifying…";
                break;
            case STATE_PAM_WRONG:
                text = "wrong!";
                break;
            default:
                break;
        }

        if (text) {
            cairo_text_extents_t extents;
            double x, y;

            cairo_set_source_rgb(ctx, 0, 0, 0);
            cairo_set_font_size(ctx, 28.0);

            cairo_text_extents(ctx, text, &extents);
            x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing);
            y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing);

            cairo_move_to(ctx, x, y);
            cairo_show_text(ctx, text);
            cairo_close_path(ctx);
        }


        /* After the user pressed any valid key or the backspace key, we
         * highlight a random part of the unlock indicator to confirm this
         * keypress. */
        if (unlock_state == STATE_KEY_ACTIVE ||
            unlock_state == STATE_BACKSPACE_ACTIVE) {
            cairo_new_sub_path(ctx);
            double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0;
            cairo_arc(ctx,
                      BUTTON_CENTER /* x */,
                      BUTTON_CENTER /* y */,
                      BUTTON_RADIUS /* radius */,
                      highlight_start,
                      highlight_start + (M_PI / 3.0));
            if (unlock_state == STATE_KEY_ACTIVE) {
                /* For normal keys, we use a lighter green. */
                cairo_set_source_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;
}
Ejemplo n.º 4
0
void PangoTexture::generate(const std::string& text){
    cairo_t* layout_context;
    cairo_t* render_context;
    cairo_surface_t* temp_surface;
    cairo_surface_t* surface;
    unsigned char* surface_data = NULL;
    PangoFontDescription *desc;
    PangoLayout* layout;

    //create layout context
    cairo_surface_t* ltemp_surface;
    ltemp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);

    layout_context  = cairo_create(ltemp_surface);
    cairo_surface_destroy(ltemp_surface);
    //cairo surface set, make pango layout
    layout = pango_cairo_create_layout(layout_context);
    pango_layout_set_text(layout, text.c_str(), -1);

    //load fond
    desc = pango_font_description_from_string(font.c_str());
    pango_layout_set_font_description(layout, desc);
    pango_font_description_free(desc);

    //get_text_size(layout, text_width, text_height);

    pango_layout_get_size(layout, &width, &height);
    //printf("width is %d\n", width);
    //printf("height is %d\n", height);

    width /= PANGO_SCALE;
    height /= PANGO_SCALE;

    //printf("width is %d\n", width);
    //printf("pango height is %d\n", height);

    surface_data = (unsigned char*)calloc(4 * width * height, sizeof(unsigned char));
    surface = cairo_image_surface_create_for_data(surface_data,
                        CAIRO_FORMAT_ARGB32,
                        width,
                        height,
                        4 * width);
    //channels == 4
    render_context = cairo_create(surface);
    cairo_set_source_rgba(render_context, 1, 1, 1, 1);
    pango_cairo_show_layout( render_context, layout);

    glBindTexture(GL_TEXTURE_2D, texture_id);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D,
                 0,
                 GL_RGBA,
                 width,
                 height,
                 0,
                 GL_BGRA,
                 GL_UNSIGNED_BYTE,
                 surface_data);

}
Ejemplo n.º 5
0
GIcon *
photos_utils_create_symbolic_icon_for_scale (const gchar *name, gint base_size, gint scale)
{
  g_autoptr (GIcon) icon = NULL;
  GIcon *ret_val = NULL;
  g_autoptr (GdkPixbuf) pixbuf = NULL;
  g_autoptr (GtkIconInfo) info = NULL;
  GtkIconTheme *theme;
  g_autoptr (GtkStyleContext) style = NULL;
  g_autoptr (GtkWidgetPath) path = NULL;
  cairo_surface_t *icon_surface = NULL; /* TODO: use g_autoptr */
  cairo_surface_t *surface; /* TODO: use g_autoptr */
  cairo_t *cr; /* TODO: use g_autoptr */
  g_autofree gchar *symbolic_name = NULL;
  const gint bg_size = 24;
  const gint emblem_margin = 4;
  gint emblem_pos;
  gint emblem_size;
  gint total_size;
  gint total_size_scaled;

  total_size = base_size / 2;
  total_size_scaled = total_size * scale;
  emblem_size = bg_size - emblem_margin * 2;

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled);
  cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale);
  cr = cairo_create (surface);

  style = gtk_style_context_new ();

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (style, path);

  gtk_style_context_add_class (style, "photos-icon-bg");

  gtk_render_background (style, cr, total_size - bg_size, total_size - bg_size, bg_size, bg_size);

  symbolic_name = g_strconcat (name, "-symbolic", NULL);
  icon = g_themed_icon_new_with_default_fallbacks (symbolic_name);

  theme = gtk_icon_theme_get_default();
  info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale, GTK_ICON_LOOKUP_FORCE_SIZE);
  if (info == NULL)
    goto out;

  pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
  if (pixbuf == NULL)
    goto out;

  icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);

  emblem_pos = total_size - emblem_size - emblem_margin;
  gtk_render_icon_surface (style, cr, icon_surface, emblem_pos, emblem_pos);

  ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled));

 out:
  cairo_surface_destroy (icon_surface);
  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  return ret_val;
}
Ejemplo n.º 6
0
bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
{
    if (!m_image)
        return false;
    // We need this to stay in scope because the native image is just a shallow copy of the data.
    m_decoder = new ImageSource(premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied, ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
    if (!m_decoder)
        return false;
    ImageSource& decoder = *m_decoder;

    m_alphaOp = AlphaDoNothing;
    if (m_image->data()) {
        decoder.setData(m_image->data(), true);
        if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
            return false;
        m_imageSurface = decoder.createFrameAtIndex(0);
    } else {
        m_imageSurface = m_image->nativeImageForCurrentFrame();
        // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value is 0xFF for each pixel,
        // which is true at present and may be changed in the future and needs adjustment accordingly.
        // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port, 
        // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
        if (!premultiplyAlpha && m_imageHtmlDomSource != HtmlDomVideo)
            m_alphaOp = AlphaDoUnmultiply;

        // if m_imageSurface is not an image, extract a copy of the surface
        if (m_imageSurface && cairo_surface_get_type(m_imageSurface.get()) != CAIRO_SURFACE_TYPE_IMAGE) {
            RefPtr<cairo_surface_t> tmpSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_imageWidth, m_imageHeight));
            copyRectFromOneSurfaceToAnother(m_imageSurface.get(), tmpSurface.get(), IntSize(), IntRect(0, 0, m_imageWidth, m_imageHeight), IntSize(), CAIRO_OPERATOR_SOURCE);
            m_imageSurface = tmpSurface.release();
        }
    }

    if (!m_imageSurface)
        return false;

    ASSERT(cairo_surface_get_type(m_imageSurface.get()) == CAIRO_SURFACE_TYPE_IMAGE);

    IntSize imageSize = cairoSurfaceSize(m_imageSurface.get());
    m_imageWidth = imageSize.width();
    m_imageHeight = imageSize.height();
    if (!m_imageWidth || !m_imageHeight)
        return false;

    if (cairo_image_surface_get_format(m_imageSurface.get()) != CAIRO_FORMAT_ARGB32)
        return false;

    unsigned int srcUnpackAlignment = 1;
    size_t bytesPerRow = cairo_image_surface_get_stride(m_imageSurface.get());
    size_t bitsPerPixel = 32;
    unsigned padding = bytesPerRow - bitsPerPixel / 8 * m_imageWidth;
    if (padding) {
        srcUnpackAlignment = padding + 1;
        while (bytesPerRow % srcUnpackAlignment)
            ++srcUnpackAlignment;
    }

    m_imagePixelData = cairo_image_surface_get_data(m_imageSurface.get());
    m_imageSourceFormat = DataFormatBGRA8;
    m_imageSourceUnpackAlignment = srcUnpackAlignment;
    return true;
}
Ejemplo n.º 7
0
 void text_rsrc::updatePixels_setup( text_update_context* context )
 {
     // Set up Cairo then Pango with initial values /////////////////////////////////////////////////////////////////////////////////////////////////////////
     
     context -> c_surf = cairo_image_surface_create( CAIRO_FORMAT_A8,        // We only need alpha, coloring is handled by OpenGL
                                                     dimensions[ 0 ],
                                                     dimensions[ 1 ] );
     context -> c_status = cairo_surface_status( context -> c_surf );
     if( context -> c_status )
     {
         exception e;
         ff::write( *e,
                    "text_rsrc::updatePixels(): Error creating Cairo surface: ",
                    cairo_status_to_string( context -> c_status ) );
         throw e;
     }
     
     context -> c_context = cairo_create( context -> c_surf );
     context -> c_status = cairo_status( context -> c_context );
     if( context -> c_status )
     {
         exception e;
         ff::write( *e,
                    "text_rsrc::updatePixels(): Error creating Cairo context: ",
                    cairo_status_to_string( context -> c_status ) );
         throw e;
     }
     cairo_surface_destroy( context -> c_surf );                                // Dereference surface
      
     context -> p_layout = pango_cairo_create_layout( context -> c_context );
     
     // Customize Pango layout & font ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
     if( max_dimensions[ 0 ] < 0 )
         pango_layout_set_width( context -> p_layout,
                                 -1 );
     else
         pango_layout_set_width( context -> p_layout,
                                 max_dimensions[ 0 ] * PANGO_SCALE );
     if( max_dimensions[ 1 ] < 0 )
         pango_layout_set_height( context -> p_layout,
                                  -1 );
     else
         pango_layout_set_height( context -> p_layout,
                                  max_dimensions[ 1 ] * PANGO_SCALE );
     
     context -> c_fontops = cairo_font_options_create();
     
     if( hinting_enabled )
         cairo_font_options_set_hint_style( context -> c_fontops,
                                            CAIRO_HINT_STYLE_DEFAULT );
     else
         cairo_font_options_set_hint_style( context -> c_fontops,
                                            CAIRO_HINT_STYLE_NONE );
     
     if( antialiasing_enabled )
         cairo_font_options_set_antialias( context -> c_fontops,
                                           CAIRO_ANTIALIAS_DEFAULT );
     else
         cairo_font_options_set_antialias( context -> c_fontops,
                                           CAIRO_ANTIALIAS_NONE );
     
     // TODO: Potentially set subpixel rendering
     
     pango_cairo_context_set_font_options( pango_layout_get_context( context -> p_layout ),
                                           context -> c_fontops );           // Many thanks to ui/gfc/pango_util.cc from the Chromium project, which appears
                                                                             // to be the only online example of setting PangoCairo font options
     
     context -> p_fontd = pango_font_description_from_string( font.c_str() );
     
     pango_font_description_set_absolute_size( context -> p_fontd,
                                               point_size * PANGO_SCALE );
     
     pango_layout_set_font_description( context -> p_layout,
                                        context -> p_fontd );
     pango_font_description_free( context -> p_fontd );                      // Dereference font description
     
     switch( ellipsize )
     {
         case NONE:
             pango_layout_set_ellipsize( context -> p_layout,
                                         PANGO_ELLIPSIZE_NONE );
             break;
         case BEGINNING:
             pango_layout_set_ellipsize( context -> p_layout,
                                         PANGO_ELLIPSIZE_START );
             break;
         case MIDDLE:
             pango_layout_set_ellipsize( context -> p_layout,
                                         PANGO_ELLIPSIZE_MIDDLE );
             break;
         case END:
             pango_layout_set_ellipsize( context -> p_layout,
                                         PANGO_ELLIPSIZE_END );
             break;
         default:
             throw exception( "text_rsrc::updatePixels(): Unknown ellipsize mode" );
     }
     
     pango_layout_set_text( context -> p_layout,
                            string.c_str(),
                            -1 );
     
     pango_cairo_update_layout( context -> c_context,
                                context -> p_layout );
 }
Ejemplo n.º 8
0
GdkPixbuf* ease_slide_button_panel_pixbuf (EaseSlide* slide, gint width) {
#line 428 "ease-slide-button-panel.c"
	GdkPixbuf* result = NULL;
	gint height;
	cairo_surface_t* surface;
	cairo_t* context;
	char* _tmp0_;
	char* _tmp1_;
	char* _tmp2_;
	char* path;
	GError * _inner_error_ = NULL;
#line 178 "ease-slide-button-panel.vala"
	g_return_val_if_fail (slide != NULL, NULL);
#line 180 "ease-slide-button-panel.vala"
	height = (gint) ((((float) width) * ease_slide_get_height (slide)) / ease_slide_get_width (slide));
#line 182 "ease-slide-button-panel.vala"
	surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
#line 184 "ease-slide-button-panel.vala"
	context = cairo_create (surface);
#line 185 "ease-slide-button-panel.vala"
	cairo_save (context);
#line 186 "ease-slide-button-panel.vala"
	cairo_scale (context, (double) (((float) width) / ease_slide_get_width (slide)), (double) (((float) height) / ease_slide_get_height (slide)));
#line 450 "ease-slide-button-panel.c"
	{
#line 191 "ease-slide-button-panel.vala"
		ease_slide_cairo_render_small (slide, context);
#line 454 "ease-slide-button-panel.c"
	}
	goto __finally17;
	__catch17_g_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		{
#line 195 "ease-slide-button-panel.vala"
			g_critical (_ ("Error drawing slide preview: %s"), e->message);
#line 465 "ease-slide-button-panel.c"
			_g_error_free0 (e);
		}
	}
	__finally17:
	if (_inner_error_ != NULL) {
		_cairo_destroy0 (context);
		_cairo_surface_destroy0 (surface);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
#line 199 "ease-slide-button-panel.vala"
	cairo_restore (context);
#line 201 "ease-slide-button-panel.vala"
	cairo_rectangle (context, (double) 0, (double) 0, (double) width, (double) height);
#line 202 "ease-slide-button-panel.vala"
	cairo_set_source_rgb (context, (double) 0, (double) 0, (double) 0);
#line 203 "ease-slide-button-panel.vala"
	cairo_stroke (context);
#line 206 "ease-slide-button-panel.vala"
	path = (_tmp2_ = g_build_filename (ease_slide_button_panel_get_temp_dir (), _tmp1_ = g_strconcat (_tmp0_ = g_strdup_printf ("%i", ease_slide_button_panel_temp_count++), ".png", NULL), NULL), _g_free0 (_tmp1_), _g_free0 (_tmp0_), _tmp2_);
#line 208 "ease-slide-button-panel.vala"
	cairo_surface_write_to_png (surface, path);
#line 489 "ease-slide-button-panel.c"
	{
		GdkPixbuf* pb;
#line 212 "ease-slide-button-panel.vala"
		pb = gdk_pixbuf_new_from_file (path, &_inner_error_);
#line 494 "ease-slide-button-panel.c"
		if (_inner_error_ != NULL) {
			goto __catch18_g_error;
		}
#line 213 "ease-slide-button-panel.vala"
		g_remove (path);
#line 500 "ease-slide-button-panel.c"
		result = pb;
		_g_free0 (path);
		_cairo_destroy0 (context);
		_cairo_surface_destroy0 (surface);
#line 214 "ease-slide-button-panel.vala"
		return result;
#line 507 "ease-slide-button-panel.c"
	}
	goto __finally18;
	__catch18_g_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		{
#line 216 "ease-slide-button-panel.vala"
			g_error ("ease-slide-button-panel.vala:216: %s", e->message);
#line 518 "ease-slide-button-panel.c"
			_g_error_free0 (e);
		}
	}
	__finally18:
	{
		_g_free0 (path);
		_cairo_destroy0 (context);
		_cairo_surface_destroy0 (surface);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
	_g_free0 (path);
	_cairo_destroy0 (context);
	_cairo_surface_destroy0 (surface);
}
static void
on_screenshot_finished (GObject *source,
                        GAsyncResult *res,
                        gpointer user_data)
{
  ScreenshotData *data = user_data;
  CcBackgroundPanel *panel = data->panel;
  CcBackgroundPanelPrivate *priv;
  GError *error;
  GdkPixbuf *pixbuf;
  cairo_surface_t *surface;
  cairo_t *cr;
  GVariant *result;

  error = NULL;
  result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
                                          res,
                                          &error);

  if (result == NULL) {
    if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      g_error_free (error);
      g_free (data);
      return;
    }
    g_debug ("Unable to get screenshot: %s",
             error->message);
    g_error_free (error);
    /* fallback? */
    priv = panel->priv;
    goto out;
  }
  g_variant_unref (result);

  priv = panel->priv;

  pixbuf = gdk_pixbuf_new_from_file (panel->priv->screenshot_path, &error);
  if (pixbuf == NULL)
    {
      g_debug ("Unable to use GNOME Shell's builtin screenshot interface: %s",
               error->message);
      g_error_free (error);
      goto out;
    }

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                        data->monitor_rect.width, data->monitor_rect.height);
  cr = cairo_create (surface);
  gdk_cairo_set_source_pixbuf (cr, pixbuf,
                               data->capture_rect.x - data->monitor_rect.x,
                               data->capture_rect.y - data->monitor_rect.y);
  cairo_paint (cr);
  g_object_unref (pixbuf);

  if (data->whole_monitor) {
    /* clear the workarea */
    cairo_save (cr);
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
    cairo_rectangle (cr, data->workarea_rect.x - data->monitor_rect.x,
                     data->workarea_rect.y - data->monitor_rect.y,
                     data->workarea_rect.width,
                     data->workarea_rect.height);
    cairo_fill (cr);
    cairo_restore (cr);
  }

  g_clear_object (&panel->priv->display_screenshot);
  panel->priv->display_screenshot = gdk_pixbuf_get_from_surface (surface,
                                                                 0, 0,
                                                                 data->monitor_rect.width,
                                                                 data->monitor_rect.height);

  /* remove the temporary file created by the shell */
  g_unlink (panel->priv->screenshot_path);
  g_clear_pointer (&priv->screenshot_path, g_free);

  cairo_destroy (cr);
  cairo_surface_destroy (surface);

 out:
  update_display_preview (panel, WID ("background-desktop-drawingarea"), priv->current_background);
  g_free (data);
}
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);
}
void
setup_tile (gint w, gint h)
{
	cairo_status_t   status;
	cairo_t*         cr          = NULL;
	cairo_surface_t* cr_surf     = NULL;
	cairo_surface_t* tmp         = NULL;
	cairo_surface_t* dummy_surf  = NULL;
	cairo_surface_t* norm_surf   = NULL;
	cairo_surface_t* blur_surf   = NULL;
	gdouble          width       = (gdouble) w;
	gdouble          height      = (gdouble) h;
	raico_blur_t*    blur        = NULL;

	cr_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					      3 * BUBBLE_SHADOW_SIZE,
					      3 * BUBBLE_SHADOW_SIZE);
	status = cairo_surface_status (cr_surf);
	if (status != CAIRO_STATUS_SUCCESS)
		g_print ("Error: \"%s\"\n", cairo_status_to_string (status));

	cr = cairo_create (cr_surf);
	status = cairo_status (cr);
	if (status != CAIRO_STATUS_SUCCESS)
	{
		cairo_surface_destroy (cr_surf);
		g_print ("Error: \"%s\"\n", cairo_status_to_string (status));
	}

	// clear and render drop-shadow and bubble-background
	cairo_scale (cr, 1.0f, 1.0f);
	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
	cairo_paint (cr);
	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);

	if (g_composited)
	{
		draw_shadow (cr,
			     width,
			     height,
			     BUBBLE_SHADOW_SIZE,
			     CORNER_RADIUS);
		cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
		draw_round_rect (cr,
				 1.0f,
				 (gdouble) BUBBLE_SHADOW_SIZE,
				 (gdouble) BUBBLE_SHADOW_SIZE,
				 (gdouble) CORNER_RADIUS,
				 (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE),
				 (gdouble) (height - 2.0f* BUBBLE_SHADOW_SIZE));
		cairo_fill (cr);
		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
		cairo_set_source_rgba (cr,
				       BUBBLE_BG_COLOR_R,
				       BUBBLE_BG_COLOR_G,
				       BUBBLE_BG_COLOR_B,
				       0.95f);
	}
	else
		cairo_set_source_rgb (cr,
				      BUBBLE_BG_COLOR_R,
				      BUBBLE_BG_COLOR_G,
				      BUBBLE_BG_COLOR_B);
	draw_round_rect (cr,
			 1.0f,
			 BUBBLE_SHADOW_SIZE,
			 BUBBLE_SHADOW_SIZE,
			 CORNER_RADIUS,
			 (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE),
			 (gdouble) (height - 2.0f * BUBBLE_SHADOW_SIZE));
	cairo_fill (cr);

	tmp = cairo_image_surface_create_for_data (
			cairo_image_surface_get_data (cr_surf),
			cairo_image_surface_get_format (cr_surf),
			3 * BUBBLE_SHADOW_SIZE,
			3 * BUBBLE_SHADOW_SIZE,
			cairo_image_surface_get_stride (cr_surf));
	dummy_surf = copy_surface (tmp);
	cairo_surface_destroy (tmp);

	tmp = cairo_image_surface_create_for_data (
			cairo_image_surface_get_data (dummy_surf),
			cairo_image_surface_get_format (dummy_surf),
			2 * BUBBLE_SHADOW_SIZE,
			2 * BUBBLE_SHADOW_SIZE,
			cairo_image_surface_get_stride (dummy_surf));
	norm_surf = copy_surface (tmp);
	cairo_surface_destroy (tmp);

	blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW);
	raico_blur_set_radius (blur, 6);
	raico_blur_apply (blur, dummy_surf);
	raico_blur_destroy (blur);

	tmp = cairo_image_surface_create_for_data (
			cairo_image_surface_get_data (dummy_surf),
			cairo_image_surface_get_format (dummy_surf),
			2 * BUBBLE_SHADOW_SIZE,
			2 * BUBBLE_SHADOW_SIZE,
			cairo_image_surface_get_stride (dummy_surf));
	blur_surf = copy_surface (tmp);
	cairo_surface_destroy (tmp);
	cairo_surface_destroy (dummy_surf);

	g_tile = tile_new_for_padding (norm_surf, blur_surf);
	cairo_surface_destroy (norm_surf);
	cairo_surface_destroy (blur_surf);

	cairo_surface_destroy (cr_surf);
	cairo_destroy (cr);
}
Ejemplo n.º 12
0
static void
gnm_so_path_set_property (GObject *obj, guint param_id,
			     GValue const *value, GParamSpec *pspec)
{
	GnmSOPath *sop = GNM_SO_PATH (obj);

	switch (param_id) {
	case SOP_PROP_STYLE: {
		GOStyle *style = go_style_dup (g_value_get_object (value));
		style->interesting_fields = GO_STYLE_OUTLINE | GO_STYLE_FILL;
		g_object_unref (sop->style);
		sop->style = style;
		break;
	}
	case SOP_PROP_PATH: {
		GOPath *path = g_value_get_boxed (value);
		if (sop->path)
			go_path_free (sop->path);
		else if (sop->paths)
			g_ptr_array_unref (sop->paths);
		sop->path = NULL;
		sop->paths = NULL;
		if (path) {
			cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
			cairo_t *cr = cairo_create (surface);

			sop->path = go_path_ref (path);
			/* evaluates the bounding rectangle */
			go_path_to_cairo (path, GO_PATH_DIRECTION_FORWARD, cr);
			cairo_fill_extents (cr,
			                    &sop->x_offset, &sop->y_offset,
			                    &sop->width, &sop->height);
			sop->width -= sop->x_offset;
			sop->height -= sop->y_offset;
			cairo_destroy (cr);
			cairo_surface_destroy (surface);
		}
		break;
	}
	case SOP_PROP_PATHS: {
		GPtrArray *paths = g_value_get_boxed (value);
		unsigned i;
		for (i = 0; i < paths->len; i++)
			/* we can only check that the path is not NULL */
			g_return_if_fail (g_ptr_array_index (paths, i) != NULL);
		if (sop->path)
			go_path_free (sop->path);
		else if (sop->paths)
			g_ptr_array_unref (sop->paths);
		sop->path = NULL;
		sop->paths = NULL;
		if (paths) {
			cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
			cairo_t *cr = cairo_create (surface);

			sop->paths = g_ptr_array_ref (paths);
			/* evaluates the bounding rectangle */
			for (i = 0; i < paths->len; i++)
				go_path_to_cairo ((GOPath *) g_ptr_array_index (paths, i),
				                  GO_PATH_DIRECTION_FORWARD, cr);
			cairo_fill_extents (cr,
			                    &sop->x_offset, &sop->y_offset,
			                    &sop->width, &sop->height);
			sop->width -= sop->x_offset;
			sop->height -= sop->y_offset;
			cairo_destroy (cr);
			cairo_surface_destroy (surface);
		}
		break;
	}
	case SOP_PROP_TEXT: {
		char const *str = g_value_get_string (value);
		g_free (sop->text);
		sop->text = g_strdup (str == NULL ? "" : str);
		break;
	}
	case SOP_PROP_MARKUP:
		if (sop->markup != NULL)
			pango_attr_list_unref (sop->markup);
		sop->markup = g_value_peek_pointer (value);
		if (sop->markup != NULL)
			pango_attr_list_ref (sop->markup);
		break;

	case SOP_PROP_VIEWBOX:
		/* not settable */
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
		return;
	}
}
Ejemplo n.º 13
0
/*
 * This function must be called with a range of samples, and a desired
 * width and height.
 * It will average samples if needed.
 */
static PyObject *
py_fill_surface (PyObject * self, PyObject * args)
{
  PyObject *samples;
  PyObject *sampleObj;
  int length, i;
  double sample;
  cairo_surface_t *surface;
  cairo_t *ctx;
  int width, height;
  float pixelsPerSample;
  float currentPixel;
  int samplesInAccum;
  float x = 0.;
  double accum;

  if (!PyArg_ParseTuple (args, "O!ii", &PyList_Type, &samples, &width, &height))
    return NULL;

  length = PyList_Size (samples);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);

  ctx = cairo_create (surface);

  cairo_set_source_rgb (ctx, 0.2, 0.6, 0.0);
  cairo_set_line_width (ctx, 0.5);
  cairo_move_to (ctx, 0, height);

  pixelsPerSample = width / (float) length;
  currentPixel = 0.;
  samplesInAccum = 0;
  accum = 0.;

  for (i = 0; i < length; i++) {
    /* Guaranteed to return something */
    sampleObj = PyList_GetItem (samples, i);
    sample = PyFloat_AsDouble (sampleObj);

    /* If the object was not a float or convertible to float */
    if (PyErr_Occurred ()) {
      cairo_surface_finish (surface);
      Py_DECREF (samples);
      return NULL;
    }

    currentPixel += pixelsPerSample;
    samplesInAccum += 1;
    accum += sample;
    if (currentPixel > 1.0) {
      accum /= samplesInAccum;
      cairo_line_to (ctx, x, height - accum);
      accum = 0;
      currentPixel -= 1.0;
      samplesInAccum = 0;
    }
    x += pixelsPerSample;
  }

  Py_DECREF (samples);
  cairo_line_to (ctx, width, height);
  cairo_close_path (ctx);
  cairo_fill_preserve (ctx);

  return PycairoSurface_FromSurface (surface, NULL);
}
Ejemplo n.º 14
0
/******************************************************************************
 *                            Basic events handlers                           *
 ******************************************************************************/
static gboolean
configure_event(GtkWidget* widget, GdkEventConfigure* dummy, gpointer data)
{
    (void) dummy;
    GtkAllocation allocation;

    int new_pixmap_width, new_pixmap_height;

    gtk_widget_get_allocation(widget, &allocation);
    new_pixmap_width = allocation.width - BORDER_SIZE * 2;
    new_pixmap_height = allocation.height - BORDER_SIZE *2;
    Monitor *m;

    m = (Monitor *) data;

    if (new_pixmap_width > 0 && new_pixmap_height > 0)
    {
        /*
         * If the stats buffer does not exist (first time we get inside this
         * function) or its size changed, reallocate the buffer and preserve
         * existing data.
         */
        if (!m->stats || (new_pixmap_width != m->pixmap_width))
        {
            stats_set *new_stats = g_new0(stats_set, new_pixmap_width);

            if (!new_stats)
                return TRUE;

            if (m->stats)
            {
                /* New allocation is larger.
                 * Add new "oldest" samples of zero following the cursor*/
                if (new_pixmap_width > m->pixmap_width)
                {
                    /* Number of values between the ring cursor and the end of
                     * the buffer */
                    int nvalues = m->pixmap_width - m->ring_cursor;

                    memcpy(new_stats,
                           m->stats,
                           m->ring_cursor * sizeof (stats_set));
                    memcpy(new_stats + nvalues,
                           m->stats + m->ring_cursor,
                           nvalues * sizeof(stats_set));
                }
                /* New allocation is smaller, but still larger than the ring
                 * buffer cursor */
                else if (m->ring_cursor <= new_pixmap_width)
                {
                    /* Numver of values that can be stored between the end of
                     * the new buffer and the ring cursor */
                    int nvalues = new_pixmap_width - m->ring_cursor;
                    memcpy(new_stats,
                           m->stats,
                           m->ring_cursor * sizeof(stats_set));
                    memcpy(new_stats + m->ring_cursor,
                           m->stats + m->pixmap_width - nvalues,
                           nvalues * sizeof(stats_set));
                }
                /* New allocation is smaller, and also smaller than the ring
                 * buffer cursor.  Discard all oldest samples following the ring
                 * buffer cursor and additional samples at the beginning of the
                 * buffer. */
                else
                {
                    memcpy(new_stats,
                           m->stats + m->ring_cursor - new_pixmap_width,
                           new_pixmap_width * sizeof(stats_set));
                }
                g_free(m->stats);
            }
            m->stats = new_stats;
        }

        m->pixmap_width = new_pixmap_width;
        m->pixmap_height = new_pixmap_height;
        if (m->pixmap)
            cairo_surface_destroy(m->pixmap);
        m->pixmap = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
                                   m->pixmap_width,
                                   m->pixmap_height);
        check_cairo_surface_status(&m->pixmap);
        redraw_pixmap(m);
    }

    return TRUE;
}
Ejemplo n.º 15
0
void gtk_codegraph_save(GtkCodeGraph *box){
    g_return_if_fail (GTK_IS_CODEGRAPH (box));
//Создается диалог выбора места сохранения тренда
    GtkWidget *_dialog = gtk_file_chooser_dialog_new("Сохранить",  NULL, GTK_FILE_CHOOSER_ACTION_SAVE, 
							GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 
                                    			GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL);							

	GtkWidget *widget = GTK_WIDGET(box);
	gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (_dialog), "Untitled");
//Добавляем фильты по типу файлов
	GtkFileFilter *ffilter = gtk_file_filter_new();
	ffilter = gtk_file_filter_new();
	gtk_file_filter_set_name( ffilter, "Рисунок PNG");
	gtk_file_filter_add_pattern( ffilter, "*.png");
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (_dialog), ffilter);

	ffilter = gtk_file_filter_new();
	gtk_file_filter_set_name( ffilter, "Файл данных MathLab");
	gtk_file_filter_add_pattern( ffilter, "*.dat");
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (_dialog), ffilter);
//Отлавливаем конец выбора и работаем
	gint result = gtk_dialog_run (GTK_DIALOG (_dialog) );
	gchar buff[100];
	gchar *fil = NULL; 
	gchar *dir = NULL;
	gchar *filename = NULL;
	if (result == GTK_RESPONSE_NONE){
	    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (_dialog));
	    fil =(char*) gtk_file_filter_get_name( gtk_file_chooser_get_filter(GTK_FILE_CHOOSER (_dialog)) );
	    dir = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (_dialog)); 
	    if (!strcmp(fil, "Рисунок PNG" ) ) 
	        snprintf(buff,sizeof(buff), "%s.png", filename );
	    else if (!strcmp(fil, "Файл данных MathLab" ) ) 
	        snprintf(buff,sizeof(buff), "%s.dat", filename );
	    else	
		snprintf(buff,sizeof(buff), "%s.png", filename );
	}
/*Если юзер передумал сохраняться*/
	else{
	    gtk_widget_destroy (_dialog);
	    return;
	}
/*Ошибка при открытии файла	*/
	FILE *fp;
	if ((fp=fopen(buff, "w")) == NULL ){
	    gchar buff[300];
	    gchar *homedir = (gchar*)getenv("HOME");
	    snprintf(buff, sizeof(buff), "Отказано в доступе.\nСохранить файл в %s  не удалось. \nВыберите, другой каталог, \nнапример: %s",filename, homedir );
	    GtkWidget* dialog = gtk_message_dialog_new (GTK_WINDOW (NULL),
				      (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
				        buff );
	    gtk_dialog_run (GTK_DIALOG (dialog));
	    gtk_widget_destroy (dialog);
	}
	else{
/*Сохраняем картинку*/
	    cairo_surface_t *surface;
	    if (!strcmp(fil, "Рисунок PNG" ) ){
		fclose(fp);
		cairo_surface_t * surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, widget->allocation.width , widget->allocation.height );
		cairo_t *cr_save = cairo_create (surface);
		gdk_cairo_set_source_pixmap(cr_save, box->priv->backing_pixmap, 0.0, 0.0);
		cairo_paint(cr_save);
		cairo_destroy (cr_save);
		cairo_surface_write_to_png (surface, buff);
		cairo_surface_destroy (surface);
	    }
/*Сохраняем данные*/	    
	    if ( !strcmp(fil, "Файл данных MathLab" )  ){
		int i; int im=0;
		gchar buff[40];
		for (i=0; i<box->priv->numPointsText; i+=2 ){
		    ++im;
		    g_snprintf(buff, sizeof(buff), "%d импульс: %1.3f сек;\n",im ,box->priv->dta[i]  );
		    fwrite(buff, strlen(buff), 1, fp);
		    g_snprintf(buff, sizeof(buff), "%d интервал: %1.3f сек;\n",im ,box->priv->dta[i+1]  );
		    fwrite(buff, strlen(buff), 1, fp);
		}
		fclose(fp);
	    }
	}
	gtk_widget_destroy (_dialog);

}
Ejemplo n.º 16
0
static cairo_test_status_t
preamble (cairo_test_context_t *ctx)
{
    Display *dpy;
    XRenderPictFormat *orig_format, *format;
    cairo_surface_t *surface;
    Pixmap pixmap;
    int screen;
    cairo_test_status_t result;

    result = CAIRO_TEST_UNTESTED;

    if (! cairo_test_is_target_enabled (ctx, "xlib"))
	goto CLEANUP_TEST;

    dpy = XOpenDisplay (NULL);
    if (! dpy) {
	cairo_test_log (ctx, "Error: Cannot open display: %s, skipping.\n",
			XDisplayName (NULL));
	goto CLEANUP_TEST;
    }

    result = CAIRO_TEST_FAILURE;

    screen = DefaultScreen (dpy);

    cairo_test_log (ctx, "Testing with image surface.\n");

    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);

    format = cairo_xlib_surface_get_xrender_format (surface);
    if (format != NULL) {
	cairo_test_log (ctx, "Error: expected NULL for image surface\n");
	goto CLEANUP_SURFACE;
    }

    cairo_surface_destroy (surface);

    cairo_test_log (ctx, "Testing with non-xrender xlib surface.\n");

    pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
			    1, 1, DefaultDepth (dpy, screen));
    surface = cairo_xlib_surface_create (dpy, pixmap,
					 DefaultVisual (dpy, screen),
					 1, 1);
    orig_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
    format = cairo_xlib_surface_get_xrender_format (surface);
    if (format != orig_format) {
	cairo_test_log (ctx, "Error: did not receive the same format as XRenderFindVisualFormat\n");
	goto CLEANUP_PIXMAP;
    }
    cairo_surface_destroy (surface);
    XFreePixmap (dpy, pixmap);

    cairo_test_log (ctx, "Testing with xlib xrender surface.\n");

    orig_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
    pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
			    1, 1, 32);
    surface = cairo_xlib_surface_create_with_xrender_format (dpy,
							     pixmap,
							     DefaultScreenOfDisplay (dpy),
							     orig_format,
							     1, 1);
    format = cairo_xlib_surface_get_xrender_format (surface);
    if (format != orig_format) {
	cairo_test_log (ctx, "Error: did not receive the same format originally set\n");
	goto CLEANUP_PIXMAP;
    }

    cairo_test_log (ctx, "Testing without the X Render extension.\n");

    cairo_boilerplate_xlib_surface_disable_render (surface);

    format = cairo_xlib_surface_get_xrender_format (surface);
    if (format != NULL) {
	cairo_test_log (ctx, "Error: did not receive a NULL format as expected\n");
	goto CLEANUP_PIXMAP;
    }

    result = CAIRO_TEST_SUCCESS;

  CLEANUP_PIXMAP:
    XFreePixmap (dpy, pixmap);
  CLEANUP_SURFACE:
    cairo_surface_destroy (surface);

    XCloseDisplay (dpy);

  CLEANUP_TEST:
    return result;
}
Ejemplo n.º 17
0
static cairo_int_status_t
_cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
				  cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;

    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);

    cairo_image_surface_t *surface = NULL;

    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);

    int advance;
    CGRect bbox;
    double width, height;
    double xscale, yscale;
    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);

    CGColorSpaceRef gray;
    CGContextRef cgContext = NULL;
    CGAffineTransform textMatrix;
    CGRect glyphRect, glyphRectInt;
    CGPoint glyphOrigin;

    //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);

    /* Create blank 2x2 image if we don't have this character.
     * Maybe we should draw a better missing-glyph slug or something,
     * but this is ok for now.
     */
    if (glyph == INVALID_GLYPH) {
	surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
	status = cairo_surface_status ((cairo_surface_t *) surface);
	if (status)
	    return status;

	_cairo_scaled_glyph_set_surface (scaled_glyph,
					 &font->base,
					 surface);
	return CAIRO_STATUS_SUCCESS;
    }

    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
    {
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
						  &xscale, &yscale, 1);
    if (status)
	return status;

    textMatrix = CGAffineTransformMake (font->base.scale.xx,
					-font->base.scale.yx,
					-font->base.scale.xy,
					font->base.scale.yy,
					0.0f, 0.0f);
    glyphRect = CGRectMake (bbox.origin.x / emscale,
			    bbox.origin.y / emscale,
			    bbox.size.width / emscale,
			    bbox.size.height / emscale);

    glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);

    /* Round the rectangle outwards, so that we don't have to deal
     * with non-integer-pixel origins or dimensions.
     */
    glyphRectInt = CGRectIntegral (glyphRect);

#if 0
    fprintf (stderr, "glyphRect[o]: %f %f %f %f\n",
	     glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
    fprintf (stderr, "glyphRectInt: %f %f %f %f\n",
	     glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height);
#endif

    glyphOrigin = glyphRectInt.origin;

    //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));

    width = glyphRectInt.size.width;
    height = glyphRectInt.size.height;

    //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);

    surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
    if (surface->base.status)
	return surface->base.status;

    gray = CGColorSpaceCreateDeviceGray ();
    cgContext = CGBitmapContextCreate (surface->data,
				       surface->width,
				       surface->height,
				       8,
				       surface->stride,
				       gray,
				       kCGImageAlphaNone);
    CGColorSpaceRelease (gray);

    CGContextSetFont (cgContext, font_face->cgFont);
    CGContextSetFontSize (cgContext, 1.0);
    CGContextSetTextMatrix (cgContext, textMatrix);

    CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height));

    if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE)
	CGContextSetShouldAntialias (cgContext, false);

    CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0);
    CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);

    CGContextRelease (cgContext);

    cairo_surface_set_device_offset (&surface->base,
				     - glyphOrigin.x,
				     height + glyphOrigin.y);

    _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);

    return status;
}
Ejemplo n.º 18
0
int main(int argc, const char* argv[])
{
	size_t tex_side =(argc>1)? std::atoi(argv[1]) : 512;
	const char* font_desc_str = (argc>2)? argv[2] : "Sans 18";
	unsigned plane = (argc>3)? std::atoi(argv[3]) : 0;

	cairo_surface_t *surface = cairo_image_surface_create(
		CAIRO_FORMAT_A8,
		tex_side,
		tex_side
	);
	cairo_t *cr = cairo_create(surface);

	PangoFontDescription *font_desc = pango_font_description_from_string(
		font_desc_str
	);
	PangoFontMap* font_map = pango_cairo_font_map_get_default();
	PangoContext* context = pango_font_map_create_context(font_map);
	PangoFont* font = pango_font_map_load_font(
		font_map,
		context,
		font_desc
	);
	PangoFontMetrics* font_metrics = pango_font_get_metrics(font, nullptr);

	// The Bitmap Glyph Metrics file
	std::ofstream bgm((argc>5) ? argv[5] : "out.bgm");
	unsigned step = tex_side / 16;
	for(unsigned y=0; y!=16; ++y)
	{
		for(unsigned x=0; x!=16; ++x)
		{
			render_glyph(
				cr,
				font_desc,
				font,
				256*plane + y*16 + x,
				x, y,
				step,
				tex_side,
				pango_font_metrics_get_ascent(font_metrics),
				pango_font_metrics_get_descent(font_metrics),
				bgm
			);
		}
	}
	bgm.close();

	pango_font_metrics_unref(font_metrics);
	pango_font_description_free(font_desc);
	g_object_unref(context);


	cairo_destroy(cr);
	cairo_status_t status = cairo_surface_write_to_png(
		surface,
		(argc>4) ? argv[4] : "out.png"
	);
	cairo_surface_destroy(surface);

	return 0;
}
Ejemplo n.º 19
0
static gboolean _lib_histogram_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_histogram_t *d = (dt_lib_histogram_t *)self->data;

  dt_develop_t *dev = darktable.develop;
  float *hist = dev->histogram;
  float hist_max = dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR?dev->histogram_max:logf(1.0 + dev->histogram_max);
  const int inset = DT_HIST_INSET;
  int width = widget->allocation.width, height = widget->allocation.height;
  cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);
  GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkWidget", GTK_TYPE_WIDGET);
  if(!style) style = gtk_rc_get_style(widget);
  cairo_set_source_rgb(cr, style->bg[0].red/65535.0, style->bg[0].green/65535.0, style->bg[0].blue/65535.0);
  cairo_paint(cr);

  cairo_translate(cr, 4*inset, inset);
  width -= 2*4*inset;
  height -= 2*inset;

  if(d->mode_x == 0)
  {
    d->color_w = 0.06*width;
    d->button_spacing = 0.01*width;
    d->button_h = 0.06*width;
    d->button_y = d->button_spacing;
    d->mode_w = d->color_w;
    d->mode_x = width - 3*(d->color_w+d->button_spacing) - (d->mode_w+d->button_spacing);
    d->red_x = width - 3*(d->color_w+d->button_spacing);
    d->green_x = width - 2*(d->color_w+d->button_spacing);
    d->blue_x = width - (d->color_w+d->button_spacing);
  }

  // TODO: probably this should move to the configure-event callback! That would be future proof if we ever (again) allow to resize the side panels.
  const gint stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);

  // this code assumes that the first expose comes before the first (preview) pipe is processed and that the size of the widget doesn't change!
  if(dev->histogram_waveform_width == 0)
  {
    dev->histogram_waveform = (uint32_t*)calloc(height * stride / 4, sizeof(uint32_t));
    dev->histogram_waveform_stride = stride;
    dev->histogram_waveform_height = height;
    dev->histogram_waveform_width = width;
//     return TRUE; // there are enough expose events following ...
  }

#if 1
  // draw shadow around
  float alpha = 1.0f;
  cairo_set_line_width(cr, 0.2);
  for(int k=0; k<inset; k++)
  {
    cairo_rectangle(cr, -k, -k, width + 2*k, height + 2*k);
    cairo_set_source_rgba(cr, 0, 0, 0, alpha);
    alpha *= 0.5f;
    cairo_fill(cr);
  }
  cairo_set_line_width(cr, 1.0);
#else
  cairo_set_line_width(cr, 1.0);
  cairo_set_source_rgb (cr, .1, .1, .1);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_stroke(cr);
#endif

  cairo_rectangle(cr, 0, 0, width, height);
  cairo_clip(cr);

  cairo_set_source_rgb (cr, .3, .3, .3);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_fill(cr);
  if(d->highlight == 1)
  {
    cairo_set_source_rgb (cr, .5, .5, .5);
    cairo_rectangle(cr, 0, 0, .2*width, height);
    cairo_fill(cr);
  }
  else if(d->highlight == 2)
  {
    cairo_set_source_rgb (cr, .5, .5, .5);
    cairo_rectangle(cr, 0.2*width, 0, width, height);
    cairo_fill(cr);
  }

  // draw grid
  cairo_set_line_width(cr, .4);
  cairo_set_source_rgb (cr, .1, .1, .1);
  if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM)
    dt_draw_waveform_lines(cr, 0, 0, width, height);
  else
    dt_draw_grid(cr, 4, 0, 0, width, height);

  if(hist_max > 0)
  {
    cairo_save(cr);
    if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM)
    {
      // make the color channel selector work:
      uint8_t *buf = (uint8_t*)malloc(sizeof(uint8_t) * height * stride);
      uint8_t mask[3] = {d->blue, d->green, d->red};
      memcpy(buf, dev->histogram_waveform, sizeof(uint8_t) * height * stride);
      for(int y = 0; y < height; y++)
        for(int x = 0; x < width; x++)
          for(int k = 0; k < 3; k++)
          {
            buf[y * stride + x * 4 + k] *= mask[k];
          }

      cairo_surface_t *source = cairo_image_surface_create_for_data(buf,
                                                CAIRO_FORMAT_ARGB32,
                                                width, height, stride);

      cairo_set_source_surface(cr, source, 0.0, 0.0);
      cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
      cairo_paint(cr);
      cairo_surface_destroy(source);
      free(buf);
    }
    else
    {
      // cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
      cairo_translate(cr, 0, height);
      cairo_scale(cr, width/63.0, -(height-10)/hist_max);
      cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
      // cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
      cairo_set_line_width(cr, 1.);
      if(d->red)
      {
        cairo_set_source_rgba(cr, 1., 0., 0., 0.2);
        dt_draw_histogram_8(cr, hist, 0, dev->histogram_type);
      }
      if(d->green)
      {
        cairo_set_source_rgba(cr, 0., 1., 0., 0.2);
        dt_draw_histogram_8(cr, hist, 1, dev->histogram_type);
      }
      if(d->blue)
      {
        cairo_set_source_rgba(cr, 0., 0., 1., 0.2);
        dt_draw_histogram_8(cr, hist, 2, dev->histogram_type);
      }
      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
      // cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
    }
    cairo_restore(cr);
  }

  cairo_set_source_rgb(cr, .25, .25, .25);
  cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size (cr, .1*height);

  char exifline[50];
  cairo_move_to (cr, .02*width, .98*height);
  dt_image_print_exif(&dev->image_storage, exifline, 50);
  cairo_save(cr);
  //   cairo_show_text(cr, exifline);
  cairo_set_line_width(cr, 2.0);
  cairo_set_source_rgba(cr, 1, 1, 1, 0.3);
  cairo_text_path(cr, exifline);
  cairo_stroke_preserve(cr);
  cairo_set_source_rgb(cr, .25, .25, .25);
  cairo_fill(cr);
  cairo_restore(cr);

  // buttons to control the display of the histogram: linear/log, r, g, b
  if(d->highlight != 0)
  {
    _draw_mode_toggle(cr, d->mode_x, d->button_y, d->mode_w, d->button_h, dev->histogram_type);
    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4);
    _draw_color_toggle(cr, d->red_x, d->button_y, d->color_w, d->button_h, d->red);
    cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.4);
    _draw_color_toggle(cr, d->green_x, d->button_y, d->color_w, d->button_h, d->green);
    cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 0.4);
    _draw_color_toggle(cr, d->blue_x, d->button_y, d->color_w, d->button_h, d->blue);
  }

  cairo_destroy(cr);
  cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget));
  cairo_set_source_surface (cr_pixmap, cst, 0, 0);
  cairo_paint(cr_pixmap);
  cairo_destroy(cr_pixmap);
  cairo_surface_destroy(cst);
  return TRUE;
}
Ejemplo n.º 20
0
static gboolean dt_iop_levels_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_levels_gui_data_t *c = (dt_iop_levels_gui_data_t *)self->gui_data;
  dt_iop_levels_params_t *p = (dt_iop_levels_params_t *)self->params;
  const int inset = DT_GUI_CURVE_EDITOR_INSET;
  int width = widget->allocation.width, height = widget->allocation.height;
  cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  float mean_picked_color = *self->picked_color / 100.0;

  /* we need to save the last picked color to prevent flickering when
   * changing from one picker to another, as the picked_color value does not
   * update as rapidly */
  if(self->request_color_pick && 
     self->color_picker_point[0] >= 0.0f && self->color_picker_point[1] >= 0.0f &&
     mean_picked_color != c->last_picked_color)
  {
    float previous_color[3];
    previous_color[0] = p->levels[0];
    previous_color[1] = p->levels[1];
    previous_color[2] = p->levels[2];

    c->last_picked_color = mean_picked_color;

    if (BLACK == c->current_pick)
    {
      if (mean_picked_color > p->levels[1])
      {
        p->levels[0] = p->levels[1]-FLT_EPSILON;
      }
      else
      {
        p->levels[0] = mean_picked_color;
      }
      c->pick_xy_positions[0][0] = self->color_picker_point[0];
      c->pick_xy_positions[0][1] = self->color_picker_point[1];
    }
    else if (GREY == c->current_pick)
    {
      if (mean_picked_color < p->levels[0] || mean_picked_color > p->levels[2])
      {
        p->levels[1] = p->levels[1];
      }
      else
      {
        p->levels[1] = mean_picked_color;
      }
      c->pick_xy_positions[1][0] = self->color_picker_point[0];
      c->pick_xy_positions[1][1] = self->color_picker_point[1];
    }
    else if (WHITE == c->current_pick)
    {
      if (mean_picked_color < p->levels[1])
      {
        p->levels[2] = p->levels[1]+FLT_EPSILON;
      }
      else
      {
        p->levels[2] = mean_picked_color;
      }
      c->pick_xy_positions[2][0] = self->color_picker_point[0];
      c->pick_xy_positions[2][1] = self->color_picker_point[1];
    }

    if (   previous_color[0] != p->levels[0]
        || previous_color[1] != p->levels[1]
        || previous_color[2] != p->levels[2] )
    {
      dt_dev_add_history_item(darktable.develop, self, TRUE);
    }
  }

  // clear bg
  cairo_set_source_rgb (cr, .2, .2, .2);
  cairo_paint(cr);

  cairo_translate(cr, inset, inset);
  width -= 2*inset;
  height -= 2*inset;

  cairo_set_line_width(cr, 1.0);
  cairo_set_source_rgb (cr, .1, .1, .1);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_stroke(cr);

  cairo_set_source_rgb (cr, .3, .3, .3);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_fill(cr);

  // draw grid
  cairo_set_line_width(cr, .4);
  cairo_set_source_rgb (cr, .1, .1, .1);
  dt_draw_vertical_lines(cr, 4, 0, 0, width, height);

  // Drawing the vertical line indicators
  cairo_set_line_width(cr, 2.);

  for(int k = 0; k < 3; k++)
  {
    if(k == c->handle_move && c->mouse_x > 0)
      cairo_set_source_rgb(cr, 1, 1, 1);
    else
      cairo_set_source_rgb(cr, .7, .7, .7);

    cairo_move_to(cr, width*p->levels[k], height);
    cairo_rel_line_to(cr, 0, -height);
    cairo_stroke(cr);
  }

  // draw x positions
  cairo_set_line_width(cr, 1.);
  const float arrw = 7.0f;
  for(int k=0; k<3; k++)
  {
    switch(k)
    {
      case 0:
        cairo_set_source_rgb(cr, 0, 0, 0);
        break;

      case 1:
        cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
        break;

      default:
        cairo_set_source_rgb(cr, 1, 1, 1);
        break;
    }

    cairo_move_to(cr, width*p->levels[k], height+inset-1);
    cairo_rel_line_to(cr, -arrw*.5f, 0);
    cairo_rel_line_to(cr, arrw*.5f, -arrw);
    cairo_rel_line_to(cr, arrw*.5f, arrw);
    cairo_close_path(cr);
    if(c->handle_move == k && c->mouse_x > 0)
      cairo_fill(cr);
    else
      cairo_stroke(cr);
  }

  cairo_translate(cr, 0, height);

  // draw lum histogram in background
  // only if the module is enabled
  if (self->enabled)
  {
    dt_develop_t *dev = darktable.develop;
    float *hist, hist_max;
    hist = self->histogram;
    hist_max = dev->histogram_linear?self->histogram_max[0]:logf(1.0 + self->histogram_max[0]);
    if(hist && hist_max > 0)
    {
      cairo_save(cr);
      cairo_scale(cr, width/63.0, -(height-5)/(float)hist_max);
      cairo_set_source_rgba(cr, .2, .2, .2, 0.5);
      dt_draw_histogram_8(cr, hist, 0);
      cairo_restore(cr);
    }
  }

  // Cleaning up
  cairo_destroy(cr);
  cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget));
  cairo_set_source_surface (cr_pixmap, cst, 0, 0);
  cairo_paint(cr_pixmap);
  cairo_destroy(cr_pixmap);
  cairo_surface_destroy(cst);
  return TRUE;
}
Ejemplo n.º 21
0
cairo_t*
measuring_context_create (void)
{
	cairo_surface_t* surf = cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1);
	return cairo_create (surf);
}
Ejemplo n.º 22
0
static gboolean
spectrogram_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data) {
    w_spectrogram_t *w = user_data;
    GtkAllocation a;
    gtk_widget_get_allocation (widget, &a);
    if (!w->samples || a.height < 1) {
        return FALSE;
    }

    int width, height;
    width = a.width;
    height = a.height;
    int ratio = ftoi (FFT_SIZE/(a.height*2));
    ratio = CLAMP (ratio,0,1023);

    if (deadbeef->get_output ()->state () == OUTPUT_STATE_PLAYING) {
        do_fft (w);
        float log_scale = (log2f(w->samplerate/2)-log2f(25.))/(a.height);
        float freq_res = w->samplerate / FFT_SIZE;

        if (a.height != w->height) {
            w->height = MIN (a.height, MAX_HEIGHT);
            for (int i = 0; i < w->height; i++) {
                w->log_index[i] = ftoi (powf(2.,((float)i) * log_scale + log2f(25.)) / freq_res);
                if (i > 0 && w->log_index[i-1] == w->log_index [i]) {
                    w->low_res_end = i;
                }
            }
        }
    }

    // start drawing
    if (!w->surf || cairo_image_surface_get_width (w->surf) != a.width || cairo_image_surface_get_height (w->surf) != a.height) {
        if (w->surf) {
            cairo_surface_destroy (w->surf);
            w->surf = NULL;
        }
        w->surf = cairo_image_surface_create (CAIRO_FORMAT_RGB24, a.width, a.height);
    }

    cairo_surface_flush (w->surf);

    unsigned char *data = cairo_image_surface_get_data (w->surf);
    if (!data) {
        return FALSE;
    }
    int stride = cairo_image_surface_get_stride (w->surf);

    if (deadbeef->get_output ()->state () == OUTPUT_STATE_PLAYING) {
        for (int i = 0; i < a.height; i++) {
            // scrolling: move line i 1px to the left
            memmove (data + (i*stride), data + sizeof (uint32_t) + (i*stride), stride - sizeof (uint32_t));
        }

        for (int i = 0; i < a.height; i++)
        {
            float f = 1.0;
            int index0, index1;
            int bin0, bin1, bin2;
            if (CONFIG_LOG_SCALE) {
                bin0 = w->log_index[CLAMP (i-1,0,height-1)];
                bin1 = w->log_index[i];
                bin2 = w->log_index[CLAMP (i+1,0,height-1)];
            }
            else {
                bin0 = (i-1) * ratio;
                bin1 = i * ratio;
                bin2 = (i+1) * ratio;
            }

            index0 = bin0 + ftoi ((bin1 - bin0)/2.f);
            if (index0 == bin0) index0 = bin1;
            index1 = bin1 + ftoi ((bin2 - bin1)/2.f);
            if (index1 == bin2) index1 = bin1;

            index0 = CLAMP (index0,0,FFT_SIZE/2-1);
            index1 = CLAMP (index1,0,FFT_SIZE/2-1);

            f = spectrogram_get_value (w, index0, index1);
            float x = 10 * log10f (f);

            // interpolate
            if (i <= w->low_res_end && CONFIG_LOG_SCALE) {
                int j = 0;
                // find index of next value
                while (i+j < height && w->log_index[i+j] == w->log_index[i]) {
                    j++;
                }
                float v0 = x;
                float v1 = w->data[w->log_index[i+j]];
                if (v1 != 0) {
                    v1 = 10 * log10f (v1);
                }

                int k = 0;
                while ((k+i) >= 0 && w->log_index[k+i] == w->log_index[i]) {
                    j++;
                    k--;
                }
                x = linear_interpolate (v0,v1,(1.0/(j-1)) * ((-1 * k) - 1));
            }

            // TODO: get rid of hardcoding 
            x += CONFIG_DB_RANGE - 63;
            x = CLAMP (x, 0, CONFIG_DB_RANGE);
            int color_index = GRADIENT_TABLE_SIZE - ftoi (GRADIENT_TABLE_SIZE/(float)CONFIG_DB_RANGE * x);
            color_index = CLAMP (color_index, 0, GRADIENT_TABLE_SIZE-1);
            _draw_point (data, stride, width-1, height-1-i, w->colors[color_index]);
        }
    }
    cairo_surface_mark_dirty (w->surf);

    cairo_save (cr);
    cairo_set_source_surface (cr, w->surf, 0, 0);
    cairo_rectangle (cr, 0, 0, a.width, a.height);
    cairo_fill (cr);
    cairo_restore (cr);

    return FALSE;
}
Ejemplo n.º 23
0
GIcon *
photos_utils_create_collection_icon (gint base_size, GList *pixbufs)
{
  cairo_surface_t *surface; /* TODO: use g_autoptr */
  cairo_t *cr; /* TODO: use g_autoptr */
  GdkPixbuf *pix;
  GIcon *ret_val;
  GList *l;
  g_autoptr (GtkStyleContext) context = NULL;
  g_autoptr (GtkWidgetPath) path = NULL;
  gint cur_x;
  gint cur_y;
  gint padding;
  gint pix_height;
  gint pix_width;
  gint scale_size;
  gint tile_size;
  guint idx;
  guint n_grid;
  guint n_pixbufs;
  guint n_tiles;

  n_pixbufs = g_list_length (pixbufs);
  if (n_pixbufs < 3)
    {
      n_grid = 1;
      n_tiles = 1;
    }
  else
    {
      n_grid = 2;
      n_tiles = 4;
    }

  padding = MAX (base_size / 10, 4);
  tile_size = (base_size - ((n_grid + 1) * padding)) / n_grid;

  context = gtk_style_context_new ();
  gtk_style_context_add_class (context, "photos-collection-icon");

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (context, path);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size);
  cr = cairo_create (surface);

  gtk_render_background (context, cr, 0, 0, base_size, base_size);

  l = pixbufs;
  idx = 0;
  cur_x = padding;
  cur_y = padding;

  while (l != NULL && idx < n_tiles)
    {
      pix = l->data;
      pix_width = gdk_pixbuf_get_width (pix);
      pix_height = gdk_pixbuf_get_height (pix);

      scale_size = MIN (pix_width, pix_height);

      cairo_save (cr);

      cairo_translate (cr, cur_x, cur_y);

      cairo_rectangle (cr, 0, 0,
                       tile_size, tile_size);
      cairo_clip (cr);

      cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size);
      gdk_cairo_set_source_pixbuf (cr, pix, 0, 0);

      cairo_paint (cr);
      cairo_restore (cr);

      idx++;
      l = l->next;

      if ((idx % n_grid) == 0)
        {
          cur_x = padding;
          cur_y += tile_size + padding;
        }
      else
        {
          cur_x += tile_size + padding;
        }
    }

  ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size));

  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  return ret_val;
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
cairo_surface_t*
pdf_page_image_get_cairo(zathura_page_t* page, void* data,
    zathura_image_t* image, zathura_error_t* error)
{
  mupdf_page_t* mupdf_page = data;

  if (page == NULL || mupdf_page == NULL || image == NULL || image->data == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  fz_image* mupdf_image = (fz_image*) image->data;

  fz_pixmap* pixmap = NULL;
  cairo_surface_t* surface = NULL;

  pixmap = fz_get_pixmap_from_image(mupdf_page->ctx, mupdf_image, NULL, NULL, 0, 0);
  if (pixmap == NULL) {
    goto error_free;
  }

  surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, mupdf_image->w, mupdf_image->h);
  if (surface == NULL) {
    goto error_free;
  }

  unsigned char* surface_data = cairo_image_surface_get_data(surface);
  int rowstride = cairo_image_surface_get_stride(surface);

  unsigned char* s = fz_pixmap_samples(mupdf_page->ctx, pixmap);
  unsigned int n   = fz_pixmap_components(mupdf_page->ctx, pixmap);

  const int height = fz_pixmap_height(mupdf_page->ctx, pixmap);
  const int width  = fz_pixmap_width(mupdf_page->ctx, pixmap);
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      guchar* p = surface_data + y * rowstride + x * 4;

      // RGB
      if (n == 4) {
        p[0] = s[2];
        p[1] = s[1];
        p[2] = s[0];
      // Gray-scale or mask
      } else {
        p[0] = s[0];
        p[1] = s[0];
        p[2] = s[0];
      }
      s += n;
    }
  }

  fz_drop_pixmap(mupdf_page->ctx, pixmap);

  return surface;

error_free:

  if (pixmap != NULL) {
    fz_drop_pixmap(mupdf_page->ctx, pixmap);
  }

  if (surface != NULL) {
    cairo_surface_destroy(surface);
  }

error_ret:

  return NULL;
}
Ejemplo n.º 26
0
QImage QImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
	Q_UNUSED(size);
	QUrl dir(id);
	RsvgDimensionData dimensions;
	int width = 1;
	int height = 1;
	/* Set the locale so that UTF-8 filenames work */
	setlocale(LC_ALL, "");
	double zoom = 1.0;
	rsvg_set_default_dpi_x_y (-1, -1);
	

	RsvgHandle *rsvg = rsvg_handle_new_from_file(dir.toLocalFile().toStdString().c_str(),NULL);
	if(rsvg!=NULL)
	{
		rsvg_handle_get_dimensions(rsvg, &dimensions);
		QRect desktop = QRect(0,0,requestedSize.width(),requestedSize.height());
		if(dimensions.width!=dimensions.height)
		{
			width = (dimensions.width<dimensions.height) ? (double)desktop.height() / (double)dimensions.height * dimensions.width : desktop.width() ;
			height = (dimensions.height<dimensions.width) ? (double)desktop.width() / (double)dimensions.width * dimensions.height : desktop.height() ;
			zoom = (width > height) ? (double)width / (double)dimensions.width : (double)height / (double)dimensions.height;
		}
		else if(desktop.width() > desktop.height())
		{
			width = desktop.height();
			height = desktop.height();
			zoom = (double)height / (double)dimensions.height;
		}
		else
		{
			width = desktop.width();
			height = desktop.width();
			zoom = (double)width / (double)dimensions.width;
		}
		qDebug() << width << "x" << height << ";" << dimensions.width << "x" << dimensions.height << ";" << zoom;
	}
	cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);

	cairo_t *cr = cairo_create(surface);
	cairo_scale(cr, zoom, zoom);
	
	rsvg_handle_render_cairo(rsvg, cr);
	QImage *source = new QImage(
		cairo_image_surface_get_data(surface),
		cairo_image_surface_get_width(surface),
		cairo_image_surface_get_height(surface),
		cairo_image_surface_get_stride(surface),
		QImage::Format_ARGB32_Premultiplied
	);
	QImage image(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface), QImage::Format_ARGB32_Premultiplied);
	image.fill(qRgba(0, 0, 0, 0));
	QPainter painter(&image);
	painter.drawImage(QPoint(0, 0), *source);

	delete source;
	g_object_unref(rsvg);
	cairo_destroy(cr);
	cairo_surface_destroy(surface);
	return image;
}
Ejemplo n.º 27
0
static int ro_composite_tile_read(struct storage_backend * store, const char *xmlconfig, const char *options, int x, int y, int z, char *buf, size_t sz, int * compressed, char * log_msg) {
    struct ro_composite_ctx * ctx = (struct ro_composite_ctx *)(store->storage_ctx);
    cairo_surface_t *imageA;
    cairo_surface_t *imageB;
    cairo_surface_t *imageC;
    cairo_t *cr;
    png_stream_to_byte_array_closure_t closure;

    if(ctx->store_primary->tile_read(ctx->store_primary, ctx->xmlconfig_primary, options, x, y, z, buf, sz, compressed, log_msg) < 0) {
        snprintf(log_msg,1024, "ro_composite_tile_read: Failed to read tile data of primary backend\n");
        return -1;
    }
    closure.data = buf;
    closure.pos = 0;
    closure.max_size = sz;
    imageA = cairo_image_surface_create_from_png_stream(&read_png_stream_from_byte_array, &closure);
    if (!imageA) {
        snprintf(log_msg,1024, "ro_composite_tile_read: Failed to decode png data from primary backend\n");
        return -1;
    }

    if(ctx->store_secondary->tile_read(ctx->store_secondary, ctx->xmlconfig_secondary, options, x, y, z, buf, sz, compressed, log_msg) < 0) {
        snprintf(log_msg,1024, "ro_composite_tile_read: Failed to read tile data of secondary backend\n");
        cairo_surface_destroy(imageA);
        return -1;
    }
    closure.data = buf;
    closure.pos = 0;
    closure.max_size = sz;
    imageB = cairo_image_surface_create_from_png_stream(&read_png_stream_from_byte_array, &closure);
    if (!imageB) {
        snprintf(log_msg,1024, "ro_composite_tile_read: Failed to decode png data from secondary backend\n");
        cairo_surface_destroy(imageA);
        return -1;
    }

    imageC = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ctx->render_size, ctx->render_size);
    if (!imageC) {
        snprintf(log_msg,1024, "ro_composite_tile_read: Failed to create output png\n");
        cairo_surface_destroy(imageA);
        cairo_surface_destroy(imageB);
        return -1;
    }

    //Create the cairo context
    cr = cairo_create(imageC);
    cairo_set_source_surface(cr, imageA, 0, 0);
    cairo_paint(cr);
    cairo_set_source_surface(cr, imageB, 0, 0);
    cairo_paint(cr);
    cairo_surface_flush(imageC);
    cairo_destroy(cr);

    closure.data = buf;
    closure.pos = 0;
    closure.max_size = sz;
    cairo_surface_write_to_png_stream(imageC, &write_png_stream_to_byte_array, &closure);

    cairo_surface_destroy(imageA);
    cairo_surface_destroy(imageB);
    cairo_surface_destroy(imageC);

    return closure.pos;
}
Ejemplo n.º 28
0
static void texbox_update ( textbox *tb )
{
    if ( tb->update ) {
        if ( tb->main_surface ) {
            cairo_destroy ( tb->main_draw );
            cairo_surface_destroy ( tb->main_surface );
            tb->main_draw    = NULL;
            tb->main_surface = NULL;
        }
        tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h );
        tb->main_draw    = cairo_create ( tb->main_surface );
        PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font );
        pango_font_description_free ( pfd );
        cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_SOURCE );

        pango_cairo_update_layout ( tb->main_draw, tb->layout );
        char *text       = tb->text ? tb->text : "";
        int  text_len    = strlen ( text );
        int  font_height = textbox_get_font_height ( tb );

        int  cursor_x     = 0;
        int  cursor_width = MAX ( 2, font_height / 10 );

        if ( tb->changed ) {
            if ( tb->flags & TB_MARKUP ) {
                pango_layout_set_markup ( tb->layout, text, text_len );
            }
            else{
                pango_layout_set_text ( tb->layout, text, text_len );
            }
        }

        if ( tb->flags & TB_EDITABLE ) {
            PangoRectangle pos;
            int            cursor_offset = 0;
            cursor_offset = MIN ( tb->cursor, text_len );
            pango_layout_get_cursor_pos ( tb->layout, cursor_offset, &pos, NULL );
            // Add a small 4px offset between cursor and last glyph.
            cursor_x = pos.x / PANGO_SCALE;
        }

        // Skip the side MARGIN on the X axis.
        int x = SIDE_MARGIN;
        int y = 0;

        if ( tb->flags & TB_RIGHT ) {
            int line_width = 0;
            // Get actual width.
            pango_layout_get_pixel_size ( tb->layout, &line_width, NULL );
            x = ( tb->w - line_width - SIDE_MARGIN );
        }
        else if ( tb->flags & TB_CENTER ) {
            int tw = textbox_get_font_width ( tb );
            x = (  ( tb->w - tw - 2 * SIDE_MARGIN ) ) / 2;
        }
        short fh = textbox_get_font_height ( tb );
        if ( fh > tb->h ) {
            y = 0;
        }
        else {
            y = (   ( tb->h - fh ) ) / 2;
        }

        // Set ARGB
        Color col = tb->color_bg;
        cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha );
        cairo_paint ( tb->main_draw );

        // Set ARGB
        col = tb->color_fg;
        cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha );
        cairo_move_to ( tb->main_draw, x, y );
        pango_cairo_show_layout ( tb->main_draw, tb->layout );

        //cairo_fill(tb->draw);
        // draw the cursor
        if ( tb->flags & TB_EDITABLE ) {
            cairo_rectangle ( tb->main_draw, x + cursor_x, y, cursor_width, font_height );
            cairo_fill ( tb->main_draw );
        }

        tb->update = FALSE;
    }
}
Ejemplo n.º 29
0
static GdkPixbuf *
create_gallery (BaconVideoWidget *bvw, const char *input, const char *output)
{
	GdkPixbuf *screenshot, *pixbuf = NULL;
	cairo_t *cr;
	cairo_surface_t *surface;
	PangoLayout *layout;
	PangoFontDescription *font_desc;
	gint64 stream_length, screenshot_interval, pos;
	guint columns = 3, rows, current_column, current_row, x, y;
	gint screenshot_width = 0, screenshot_height = 0, x_padding = 0, y_padding = 0;
	gfloat scale = 1.0;
	gchar *header_text, *duration_text, *filename;

	/* Calculate how many screenshots we're going to take */
	stream_length = bacon_video_widget_get_stream_length (bvw);

	/* As a default, we have one screenshot per minute of stream,
	 * but adjusted so we don't have any gaps in the resulting gallery. */
	if (gallery == 0) {
		gallery = stream_length / 60000;

		while (gallery % 3 != 0 &&
		       gallery % 4 != 0 &&
		       gallery % 5 != 0) {
			gallery++;
		}
	}

	if (gallery < GALLERY_MIN)
		gallery = GALLERY_MIN;
	if (gallery > GALLERY_MAX)
		gallery = GALLERY_MAX;
	screenshot_interval = stream_length / gallery;

	/* Put a lower bound on the screenshot interval so we can't enter an infinite loop below */
	if (screenshot_interval == 0)
		screenshot_interval = 1;

	PROGRESS_DEBUG ("Producing gallery of %u screenshots, taken at %" G_GINT64_FORMAT " millisecond intervals throughout a %" G_GINT64_FORMAT " millisecond-long stream.",
			gallery, screenshot_interval, stream_length);

	/* Calculate how to arrange the screenshots so we don't get ones orphaned on the last row.
	 * At this point, only deal with arrangements of 3, 4 or 5 columns. */
	y = G_MAXUINT;
	for (x = 3; x <= 5; x++) {
		if (gallery % x == 0 || x - gallery % x < y) {
			y = x - gallery % x;
			columns = x;

			/* Have we found an optimal solution already? */
			if (y == x)
				break;
		}
	}

	rows = ceil ((gfloat) gallery / (gfloat) columns);

	PROGRESS_DEBUG ("Outputting as %u rows and %u columns.", rows, columns);

	/* Take the screenshots and composite them into a pixbuf */
	current_column = current_row = x = y = 0;
	for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) {
		screenshot = capture_frame_at_time (bvw, input, output, pos);

		if (pixbuf == NULL) {
			screenshot_width = gdk_pixbuf_get_width (screenshot);
			screenshot_height = gdk_pixbuf_get_height (screenshot);

			/* Calculate a scaling factor so that screenshot_width -> output_size */
			scale = (float) output_size / (float) screenshot_width;

			x_padding = x = MAX (output_size * 0.05, 1);
			y_padding = y = MAX (scale * screenshot_height * 0.05, 1);

			PROGRESS_DEBUG ("Scaling each screenshot by %f.", scale);

			/* Create our massive pixbuf */
			pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
						 columns * output_size + (columns + 1) * x_padding,
						 (guint) (rows * scale * screenshot_height + (rows + 1) * y_padding));
			gdk_pixbuf_fill (pixbuf, 0x000000ff);

			PROGRESS_DEBUG ("Created output pixbuf (%ux%u).", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
		}

		/* Composite the screenshot into our gallery */
		gdk_pixbuf_composite (screenshot, pixbuf,
				      x, y, output_size, scale * screenshot_height,
				      (gdouble) x, (gdouble) y, scale, scale,
				      GDK_INTERP_BILINEAR, 255);
		g_object_unref (screenshot);

		PROGRESS_DEBUG ("Composited screenshot from %" G_GINT64_FORMAT " milliseconds (address %u) at (%u,%u).",
				pos, GPOINTER_TO_UINT (screenshot), x, y);

		/* We print progress in the range 10% (MIN_PROGRESS) to 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0 */
		PRINT_PROGRESS (MIN_PROGRESS + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));

		current_column = (current_column + 1) % columns;
		x += output_size + x_padding;
		if (current_column == 0) {
			x = x_padding;
			y += scale * screenshot_height + y_padding;
			current_row++;
		}
	}

	PROGRESS_DEBUG ("Converting pixbuf to a Cairo surface.");

	/* Load the pixbuf into a Cairo surface and overlay the text. The height is the height of
	 * the gallery plus the necessary height for 3 lines of header (at ~18px each), plus some
	 * extra padding. */
	surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width (pixbuf),
					      gdk_pixbuf_get_height (pixbuf) + GALLERY_HEADER_HEIGHT + y_padding);
	cr = cairo_create (surface);
	cairo_surface_destroy (surface);

	/* First, copy across the gallery pixbuf */
	gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, GALLERY_HEADER_HEIGHT + y_padding);
	cairo_rectangle (cr, 0.0, GALLERY_HEADER_HEIGHT + y_padding, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
	cairo_fill (cr);
	g_object_unref (pixbuf);

	/* Build the header information */
	duration_text = totem_time_to_string (stream_length);
	filename = NULL;
	if (strstr (input, "://")) {
		char *local;
		local = g_filename_from_uri (input, NULL, NULL);
		filename = g_path_get_basename (local);
		g_free (local);
	}
	if (filename == NULL)
		filename = g_path_get_basename (input);

	/* Translators: The first string is "Filename" (as translated); the second is an actual filename.
			The third string is "Resolution" (as translated); the fourth and fifth are screenshot height and width, respectively.
			The sixth string is "Duration" (as translated); the seventh is the movie duration in words. */
	header_text = g_strdup_printf (_("<b>%s</b>: %s\n<b>%s</b>: %d\303\227%d\n<b>%s</b>: %s"),
				       _("Filename"),
				       filename,
				       _("Resolution"),
				       screenshot_width,
				       screenshot_height,
				       _("Duration"),
				       duration_text);
	g_free (duration_text);
	g_free (filename);

	PROGRESS_DEBUG ("Writing header text with Pango.");

	/* Write out some header information */
	layout = pango_cairo_create_layout (cr);
	font_desc = pango_font_description_from_string ("Sans 18px");
	pango_layout_set_font_description (layout, font_desc);
	pango_font_description_free (font_desc);

	pango_layout_set_markup (layout, header_text, -1);
	g_free (header_text);

	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
	cairo_move_to (cr, (gdouble) x_padding, (gdouble) y_padding);
	pango_cairo_show_layout (cr, layout);

	/* Go through each screenshot and write its timestamp */
	current_column = current_row = 0;
	x = x_padding + output_size;
	y = y_padding * 2 + GALLERY_HEADER_HEIGHT + scale * screenshot_height;

	font_desc = pango_font_description_from_string ("Sans 10px");
	pango_layout_set_font_description (layout, font_desc);
	pango_font_description_free (font_desc);

	PROGRESS_DEBUG ("Writing screenshot timestamps with Pango.");

	for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) {
		gchar *timestamp_text;
		gint layout_width, layout_height;

		timestamp_text = totem_time_to_string (pos);

		pango_layout_set_text (layout, timestamp_text, -1);
		pango_layout_get_pixel_size (layout, &layout_width, &layout_height);

		/* Display the timestamp in the bottom-right corner of the current screenshot */
		cairo_move_to (cr, x - layout_width - 0.02 * output_size, y - layout_height - 0.02 * scale * screenshot_height);

		/* We have to stroke the text so it's visible against screenshots of the same
		 * foreground color. */
		pango_cairo_layout_path (cr, layout);
		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
		cairo_stroke_preserve (cr);
		cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
		cairo_fill (cr);

		PROGRESS_DEBUG ("Writing timestamp \"%s\" at (%f,%f).", timestamp_text,
				x - layout_width - 0.02 * output_size,
				y - layout_height - 0.02 * scale * screenshot_height);

		/* We print progress in the range 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0) to 90% (MAX_PROGRESS) */
		PRINT_PROGRESS (MIN_PROGRESS + (MAX_PROGRESS - MIN_PROGRESS) / 2.0 + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));

		g_free (timestamp_text);

		current_column = (current_column + 1) % columns;
		x += output_size + x_padding;
		if (current_column == 0) {
			x = x_padding + output_size;
			y += scale * screenshot_height + y_padding;
			current_row++;
		}
	}

	g_object_unref (layout);

	PROGRESS_DEBUG ("Converting Cairo surface back to pixbuf.");

	/* Create a new pixbuf from the Cairo context */
	pixbuf = cairo_surface_to_pixbuf (cairo_get_target (cr));
	cairo_destroy (cr);

	return pixbuf;
}
Ejemplo n.º 30
0
int main(int argc, char* argv[])
{
  std::string   map;
  std::string   style;
  std::string   output;
  size_t        width,height;
  double        lon,lat,zoom;

  if (argc!=9) {
    std::cerr << "DrawMap <map directory> <style-file> <width> <height> <lon> <lat> <zoom> <output>" << std::endl;
    return 1;
  }

  map=argv[1];
  style=argv[2];

  if (!osmscout::StringToNumber(argv[3],width)) {
    std::cerr << "width is not numeric!" << std::endl;
    return 1;
  }

  if (!osmscout::StringToNumber(argv[4],height)) {
    std::cerr << "height is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[5],"%lf",&lon)!=1) {
    std::cerr << "lon is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[6],"%lf",&lat)!=1) {
    std::cerr << "lat is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[7],"%lf",&zoom)!=1) {
    std::cerr << "zoom is not numeric!" << std::endl;
    return 1;
  }

  output=argv[8];

  osmscout::DatabaseParameter databaseParameter;
  osmscout::DatabaseRef       database(new osmscout::Database(databaseParameter));
  osmscout::MapServiceRef     mapService(new osmscout::MapService(database));

  if (!database->Open(map.c_str())) {
    std::cerr << "Cannot open database" << std::endl;

    return 1;
  }

  osmscout::StyleConfigRef styleConfig(new osmscout::StyleConfig(database->GetTypeConfig()));

  if (!styleConfig->Load(style)) {
    std::cerr << "Cannot open style" << std::endl;
  }

  cairo_surface_t *surface;
  cairo_t         *cairo;

  surface=cairo_image_surface_create(CAIRO_FORMAT_RGB24,width,height);

  if (surface!=NULL) {
    cairo=cairo_create(surface);

    if (cairo!=NULL) {
      osmscout::MercatorProjection  projection;
      osmscout::MapParameter        drawParameter;
      osmscout::AreaSearchParameter searchParameter;
      osmscout::MapData             data;
      osmscout::MapPainterCairo     painter(styleConfig);

      drawParameter.SetFontSize(3.0);

      projection.Set(osmscout::GeoCoord(lat,lon),
                     osmscout::Magnification(zoom),
                     DPI,
                     width,
                     height);

      std::list<osmscout::TileRef> tiles;

      mapService->LookupTiles(projection,tiles);
      mapService->LoadMissingTileData(searchParameter,*styleConfig,tiles);
      mapService->ConvertTilesToMapData(tiles,data);

      if (painter.DrawMap(projection,
                          drawParameter,
                          data,
                          cairo)) {
        if (cairo_surface_write_to_png(surface,output.c_str())!=CAIRO_STATUS_SUCCESS) {
          std::cerr << "Cannot write PNG" << std::endl;
        }
      }

      cairo_destroy(cairo);
    }
    else {
      std::cerr << "Cannot create cairo cairo" << std::endl;
    }

    cairo_surface_destroy(surface);
  }
  else {
    std::cerr << "Cannot create cairo surface" << std::endl;
  }

  return 0;
}