/** * 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; }
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); }
/* * 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; }
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); }
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; }
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; }
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 ); }
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); }
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; } }
/* * 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); }
/****************************************************************************** * 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; }
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); }
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; }
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; }
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; }
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; }
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; }
cairo_t* measuring_context_create (void) { cairo_surface_t* surf = cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1); return cairo_create (surf); }
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; }
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; }
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; }
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; }
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; }
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; }
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; } }
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; }
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; }