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; }
bool PageView::paintPage(cairo_t* cr, GdkRectangle* rect) { XOJ_CHECK_TYPE(PageView); static const char* txtLoading = _("Loading..."); double zoom = xournal->getZoom(); g_mutex_lock(this->drawingMutex); int dispWidth = getDisplayWidth(); int dispHeight = getDisplayHeight(); if (this->crBuffer == NULL) { this->crBuffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dispWidth, dispHeight); cairo_t* cr2 = cairo_create(this->crBuffer); cairo_set_source_rgb(cr2, 1, 1, 1); cairo_rectangle(cr2, 0, 0, dispWidth, dispHeight); cairo_fill(cr2); cairo_scale(cr2, zoom, zoom); cairo_text_extents_t ex; cairo_set_source_rgb(cr2, 0.5, 0.5, 0.5); cairo_select_font_face(cr2, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr2, 32.0); cairo_text_extents(cr2, txtLoading, &ex); cairo_move_to(cr2, (page->getWidth() - ex.width) / 2 - ex.x_bearing, (page->getHeight() - ex.height) / 2 - ex.y_bearing); cairo_show_text(cr2, txtLoading); cairo_destroy(cr2); rerenderPage(); } cairo_save(cr); double width = cairo_image_surface_get_width(this->crBuffer); if (width != dispWidth) { double scale = ((double) dispWidth) / ((double) width); // Scale current image to fit the zoom level cairo_scale(cr, scale, scale); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_set_source_surface(cr, this->crBuffer, 0, 0); rerenderPage(); rect = NULL; } else { cairo_set_source_surface(cr, this->crBuffer, 0, 0); } if (rect) { cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); cairo_fill(cr); #ifdef SHOW_PAINT_BOUNDS cairo_set_source_rgb(cr, 1.0, 0.5, 1.0); cairo_set_line_width(cr, 1. / zoom); cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); cairo_stroke(cr); #endif } else { cairo_paint(cr); } cairo_restore(cr); // don't paint this with scale, because it needs a 1:1 zoom if (this->verticalSpace) { this->verticalSpace->paint(cr, rect, zoom); } cairo_scale(cr, zoom, zoom); if (this->textEditor) { this->textEditor->paint(cr, rect, zoom); } if (this->selection) { this->selection->paint(cr, rect, zoom); } if (this->search) { this->search->paint(cr, rect, zoom, getSelectionColor()); } this->inputHandler->draw(cr, zoom); g_mutex_unlock(this->drawingMutex); return true; }
static cairo_status_t png_diff (const char *filename_a, const char *filename_b, const char *filename_diff, int ax, int ay, int bx, int by, buffer_diff_result_t *result) { cairo_surface_t *surface_a; cairo_surface_t *surface_b; cairo_surface_t *surface_diff; cairo_status_t status; surface_a = cairo_image_surface_create_from_png (filename_a); status = cairo_surface_status (surface_a); if (status) { fprintf (stderr, "Error: Failed to create surface from %s: %s\n", filename_a, cairo_status_to_string (status)); return status; } surface_b = cairo_image_surface_create_from_png (filename_b); status = cairo_surface_status (surface_b); if (status) { fprintf (stderr, "Error: Failed to create surface from %s: %s\n", filename_b, cairo_status_to_string (status)); cairo_surface_destroy (surface_a); return status; } if (ax || ay) { extract_sub_surface (&surface_a, ax, ay); ax = ay = 0; } if (bx || by) { extract_sub_surface (&surface_b, bx, by); bx = by = 0; } status = cairo_surface_status (surface_a); if (status) { fprintf (stderr, "Error: Failed to extract surface from %s: %s\n", filename_a, cairo_status_to_string (status)); cairo_surface_destroy (surface_a); cairo_surface_destroy (surface_b); return status; } status = cairo_surface_status (surface_b); if (status) { fprintf (stderr, "Error: Failed to extract surface from %s: %s\n", filename_b, cairo_status_to_string (status)); cairo_surface_destroy (surface_a); cairo_surface_destroy (surface_b); return status; } surface_diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, cairo_image_surface_get_width (surface_a), cairo_image_surface_get_height (surface_a)); status = cairo_surface_status (surface_diff); if (status) { fprintf (stderr, "Error: Failed to allocate surface to hold differences\n"); cairo_surface_destroy (surface_a); cairo_surface_destroy (surface_b); return CAIRO_STATUS_NO_MEMORY; } status = image_diff (NULL, surface_a, surface_b, surface_diff, result); cairo_surface_destroy (surface_a); cairo_surface_destroy (surface_b); cairo_surface_destroy (surface_diff); _xunlink (filename_diff); if (status == CAIRO_STATUS_SUCCESS && result->pixels_changed) { status = write_png (surface_diff, filename_diff); } return status; }
static gpointer equalize_exec (GthAsyncTask *task, gpointer user_data) { EqualizeData *equalize_data = user_data; cairo_surface_t *source; cairo_format_t format; int width; int height; int source_stride; cairo_surface_t *destination; int destination_stride; unsigned char *p_source_line; unsigned char *p_destination_line; unsigned char *p_source; unsigned char *p_destination; gboolean cancelled; double progress; int x, y; unsigned char red, green, blue, alpha; /* initialize the extra data */ source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task)); equalize_histogram_setup (equalize_data, source); /* convert the image */ format = cairo_image_surface_get_format (source); width = cairo_image_surface_get_width (source); height = cairo_image_surface_get_height (source); source_stride = cairo_image_surface_get_stride (source); destination = cairo_image_surface_create (format, width, height); destination_stride = cairo_image_surface_get_stride (destination); p_source_line = _cairo_image_surface_flush_and_get_data (source); p_destination_line = _cairo_image_surface_flush_and_get_data (destination); for (y = 0; y < height; y++) { gth_async_task_get_data (task, NULL, &cancelled, NULL); if (cancelled) return NULL; progress = (double) y / height; gth_async_task_set_data (task, NULL, NULL, &progress); p_source = p_source_line; p_destination = p_destination_line; for (x = 0; x < width; x++) { CAIRO_GET_RGBA (p_source, red, green, blue, alpha); red = equalize_func (equalize_data, GTH_HISTOGRAM_CHANNEL_RED, red); green = equalize_func (equalize_data, GTH_HISTOGRAM_CHANNEL_GREEN, green); blue = equalize_func (equalize_data, GTH_HISTOGRAM_CHANNEL_BLUE, blue); CAIRO_SET_RGBA (p_destination, red, green, blue, alpha); p_source += 4; p_destination += 4; } p_source_line += source_stride; p_destination_line += destination_stride; } cairo_surface_mark_dirty (destination); gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination); cairo_surface_destroy (destination); cairo_surface_destroy (source); return NULL; }
bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile) { // This implementation is taken from GraphicsContext3DCairo. 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) return false; m_imageWidth = cairo_image_surface_get_width(m_imageSurface.get()); m_imageHeight = cairo_image_surface_get_height(m_imageSurface.get()); if (!m_imageWidth || !m_imageHeight) return false; if (cairo_image_surface_get_format(m_imageSurface.get()) != CAIRO_FORMAT_ARGB32) return false; uint 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; }
static const char * write_ppm (cairo_surface_t *surface, int fd) { char buf[4096]; cairo_format_t format; const char *format_str; const unsigned char *data; int len; int width, height, stride; int i, j; data = cairo_image_surface_get_data (surface); height = cairo_image_surface_get_height (surface); width = cairo_image_surface_get_width (surface); stride = cairo_image_surface_get_stride (surface); format = cairo_image_surface_get_format (surface); if (format == CAIRO_FORMAT_ARGB32) { /* see if we can convert to a standard ppm type and trim a few bytes */ const unsigned char *alpha = data; for (j = height; j--; alpha += stride) { for (i = 0; i < width; i++) { if ((*(unsigned int *) (alpha+4*i) & 0xff000000) != 0xff000000) goto done; } } format = CAIRO_FORMAT_RGB24; done: ; } switch (format) { case CAIRO_FORMAT_ARGB32: /* XXX need true alpha for svg */ format_str = "P7"; break; case CAIRO_FORMAT_RGB24: format_str = "P6"; break; case CAIRO_FORMAT_A8: format_str = "P5"; break; case CAIRO_FORMAT_A1: default: return "unhandled image format"; } len = sprintf (buf, "%s %d %d 255\n", format_str, width, height); for (j = 0; j < height; j++) { const unsigned int *row = (unsigned int *) (data + stride * j); switch ((int) format) { case CAIRO_FORMAT_ARGB32: len = _write (fd, buf, sizeof (buf), len, (unsigned char *) row, 4 * width); break; case CAIRO_FORMAT_RGB24: for (i = 0; i < width; i++) { unsigned char rgb[3]; unsigned int p = *row++; rgb[0] = (p & 0xff0000) >> 16; rgb[1] = (p & 0x00ff00) >> 8; rgb[2] = (p & 0x0000ff) >> 0; len = _write (fd, buf, sizeof (buf), len, rgb, 3); } break; case CAIRO_FORMAT_A8: len = _write (fd, buf, sizeof (buf), len, (unsigned char *) row, width); break; } if (len < 0) return "write failed"; } if (len && ! _writen (fd, buf, len)) return "write failed"; return NULL; }
static cairo_surface_t* _cairocks_create_embossed_surface( cairo_surface_t* surface, double azimuth, double elevation, double height, double ambient, double diffuse ) { unsigned char* src = cairo_image_surface_get_data(surface); int w = cairo_image_surface_get_width(surface); int h = cairo_image_surface_get_height(surface); int stride = cairo_image_surface_get_stride(surface); cairo_surface_t* dst_surface = cairo_image_surface_create(CAIRO_FORMAT_A8, w, h); unsigned char* dst = cairo_image_surface_get_data(dst_surface); double scale = height / (4.0f * 255.0f); double Lx = cos(azimuth) * cos(elevation); double Ly = sin(azimuth) * cos(elevation); double Lz = sin(elevation); int y; int x; memset(dst, minc(ambient + diffuse * Lz), stride * h); /* I'm going to set a minimum requirement size for embossing here for now, since the matrix "d" below assumes 3x3. Later, if it's necessary for such small surfaces, we could rectify this. */ if(w < 4 || h < 4) goto dirty_ret; for(y = 0; y < h; y++) { for(x = 0; x < w; x++) { double Nx; double Ny; double Nz; double NdotL; double d[3][3]; int i; int j; for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { d[i][j] = (unsigned char)(src[OFFSET(x + i - 1, y + j - 1, w, h, stride)]); } } /* Compute the normal from the source. */ Nx = d[2][0] + (2.0f * d[2][1]) + d[2][2]; Nx -= d[0][0] + (2.0f * d[0][1]) + d[0][2]; Nx /= 9; Nx *= scale; Ny = d[0][2] + (2.0f * d[1][2]) + d[2][2]; Ny -= d[0][0] + (2.0f * d[1][0]) + d[2][0]; Ny /= 9; Ny *= scale; Nz = 0.5; NdotL = (Nx * Lx) + (Ny * Ly) + (Nz * Lz); NdotL = (NdotL > 0.0) ? NdotL : 0.0; dst[(y * stride) + x] = minc(ambient + (diffuse * NdotL)); } } dirty_ret: cairo_surface_mark_dirty(dst_surface); return dst_surface; }
static PyObject * image_surface_get_width (PycairoImageSurface *o) { return PyInt_FromLong (cairo_image_surface_get_width (o->surface)); }
void DrawTrayWindow(TrayWindow* trayWindow) { FcitxClassicUI *classicui = trayWindow->owner; FcitxSkin *sc = &classicui->skin; SkinImage *image; int f_state; if (!classicui->bUseTrayIcon) return; if (FcitxInstanceGetCurrentState(classicui->owner) == IS_ACTIVE) f_state = ACTIVE_ICON; else f_state = INACTIVE_ICON; cairo_t *c; cairo_surface_t *png_surface ; if (!trayWindow->bTrayMapped) return; /* 画png */ if (f_state) { image = LoadImage(sc, sc->skinTrayIcon.active, true); } else { image = LoadImage(sc, sc->skinTrayIcon.inactive, true); } if (image == NULL) return; png_surface = image->image; c = cairo_create(trayWindow->cs); cairo_set_source_rgba(c, 0, 0, 0, 0); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_paint(c); do { if (png_surface) { int w = cairo_image_surface_get_width(png_surface); int h = cairo_image_surface_get_height(png_surface); if (w == 0 || h == 0) break; double scaleW = 1.0, scaleH = 1.0; if (w > trayWindow->size || h > trayWindow->size) { scaleW = ((double) trayWindow->size) / w; scaleH = ((double) trayWindow->size) / h; if (scaleW > scaleH) scaleH = scaleW; else scaleW = scaleH; } int aw = scaleW * w; int ah = scaleH * h; cairo_scale(c, scaleW, scaleH); cairo_set_source_surface(c, png_surface, (trayWindow->size - aw) / 2 , (trayWindow->size - ah) / 2); cairo_set_operator(c, CAIRO_OPERATOR_OVER); cairo_paint_with_alpha(c, 1); } } while(0); cairo_destroy(c); XVisualInfo* vi = trayWindow->visual.visual ? &trayWindow->visual : NULL; if (!(vi && vi->visual)) { XClearArea(trayWindow->owner->dpy, trayWindow->window, 0, 0, trayWindow->size, trayWindow->size, False); } c = cairo_create(trayWindow->cs_x); if (vi && vi->visual) { cairo_set_source_rgba(c, 0, 0, 0, 0); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_paint(c); } cairo_set_operator(c, CAIRO_OPERATOR_OVER); cairo_set_source_surface(c, trayWindow->cs, 0, 0); cairo_rectangle(c, 0, 0, trayWindow->size, trayWindow->size); cairo_clip(c); cairo_paint(c); cairo_destroy(c); }
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); }
static gboolean panel_background_prepare (PanelBackground *background) { PanelBackgroundType effective_type; GtkWidget *widget = NULL; if (!background->transformed) return FALSE; effective_type = panel_background_effective_type (background); switch (effective_type) { case PANEL_BACK_NONE: if (background->default_pattern) { /* the theme background-image pattern must be scaled by * the width & height of the panel so that when the * backing region is cleared * (gdk_window_clear_backing_region), the correctly * scaled pattern is used */ cairo_matrix_t m; cairo_surface_t *surface; double width, height; surface = NULL; width = 1.0; height = 1.0; cairo_pattern_get_surface(background->default_pattern, &surface); /* catch invalid images (e.g. -gtk-gradient) before scaling and rendering */ if (surface != NULL ){ cairo_surface_reference(surface); width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); cairo_matrix_init_translate (&m, 0, 0); cairo_matrix_scale (&m, width / background->region.width, height / background->region.height); cairo_pattern_set_matrix (background->default_pattern, &m); gdk_window_set_background_pattern (background->window, background->default_pattern); } else { g_warning ("%s", "unsupported value of 'background-image' in GTK+ theme (such as '-gtk-gradient')"); /* use any background color that has been set if image is invalid */ gdk_window_set_background_rgba ( background->window, &background->default_color); } cairo_surface_destroy(surface); } else gdk_window_set_background_rgba ( background->window, &background->default_color); break; case PANEL_BACK_COLOR: if (background->has_alpha && !gdk_window_check_composited_wm(background->window)) set_pixbuf_background (background); else { gdk_window_set_background_rgba (background->window, &background->color); } break; case PANEL_BACK_IMAGE: set_pixbuf_background (background); break; default: g_assert_not_reached (); break; } /* Panel applets may use the panel's background pixmap to * decide how to draw themselves. Therefore, we need to * make sure that all drawing has been completed before * the applet looks at the pixmap. */ gdk_display_sync (gdk_window_get_display (background->window)); gdk_window_get_user_data (GDK_WINDOW (background->window), (gpointer) &widget); if (GTK_IS_WIDGET (widget)) { panel_background_apply_css (background, gtk_widget_get_toplevel(widget)); gtk_widget_set_app_paintable(widget,TRUE); gtk_widget_queue_draw (widget); } background->notify_changed (background, background->user_data); return TRUE; }
void DrawResizableBackground(cairo_t *c, cairo_surface_t *background, int width, int height, int marginLeft, int marginTop, int marginRight, int marginBottom, FillRule fillV, FillRule fillH ) { int resizeHeight = cairo_image_surface_get_height(background) - marginTop - marginBottom; int resizeWidth = cairo_image_surface_get_width(background) - marginLeft - marginRight; if (resizeHeight <= 0) resizeHeight = 1; if (resizeWidth <= 0) resizeWidth = 1; cairo_save(c); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(c, background, 0, 0); /* 九宫格 * 7 8 9 * 4 5 6 * 1 2 3 */ /* part 1 */ cairo_save(c); cairo_translate(c, 0, height - marginBottom); cairo_set_source_surface(c, background, 0, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, marginLeft, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 3 */ cairo_save(c); cairo_translate(c, width - marginRight, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, marginRight, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 7 */ cairo_save(c); cairo_rectangle(c, 0, 0, marginLeft, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 9 */ cairo_save(c); cairo_translate(c, width - marginRight, 0); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, 0); cairo_rectangle(c, 0, 0, marginRight, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 & 8 */ { if (fillH == F_COPY) { int repaint_times = (width - marginLeft - marginRight) / resizeWidth; int remain_width = (width - marginLeft - marginRight) % resizeWidth; int i = 0; for (i = 0; i < repaint_times; i++) { /* part 8 */ cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth, 0); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, resizeWidth, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, resizeWidth, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } if (remain_width != 0) { /* part 8 */ cairo_save(c); cairo_translate(c, marginLeft + repaint_times * resizeWidth, 0); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, remain_width, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, marginLeft + repaint_times * resizeWidth, height - marginBottom); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, remain_width, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } else { cairo_save(c); cairo_translate(c, marginLeft, 0); cairo_scale(c, (double)(width - marginLeft - marginRight) / (double)resizeWidth, 1); cairo_set_source_surface(c, background, -marginLeft, 0); cairo_rectangle(c, 0, 0, resizeWidth, marginTop); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_save(c); cairo_translate(c, marginLeft, height - marginBottom); cairo_scale(c, (double)(width - marginLeft - marginRight) / (double)resizeWidth, 1); cairo_set_source_surface(c, background, -marginLeft, -marginTop - resizeHeight); cairo_rectangle(c, 0, 0, resizeWidth, marginBottom); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } /* part 4 & 6 */ { if (fillV == F_COPY) { int repaint_times = (height - marginTop - marginBottom) / resizeHeight; int remain_height = (height - marginTop - marginBottom) % resizeHeight; int i = 0; for (i = 0; i < repaint_times; i++) { /* part 4 */ cairo_save(c); cairo_translate(c, 0, marginTop + i * resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 6 */ cairo_save(c); cairo_translate(c, width - marginRight, marginTop + i * resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); } if (remain_height != 0) { /* part 8 */ cairo_save(c); cairo_translate(c, 0, marginTop + repaint_times * resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, remain_height); cairo_clip(c); cairo_paint(c); cairo_restore(c); /* part 2 */ cairo_save(c); cairo_translate(c, width - marginRight, marginTop + repaint_times * resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, remain_height); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } else { cairo_save(c); cairo_translate(c, 0, marginTop); cairo_scale(c, 1, (double)(height - marginTop - marginBottom) / (double)resizeHeight); cairo_set_source_surface(c, background, 0, -marginTop); cairo_rectangle(c, 0, 0, marginLeft, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_save(c); cairo_translate(c, width - marginRight, marginTop); cairo_scale(c, 1, (double)(height - marginTop - marginBottom) / (double)resizeHeight); cairo_set_source_surface(c, background, -marginLeft - resizeWidth, -marginTop); cairo_rectangle(c, 0, 0, marginRight, resizeHeight); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } /* part 5 */ { int repaintH = 0, repaintV = 0; int remainW = 0, remainH = 0; double scaleX = 1.0, scaleY = 1.0; if (fillH == F_COPY) { repaintH = (width - marginLeft - marginRight) / resizeWidth + 1; remainW = (width - marginLeft - marginRight) % resizeWidth; } else { repaintH = 1; scaleX = (double)(width - marginLeft - marginRight) / (double)resizeWidth; } if (fillV == F_COPY) { repaintV = (height - marginTop - marginBottom) / (double)resizeHeight + 1; remainH = (height - marginTop - marginBottom) % resizeHeight; } else { repaintV = 1; scaleY = (double)(height - marginTop - marginBottom) / (double)resizeHeight; } int i, j; for (i = 0; i < repaintH; i ++) { for (j = 0; j < repaintV; j ++) { cairo_save(c); cairo_translate(c, marginLeft + i * resizeWidth , marginTop + j * resizeHeight); cairo_scale(c, scaleX, scaleY); cairo_set_source_surface(c, background, -marginLeft, -marginTop); int w = resizeWidth, h = resizeHeight; if (fillV == F_COPY && j == repaintV - 1) h = remainH; if (fillH == F_COPY && i == repaintH - 1) w = remainW; cairo_rectangle(c, 0, 0, w, h); cairo_clip(c); cairo_paint(c); cairo_restore(c); } } } cairo_restore(c); }
int Image::getSurfaceWidth() const { return cairo_image_surface_get_width(_surface); }
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; }
bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dstHeight, wxDC* source, int xsrc, int ysrc, int srcWidth, int srcHeight, wxRasterOperationMode rop, bool useMask, int xsrcMask, int ysrcMask) { wxCHECK_MSG(IsOk(), false, "invalid DC"); wxCHECK_MSG(source && source->IsOk(), false, "invalid source DC"); cairo_t* cr = NULL; if (m_graphicContext) cr = static_cast<cairo_t*>(m_graphicContext->GetNativeContext()); cairo_t* cr_src = NULL; wxGraphicsContext* gc_src = source->GetGraphicsContext(); if (gc_src) cr_src = static_cast<cairo_t*>(gc_src->GetNativeContext()); if (cr == NULL || cr_src == NULL) return false; const int xsrc_dev = source->LogicalToDeviceX(xsrc); const int ysrc_dev = source->LogicalToDeviceY(ysrc); cairo_surface_t* surfaceSrc = cairo_get_target(cr_src); cairo_surface_flush(surfaceSrc); cairo_surface_t* surfaceTmp = NULL; // If destination (this) and source wxDC refer to the same Cairo context // it means that we operate on one surface and results of drawing // can be invalid if destination and source regions overlap. // In such situation we have to copy source surface to the temporary // surface and use this copy in the drawing operations. if ( cr == cr_src ) { // Check if destination and source regions overlap. // If necessary, copy source surface to the temporary one. if (wxRect(xdest, ydest, dstWidth, dstHeight) .Intersects(wxRect(xsrc, ysrc, srcWidth, srcHeight))) { const int w = cairo_image_surface_get_width(surfaceSrc); const int h = cairo_image_surface_get_height(surfaceSrc); #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0) if ( cairo_version() >= CAIRO_VERSION_ENCODE(1, 12, 0) ) { surfaceTmp = cairo_surface_create_similar_image(surfaceSrc, cairo_image_surface_get_format(surfaceSrc), w, h); } else #endif // Cairo 1.12 { surfaceTmp = cairo_surface_create_similar(surfaceSrc, CAIRO_CONTENT_COLOR_ALPHA, w, h); } cairo_t* crTmp = cairo_create(surfaceTmp); cairo_set_source_surface(crTmp, surfaceSrc, 0, 0); cairo_rectangle(crTmp, 0.0, 0.0, w, h); cairo_set_operator(crTmp, CAIRO_OPERATOR_SOURCE); cairo_fill(crTmp); cairo_destroy(crTmp); cairo_surface_flush(surfaceTmp); surfaceSrc = surfaceTmp; } } cairo_save(cr); cairo_translate(cr, xdest, ydest); cairo_rectangle(cr, 0, 0, dstWidth, dstHeight); double sx, sy; source->GetUserScale(&sx, &sy); cairo_scale(cr, dstWidth / (sx * srcWidth), dstHeight / (sy * srcHeight)); cairo_set_source_surface(cr, surfaceSrc, -xsrc_dev, -ysrc_dev); const wxRasterOperationMode rop_save = m_logicalFunction; SetLogicalFunction(rop); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_surface_t* maskSurf = NULL; if (useMask) { const wxBitmap& bitmap = source->GetImpl()->GetSelectedBitmap(); if (bitmap.IsOk()) { wxMask* mask = bitmap.GetMask(); if (mask) maskSurf = *mask; } } if (maskSurf) { int xsrcMask_dev = xsrc_dev; int ysrcMask_dev = ysrc_dev; if (xsrcMask != -1) xsrcMask_dev = source->LogicalToDeviceX(xsrcMask); if (ysrcMask != -1) ysrcMask_dev = source->LogicalToDeviceY(ysrcMask); cairo_clip(cr); cairo_mask_surface(cr, maskSurf, -xsrcMask_dev, -ysrcMask_dev); } else { cairo_fill(cr); } cairo_restore(cr); if ( surfaceTmp ) { cairo_surface_destroy(surfaceTmp); } m_logicalFunction = rop_save; return true; }
/** renderer for setups */ static NftResult _render_setup(cairo_surface_t ** surface, gpointer element) { if(!surface || !element) NFT_LOG_NULL(NFT_FAILURE); /* setup to render */ LedSetup *s = (LedSetup *) element; /* get dimensions of setup */ LedFrameCord w, h; led_setup_get_dim(s, &w, &h); /* calculate rendered dimensions of this tile */ double width = (double) w * ui_renderer_scale_factor(); double height = (double) h * ui_renderer_scale_factor(); /* if dimensions changed, we need to allocate a new surface */ if(!renderer_resize(setup_get_renderer(), width, height)) { g_error("Failed to resize renderer to %dx%d", w, h); return NFT_FAILURE; } /* create context for drawing */ cairo_t *cr = cairo_create(*surface); /* clear surface */ #ifdef DEBUG cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 1); #else cairo_set_source_rgba(cr, 0, 0, 0, 1); #endif cairo_rectangle(cr, 0, 0, (double) cairo_image_surface_get_width(*surface), (double) cairo_image_surface_get_height(*surface)); cairo_fill(cr); /* walk through all hardware LED adapters */ LedHardware *hw; for(hw = led_setup_get_hardware(s); hw; hw = led_hardware_list_get_next(hw)) { /* calculate offset of complete setup */ LedTile *t; double xOff = 0, yOff = 0; for(t = led_hardware_get_tile(hw); t; t = led_tile_list_get_next(t)) { double xOffT, yOffT; tile_calc_render_offset(led_tile_get_privdata(t), (double) w, (double) h, &xOffT, &yOffT); xOff = MIN(xOff, xOffT); yOff = MIN(yOff, yOffT); } renderer_set_offset(setup_get_renderer(), xOff * ui_renderer_scale_factor(), yOff * ui_renderer_scale_factor()); /* Walk all tiles of this hardware & draw their surface */ for(t = led_hardware_get_tile(hw); t; t = led_tile_list_get_next(t)) { /** @todo check for visibility? */ /* get surface from tile */ NiftyconfTile *tile = (NiftyconfTile *) led_tile_get_privdata(t); /* get surface */ cairo_surface_t *tsurface = renderer_get_surface (tile_get_renderer(tile)); /* compensate child tiles' offset */ double xOffT, yOffT; renderer_get_offset(tile_get_renderer(tile), &xOffT, &yOffT); cairo_translate(cr, xOffT, yOffT); /* compensate setup offset */ cairo_translate(cr, -xOff * ui_renderer_scale_factor(), -yOff * ui_renderer_scale_factor()); /* move to x/y */ LedFrameCord x, y; led_tile_get_pos(t, &x, &y); cairo_translate(cr, ((double) x) * ui_renderer_scale_factor(), ((double) y) * ui_renderer_scale_factor()); /* rotate around pivot */ double pX, pY; led_tile_get_pivot(t, &pX, &pY); cairo_translate(cr, pX * ui_renderer_scale_factor(), pY * ui_renderer_scale_factor()); cairo_rotate(cr, led_tile_get_rotation(t)); cairo_translate(cr, -pX * ui_renderer_scale_factor(), -pY * ui_renderer_scale_factor()); /* draw surface */ cairo_set_source_surface(cr, tsurface, 0, 0); /* disable filtering */ cairo_pattern_set_filter(cairo_get_source(cr), ui_renderer_filter()); /* disable antialiasing */ cairo_set_antialias(cr, ui_renderer_antialias()); /* render surface */ cairo_paint(cr); /* reset transformation matrix */ cairo_identity_matrix(cr); } /* Draw chain of this hardware */ /* s = * chain_get_surface(led_chain_get_privdata(led_hardware_get_chain(h))); * cairo_set_source_surface(cr, s, 0, 0); cairo_paint(cr); */ } cairo_destroy(cr); return NFT_SUCCESS; }
static GtkWidget * gth_file_tool_resize_get_options (GthFileTool *base) { GthFileToolResize *self = (GthFileToolResize *) base; cairo_surface_t *source; GtkWidget *window; GtkWidget *viewer_page; GtkWidget *viewer; GtkAllocation allocation; int preview_width; int preview_height; GtkWidget *options; char *text; source = gth_image_viewer_page_tool_get_source (GTH_IMAGE_VIEWER_PAGE_TOOL (self)); if (source == NULL) return NULL; self->priv->original_width = cairo_image_surface_get_width (source); self->priv->original_height = cairo_image_surface_get_height (source); window = gth_file_tool_get_window (base); viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window)); viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page)); gtk_widget_get_allocation (GTK_WIDGET (viewer), &allocation); preview_width = self->priv->original_width; preview_height = self->priv->original_height; if (scale_keeping_ratio (&preview_width, &preview_height, allocation.width, allocation.height, FALSE)) self->priv->preview = _cairo_image_surface_scale_fast (source, preview_width, preview_height); else self->priv->preview = cairo_surface_reference (source); _gtk_widget_get_screen_size (window, &self->priv->screen_width, &self->priv->screen_height); self->priv->new_image = NULL; self->priv->new_width = self->priv->original_width; self->priv->new_height = self->priv->original_height; self->priv->high_quality = g_settings_get_boolean (self->priv->settings, PREF_RESIZE_HIGH_QUALITY); self->priv->unit = g_settings_get_enum (self->priv->settings, PREF_RESIZE_UNIT); self->priv->builder = _gtk_builder_new_from_file ("resize-options.ui", "file_tools"); self->priv->apply_to_original = FALSE; update_dimensione_info_label (self, "original_dimensions_label", self->priv->original_width, self->priv->original_height, TRUE); options = _gtk_builder_get_widget (self->priv->builder, "options"); gtk_widget_show (options); if (self->priv->unit == GTH_UNIT_PIXELS) { gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 0); gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 0); gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), g_settings_get_double (self->priv->settings, PREF_RESIZE_WIDTH)); gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), g_settings_get_double (self->priv->settings, PREF_RESIZE_HEIGHT)); } else if (self->priv->unit == GTH_UNIT_PERCENTAGE) { gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 2); gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 2); gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), g_settings_get_double (self->priv->settings, PREF_RESIZE_WIDTH)); gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), g_settings_get_double (self->priv->settings, PREF_RESIZE_HEIGHT)); } gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")), self->priv->unit); self->priv->ratio_combobox = _gtk_combo_box_new_with_texts (_("None"), _("Square"), NULL); text = g_strdup_printf (_("%d x %d (Image)"), self->priv->original_width, self->priv->original_height); gtk_label_set_text (GTK_LABEL (GET_WIDGET ("image_size_label")), text); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->priv->ratio_combobox), text); g_free (text); text = g_strdup_printf (_("%d x %d (Screen)"), self->priv->screen_width, self->priv->screen_height); gtk_label_set_text (GTK_LABEL (GET_WIDGET ("screen_size_label")), text); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->priv->ratio_combobox), text); g_free (text); _gtk_combo_box_append_texts (GTK_COMBO_BOX_TEXT (self->priv->ratio_combobox), _("5:4"), _("4:3 (DVD, Book)"), _("7:5"), _("3:2 (Postcard)"), _("16:10"), _("16:9 (DVD)"), _("1.85:1"), _("2.39:1"), _("Custom"), NULL); gtk_widget_show (self->priv->ratio_combobox); gtk_box_pack_start (GTK_BOX (GET_WIDGET ("ratio_combobox_box")), self->priv->ratio_combobox, TRUE, TRUE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("high_quality_checkbutton")), self->priv->high_quality); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("invert_ratio_checkbutton")), g_settings_get_boolean (self->priv->settings, PREF_RESIZE_ASPECT_RATIO_INVERT)); gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_w_spinbutton")), MAX (g_settings_get_int (self->priv->settings, PREF_RESIZE_ASPECT_RATIO_WIDTH), 1)); gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_h_spinbutton")), MAX (g_settings_get_int (self->priv->settings, PREF_RESIZE_ASPECT_RATIO_HEIGHT), 1)); g_signal_connect_swapped (GET_WIDGET ("options_close_button"), "clicked", G_CALLBACK (gtk_widget_hide), GET_WIDGET ("options_dialog")); g_signal_connect (GET_WIDGET ("options_dialog"), "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL); g_signal_connect (GET_WIDGET ("resize_width_spinbutton"), "value-changed", G_CALLBACK (selection_width_value_changed_cb), self); g_signal_connect (GET_WIDGET ("resize_height_spinbutton"), "value-changed", G_CALLBACK (selection_height_value_changed_cb), self); g_signal_connect (GET_WIDGET ("high_quality_checkbutton"), "toggled", G_CALLBACK (high_quality_checkbutton_toggled_cb), self); g_signal_connect (GET_WIDGET ("unit_combobox"), "changed", G_CALLBACK (unit_combobox_changed_cb), self); g_signal_connect (self->priv->ratio_combobox, "changed", G_CALLBACK (ratio_combobox_changed_cb), self); g_signal_connect (GET_WIDGET ("ratio_w_spinbutton"), "value_changed", G_CALLBACK (ratio_value_changed_cb), self); g_signal_connect (GET_WIDGET ("ratio_h_spinbutton"), "value_changed", G_CALLBACK (ratio_value_changed_cb), self); g_signal_connect (GET_WIDGET ("invert_ratio_checkbutton"), "toggled", G_CALLBACK (invert_ratio_changed_cb), self); g_signal_connect (GET_WIDGET ("image_size_button"), "clicked", G_CALLBACK (image_size_button_clicked_cb), self); g_signal_connect (GET_WIDGET ("screen_size_button"), "clicked", G_CALLBACK (screen_size_button_clicked_cb), self); gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->ratio_combobox), g_settings_get_enum (self->priv->settings, PREF_RESIZE_ASPECT_RATIO)); gth_image_viewer_set_zoom_quality (GTH_IMAGE_VIEWER (viewer), GTH_ZOOM_QUALITY_HIGH); return options; }
static void image_set_from_surface (GtkImage *gtkimage, cairo_surface_t *surface) { GdkPixbuf *pixbuf; cairo_surface_t *image; cairo_t *cr; gboolean has_alpha; gint width, height; cairo_format_t surface_format; gint pixbuf_n_channels; gint pixbuf_rowstride; guchar *pixbuf_pixels; gint x, y; width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); surface_format = cairo_image_surface_get_format (surface); has_alpha = (surface_format == CAIRO_FORMAT_ARGB32); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf); pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); pixbuf_pixels = gdk_pixbuf_get_pixels (pixbuf); image = cairo_image_surface_create_for_data (pixbuf_pixels, surface_format, width, height, pixbuf_rowstride); cr = cairo_create (image); cairo_set_source_surface (cr, surface, 0, 0); if (has_alpha) cairo_mask_surface (cr, surface, 0, 0); else cairo_paint (cr); cairo_destroy (cr); cairo_surface_destroy (image); for (y = 0; y < height; y++) { guchar *p = pixbuf_pixels + y * pixbuf_rowstride; for (x = 0; x < width; x++) { guchar tmp; #if G_BYTE_ORDER == G_LITTLE_ENDIAN tmp = p[0]; p[0] = p[2]; p[2] = tmp; p[3] = (has_alpha) ? p[3] : 0xff; #else tmp = p[0]; p[0] = (has_alpha) ? p[3] : 0xff; p[3] = p[2]; p[2] = p[1]; p[1] = tmp; #endif p += pixbuf_n_channels; } } gtk_image_set_from_pixbuf (gtkimage, pixbuf); g_object_unref (pixbuf); }
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); }
static VALUE cr_image_surface_get_width (VALUE self) { return INT2NUM (cairo_image_surface_get_width (_SELF)); }
/** * _st_create_shadow_cairo_pattern: * @shadow_spec: the definition of the shadow * @src_pattern: surface pattern for which we create the shadow * (must be a surface pattern) * * This is a utility function for creating shadows used by * st-theme-node.c; it's in this file to share the gaussian * blur implementation. The usage of this function is quite different * depending on whether shadow_spec->inset is %TRUE or not. If * shadow_spec->inset is %TRUE, the caller should pass in a @src_pattern * which is the <i>inverse</i> of what they want shadowed, and must take * care of the spread and offset from the shadow spec themselves. If * shadow_spec->inset is %FALSE then the caller should pass in what they * want shadowed directly, and this function takes care of the spread and * the offset. */ cairo_pattern_t * _st_create_shadow_cairo_pattern (StShadow *shadow_spec, cairo_pattern_t *src_pattern) { static cairo_user_data_key_t shadow_pattern_user_data; cairo_t *cr; cairo_surface_t *src_surface; cairo_surface_t *surface_in; cairo_surface_t *surface_out; cairo_pattern_t *dst_pattern; guchar *pixels_in, *pixels_out; gint width_in, height_in, rowstride_in; gint width_out, height_out, rowstride_out; cairo_matrix_t shadow_matrix; int i, j; g_return_val_if_fail (shadow_spec != NULL, NULL); g_return_val_if_fail (src_pattern != NULL, NULL); cairo_pattern_get_surface (src_pattern, &src_surface); width_in = cairo_image_surface_get_width (src_surface); height_in = cairo_image_surface_get_height (src_surface); /* We want the output to be a color agnostic alpha mask, * so we need to strip the color channels from the input */ if (cairo_image_surface_get_format (src_surface) != CAIRO_FORMAT_A8) { surface_in = cairo_image_surface_create (CAIRO_FORMAT_A8, width_in, height_in); cr = cairo_create (surface_in); cairo_set_source_surface (cr, src_surface, 0, 0); cairo_paint (cr); cairo_destroy (cr); } else { surface_in = cairo_surface_reference (src_surface); } pixels_in = cairo_image_surface_get_data (surface_in); rowstride_in = cairo_image_surface_get_stride (surface_in); pixels_out = blur_pixels (pixels_in, width_in, height_in, rowstride_in, shadow_spec->blur, &width_out, &height_out, &rowstride_out); cairo_surface_destroy (surface_in); /* Invert pixels for inset shadows */ if (shadow_spec->inset) { for (j = 0; j < height_out; j++) { guchar *p = pixels_out + rowstride_out * j; for (i = 0; i < width_out; i++, p++) *p = ~*p; } } surface_out = cairo_image_surface_create_for_data (pixels_out, CAIRO_FORMAT_A8, width_out, height_out, rowstride_out); cairo_surface_set_user_data (surface_out, &shadow_pattern_user_data, pixels_out, (cairo_destroy_func_t) g_free); dst_pattern = cairo_pattern_create_for_surface (surface_out); cairo_surface_destroy (surface_out); cairo_pattern_get_matrix (src_pattern, &shadow_matrix); if (shadow_spec->inset) { /* For inset shadows, offsets and spread radius have already been * applied to the original pattern, so all left to do is shift the * blurred image left, so that it aligns centered under the * unblurred one */ cairo_matrix_translate (&shadow_matrix, (width_out - width_in) / 2.0, (height_out - height_in) / 2.0); cairo_pattern_set_matrix (dst_pattern, &shadow_matrix); return dst_pattern; } /* Read all the code from the cairo_pattern_set_matrix call * at the end of this function to here from bottom to top, * because each new affine transformation is applied in * front of all the previous ones */ /* 6. Invert the matrix back */ cairo_matrix_invert (&shadow_matrix); /* 5. Adjust based on specified offsets */ cairo_matrix_translate (&shadow_matrix, shadow_spec->xoffset, shadow_spec->yoffset); /* 4. Recenter the newly scaled image */ cairo_matrix_translate (&shadow_matrix, - shadow_spec->spread, - shadow_spec->spread); /* 3. Scale up the blurred image to fill the spread */ cairo_matrix_scale (&shadow_matrix, (width_in + 2.0 * shadow_spec->spread) / width_in, (height_in + 2.0 * shadow_spec->spread) / height_in); /* 2. Shift the blurred image left, so that it aligns centered * under the unblurred one */ cairo_matrix_translate (&shadow_matrix, - (width_out - width_in) / 2.0, - (height_out - height_in) / 2.0); /* 1. Invert the matrix so we can work with it in pattern space */ cairo_matrix_invert (&shadow_matrix); cairo_pattern_set_matrix (dst_pattern, &shadow_matrix); return dst_pattern; }
static cairo_test_status_t test_cairo_image_surface_get_width (cairo_surface_t *surface) { unsigned int width = cairo_image_surface_get_width (surface); return width == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_IMAGE) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR; }
static gint get_surface_size (cairo_surface_t *surface) { return MAX (cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface)); }
GtkWidget *create_class_page (void) { #if 1 GtkWidget *vbox; gchar *path; vbox = gtk_vbox_new (FALSE, 0); priv->kb = utt_keyboard_new (); path = g_build_filename (PKGDATADIR, "keyboard_wubi.png", NULL); utt_keyboard_set_image (UTT_KEYBOARD (priv->kb), path); g_free (path); gtk_box_pack_start (GTK_BOX (vbox), priv->kb, FALSE, FALSE, 0); return vbox; #else GtkWidget *vbox; GtkWidget *frame, *hbox, *hbox2, *align; GtkWidget *ch_draw[6]; GtkWidget *kb_draw; cairo_surface_t *kb_image; gint i; gchar *path; vbox = gtk_vbox_new (FALSE, 0); frame = gtk_frame_new (_("Display Zone")); hbox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), hbox); gtk_container_set_border_width (GTK_CONTAINER (frame), 4); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); /* padding */ hbox2 = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), hbox2, TRUE, TRUE, 0); for (i = 0; i < 6; i++) { ch_draw[i] = gtk_drawing_area_new (); gtk_widget_set_size_request (ch_draw[i], 48, 48); hbox2 = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), hbox2, TRUE, TRUE, 0); align = gtk_alignment_new (0.5, 0.5, 0, 0); gtk_container_add (GTK_CONTAINER (align), ch_draw[i]); gtk_box_pack_start (GTK_BOX (hbox2), align, TRUE, TRUE, 0); } /* padding */ hbox2 = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), hbox2, TRUE, TRUE, 0); kb_draw = gtk_drawing_area_new (); path = g_build_filename (PKGDATADIR, "keyboard_wubi.png", NULL); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { g_error (G_STRLOC ": %s doesn't exists.", path); } kb_image = cairo_image_surface_create_from_png (path); g_free (path); gtk_widget_add_events (kb_draw, GDK_KEY_PRESS_MASK); /* set can focus and grab focus, so we can receive key press event */ gtk_widget_set_can_focus (kb_draw, TRUE); gtk_widget_set_size_request (kb_draw, cairo_image_surface_get_width (kb_image), cairo_image_surface_get_height (kb_image)); align = gtk_alignment_new (0.5, 0.5, 0, 0); gtk_container_add (GTK_CONTAINER (align), kb_draw); gtk_container_set_border_width (GTK_CONTAINER (align), 4); gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0); return vbox; #endif }
/* * function to draw the rectangular selection */ static void paint_selection (cairo_t *ci, Detect * d) { double t = microtime(); int w = cairo_image_surface_get_width (surface); int h = cairo_image_surface_get_height (surface); /** draw brush */ /* cairo_surface_t* test; cairo_t *cb; double brush_w = 70, brush_h = 70; int w = cairo_image_surface_get_width (image); int h = cairo_image_surface_get_height (image); test = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, w, h ); cb = cairo_create(test); cairo_scale (cb, brush_w/w, brush_h/h); cairo_set_source_surface (cb, image, 0, 0); cairo_mask_surface(cb, test, 0, 0); cairo_paint(cb); cairo_destroy (cb); // cairo_set_source_rgb (ci, 0.5,0.5,0.5); cairo_paint(ci); cairo_set_source_surface (ci, test, mouse->x-(brush_w/2),mouse->y-(brush_h/2)); cairo_paint(ci); */ d_events * events; d_events::iterator it_events; events = d->GetEvents(); MousePosition mouse; /* mouse->x = 100; mouse->y = 100; mouse->prev_x = 250; mouse->prev_y = 100;*/ //cairo_save (ci); //printf("size %d \n",events->size()); for(it_events = events->begin(); it_events!= events->end(); it_events++){ if(it_events->second.live ){ mouse.x = (gint) (w*(1-it_events->second.x)); mouse.y = (gint) (h*it_events->second.y); mouse.prev_x = (gint) (w*(1-it_events->second.last[1].x)); mouse.prev_y = (gint) (h*(it_events->second.last[1].y)); mouse.bold = it_events->second.size; // printf("mouse: %d %d %d | ", mouse.x, mouse.y, mouse.bold); //printf("mouse: %d %d %d | ", mouse.prev_x, mouse.prev_y, mouse.bold); //printf("mouse: %f %f | %f %f \n", it_events->second.x, it_events->second.y, it_events->second.last[1].x, it_events->second.last[1].y); /*cairo_set_source_rgba (ci, 255,0,0, 1.); cairo_arc (ci, mouse.x,mouse.y, 20, 0, 2 * M_PI); cairo_fill_preserve (ci); cairo_stroke (ci);*/ //printf("%f %f\n",mouse->f_x,mouse->f_y); //if(!(mouse->f_x>0 && mouse->f_y > 0)) return; //mouse->x = (int) (w-mouse->f_x*w); //mouse->y = (int) (mouse->f_y*h); //printf("(%d %d) %d %d < %f %f\n",w,h,mouse->x,mouse->y,mouse->f_x,mouse->f_y); /* proložení vykreslování */ float test_t = sqrt(pow(mouse.x-mouse.prev_x,2) + pow(mouse.y-mouse.prev_y,2)); int size_brush; //omezení pokud jsou velké skoky if(test_t==0 || test_t > 100) break; if(brush_type == 0 || brush_type==3){ size_brush = (mouse.bold / 2) - 5; if(size_brush < 5) size_brush = 5; if(size_brush > 20) size_brush = 20; cairo_set_line_width (ci, 0.); } else { size_brush = mouse.bold / 10; if(size_brush > 5) size_brush = 5; if(size_brush < 1) size_brush = 1; } // printf("brush %d \n", size_brush); int step = int (test_t/size_brush); int rate_rand = 10; //printf("%d %d\n",size_brush, mouse->bold); //délka jednoho tahu double step_x = (mouse.x - mouse.prev_x)/(double) step; double step_y = (mouse.y - mouse.prev_y)/(double) step; float aplha = 1.; if (brush_type == 3) aplha = 0.3; if(brush_type == 2) { aplha = 0.2; // size_brush = 5; } // printf("color: %f %f %f\n",color.r, color.g, color.b); /* proložení ploch */ if(brush_type == 0){ for(int i=0; i < step+1; i++){ if(brush_type == 0){ cairo_set_source_rgba (ci, color.r, color.g, color.b, 1.); cairo_arc (ci, mouse.prev_x+step_x*i,mouse.prev_y+step_y*i, size_brush, 0, 2 * M_PI); cairo_fill_preserve (ci); cairo_stroke (ci); } else { cairo_set_source_rgba (ci, color.r, color.g, color.b, aplha); for(int j=0; j < 5; j++){ // printf("%f ",10*(drand48()*2.-1.)); cairo_arc (ci, (mouse.prev_x+step_x*i)+rate_rand*(drand48()*2.-1.), (mouse.prev_y+step_y*i)+rate_rand*(drand48()*2.-1.), size_brush, 0, 2 * M_PI); cairo_fill_preserve (ci); cairo_stroke (ci); } } } } //vykreslení plochy if(brush_type == 0){ cairo_set_source_rgba (ci, color.r, color.g, color.b, 1.); cairo_arc (ci, mouse.x, mouse.y, size_brush, 0, 2 * M_PI); cairo_fill_preserve (ci); cairo_stroke (ci); } else { cairo_set_source_rgba (ci, color.r, color.g, color.b, aplha); for(int j=0; j < 8; j++){ // printf("%f ",10*(drand48()*2.-1.)); cairo_arc (ci, mouse.x+rate_rand*(drand48()*2.5-1.), mouse.y+rate_rand*(drand48()*2.5-1.), ((int) size_brush), 0, 2 * M_PI); cairo_fill_preserve (ci); cairo_stroke (ci); } } } } // cairo_restore (ci); if(image!=NULL){ int _w = cairo_image_surface_get_width (image); int _h = cairo_image_surface_get_height (image); //cairo_surface_t* test; //cairo_t *cb; //test = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, _w, _h ); //printf("%d %d\n",_w,_h); //cb = cairo_create(test); cairo_scale (ci, w/(double)_w, h/(double)_h); cairo_set_source_surface (ci, image, 0, 0); cairo_paint(ci); } cairo_restore (ci); timer[1] = microtime() - t; }
void flush() { cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_A8, _totalWidth, _maxHeight); cairo_t *cr = cairo_create(surface); int pos = 0; cairo_set_source_rgba (cr, 0., 0., 0., 0); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_font_options_t *fontOptions = cairo_font_options_create(); cairo_get_font_options(cr, fontOptions); cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL); cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_GRAY); cairo_set_font_options(cr, fontOptions); cairo_font_options_destroy(fontOptions); cairo_set_source_rgba(cr, 1, 1, 1, 1); for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end(); ++it) { cairo_move_to(cr, pos - it->xBearing, -it->yBearing); cairo_set_font_size(cr, it->fontSize); cairo_set_font_face(cr, it->fontFace); cairo_show_text(cr, it->text.c_str()); cairo_font_face_destroy(it->fontFace); pos += it->width; } cairo_destroy(cr); //setup matrices GLint matrixMode; GLuint textureId; glGetIntegerv (GL_MATRIX_MODE, &matrixMode); glMatrixMode (GL_PROJECTION); glPushMatrix(); glLoadIdentity (); glMatrixMode (GL_MODELVIEW); glPushMatrix(); glLoadIdentity (); float winw = Fl_Window::current()->w(); float winh = Fl_Window::current()->h(); glScalef (2.0f / winw, 2.0f / winh, 1.0f); glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f); //write the texture on screen glEnable(GL_TEXTURE_RECTANGLE_ARB); glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureId); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA, cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface), 0, GL_ALPHA, GL_UNSIGNED_BYTE, cairo_image_surface_get_data(surface)); //glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SRC0_ALPHA); //printf("error %i %s\n", __LINE__, gluErrorString(glGetError())); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pos = 0; for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end(); ++it) { glTranslatef(it->x, it->y, it->z); glColor4f(it->r, it->g, it->b, it->alpha); int Lx = it->width; int Ly = it->height; glBegin (GL_QUADS); glTexCoord2f (pos, 0); glVertex2f (0.0f, Ly); glTexCoord2f (pos + Lx, 0); glVertex2f (Lx, Ly); glTexCoord2f (pos + Lx, Ly); glVertex2f (Lx, 0.0f); glTexCoord2f (pos, Ly); glVertex2f (0.0f, 0.0f); glEnd (); pos += Lx; glTranslatef(-it->x, -it->y, -it->z); } glDeleteTextures(1, &textureId); glPopAttrib(); // reset original matrices glPopMatrix(); // GL_MODELVIEW glMatrixMode (GL_PROJECTION); glPopMatrix(); glMatrixMode (matrixMode); _elements.clear(); _maxHeight = 0; _totalWidth = 0; cairo_surface_destroy(surface); }
void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator compositeOp) { size_t frames = frameCount(); for (size_t i = 0; i < frames; ++i) { cairo_surface_t* image = frameAtIndex(i)->surface(); if (cairo_image_surface_get_height(image) == static_cast<size_t>(srcSize.height()) && cairo_image_surface_get_width(image) == static_cast<size_t>(srcSize.width())) { size_t currentFrame = m_currentFrame; m_currentFrame = i; draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, srcSize.width(), srcSize.height()), ColorSpaceDeviceRGB, compositeOp); m_currentFrame = currentFrame; return; } } // No image of the correct size was found, fallback to drawing the current frame IntSize imageSize = BitmapImage::size(); draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), ColorSpaceDeviceRGB, compositeOp); }
int main(int argc, char **argv) { char *image_path = NULL; char *scaling_mode_str = "fit"; init_log(L_INFO); static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"image", required_argument, NULL, 'i'}, {"scaling", required_argument, NULL, 's'}, {"tiling", no_argument, NULL, 't'}, {"version", no_argument, NULL, 'v'}, {0, 0, 0, 0} }; const char *usage = "Usage: swaylock [options...]\n" "\n" " -h, --help Show help message and quit.\n" " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n" " -t, --tiling Same as --scaling=tile.\n" " -v, --version Show the version number and quit.\n" " -i, --image <path> Display the given image.\n"; int c; while (1) { int option_index = 0; c = getopt_long(argc, argv, "hi:s:tv", long_options, &option_index); if (c == -1) { break; } switch (c) { case 'i': image_path = optarg; break; case 's': scaling_mode_str = optarg; break; case 't': scaling_mode_str = "tile"; break; case 'v': #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", SWAY_GIT_VERSION, SWAY_VERSION_DATE, SWAY_GIT_BRANCH); #else fprintf(stdout, "version not detected\n"); #endif exit(EXIT_SUCCESS); break; default: fprintf(stderr, "%s", usage); exit(EXIT_FAILURE); } } // TODO: support locking without image if (!image_path) { fprintf(stderr, "No image specified!\n"); exit(EXIT_FAILURE); } password = malloc(1024); // TODO: Let this grow password[0] = '\0'; surfaces = create_list(); registry = registry_poll(); if (!registry->swaylock) { sway_abort("swaylock requires the compositor to support the swaylock extension."); } int i; for (i = 0; i < registry->outputs->length; ++i) { struct output_state *output = registry->outputs->items[i]; struct window *window = window_setup(registry, output->width, output->height, true); if (!window) { sway_abort("Failed to create surfaces."); } list_add(surfaces, window); } registry->input->notify = notify_key; #ifdef WITH_GDK_PIXBUF GError *err = NULL; GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(image_path, &err); if (!pixbuf) { sway_abort("Failed to load background image."); } cairo_surface_t *image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf); g_object_unref(pixbuf); #else cairo_surface_t *image = cairo_image_surface_create_from_png(argv[1]); #endif //WITH_GDK_PIXBUF if (!image) { sway_abort("Failed to read background image."); } double width = cairo_image_surface_get_width(image); double height = cairo_image_surface_get_height(image); enum scaling_mode scaling_mode = SCALING_MODE_STRETCH; if (strcmp(scaling_mode_str, "stretch") == 0) { scaling_mode = SCALING_MODE_STRETCH; } else if (strcmp(scaling_mode_str, "fill") == 0) { scaling_mode = SCALING_MODE_FILL; } else if (strcmp(scaling_mode_str, "fit") == 0) { scaling_mode = SCALING_MODE_FIT; } else if (strcmp(scaling_mode_str, "center") == 0) { scaling_mode = SCALING_MODE_CENTER; } else if (strcmp(scaling_mode_str, "tile") == 0) { scaling_mode = SCALING_MODE_TILE; } else { sway_abort("Unsupported scaling mode: %s", scaling_mode_str); } for (i = 0; i < surfaces->length; ++i) { struct window *window = surfaces->items[i]; if (window_prerender(window) && window->cairo) { switch (scaling_mode) { case SCALING_MODE_STRETCH: cairo_scale(window->cairo, (double) window->width / width, (double) window->height / height); cairo_set_source_surface(window->cairo, image, 0, 0); break; case SCALING_MODE_FILL: { double window_ratio = (double) window->width / window->height; double bg_ratio = width / height; if (window_ratio > bg_ratio) { double scale = (double) window->width / width; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, 0, (double) window->height/2 / scale - height/2); } else { double scale = (double) window->height / height; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, (double) window->width/2 / scale - width/2, 0); } break; } case SCALING_MODE_FIT: { double window_ratio = (double) window->width / window->height; double bg_ratio = width / height; if (window_ratio > bg_ratio) { double scale = (double) window->height / height; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, (double) window->width/2 / scale - width/2, 0); } else { double scale = (double) window->width / width; cairo_scale(window->cairo, scale, scale); cairo_set_source_surface(window->cairo, image, 0, (double) window->height/2 / scale - height/2); } break; } case SCALING_MODE_CENTER: cairo_set_source_surface(window->cairo, image, (double) window->width/2 - width/2, (double) window->height/2 - height/2); break; case SCALING_MODE_TILE: { cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); cairo_set_source(window->cairo, pattern); break; } default: sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str); } cairo_paint(window->cairo); window_render(window); } } cairo_surface_destroy(image); bool locked = false; while (wl_display_dispatch(registry->display) != -1) { if (!locked) { for (i = 0; i < registry->outputs->length; ++i) { struct output_state *output = registry->outputs->items[i]; struct window *window = surfaces->items[i]; lock_set_lock_surface(registry->swaylock, output->output, window->surface); } locked = true; } } for (i = 0; i < surfaces->length; ++i) { struct window *window = surfaces->items[i]; window_teardown(window); } list_free(surfaces); registry_teardown(registry); return 0; }
BufferData * _create_buffer_similar (BufferData *buffer) { return _create_buffer (cairo_image_surface_get_width (buffer->surface), cairo_image_surface_get_height (buffer->surface)); }
static void gd_tagged_entry_tag_get_relative_allocations (GdTaggedEntryTag *tag, GdTaggedEntry *entry, GtkStyleContext *context, GtkAllocation *background_allocation_out, GtkAllocation *layout_allocation_out, GtkAllocation *button_allocation_out) { GtkAllocation background_allocation, layout_allocation, button_allocation; gint width, height, x, y, pix_width, pix_height; gint layout_width, layout_height; gint scale_factor; GtkBorder padding, border; GtkStateFlags state; width = gdk_window_get_width (tag->window); height = gdk_window_get_height (tag->window); scale_factor = gdk_window_get_scale_factor (tag->window); state = gd_tagged_entry_tag_get_state (tag, entry); gtk_style_context_get_margin (context, state, &padding); width -= padding.left + padding.right; height -= padding.top + padding.bottom; x = padding.left; y = padding.top; background_allocation.x = x; background_allocation.y = y; background_allocation.width = width; background_allocation.height = height; layout_allocation = button_allocation = background_allocation; gtk_style_context_get_padding (context, state, &padding); gtk_style_context_get_border (context, state, &border); gd_tagged_entry_tag_ensure_layout (tag, entry); pango_layout_get_pixel_size (tag->layout, &layout_width, &layout_height); layout_allocation.x += border.left + padding.left; layout_allocation.y += (layout_allocation.height - layout_height) / 2; if (entry->button_visible && tag->has_close_button) { pix_width = cairo_image_surface_get_width (tag->close_surface) / scale_factor; pix_height = cairo_image_surface_get_height (tag->close_surface) / scale_factor; } else { pix_width = 0; pix_height = 0; } button_allocation.x += width - pix_width - border.right - padding.right; button_allocation.y += (height - pix_height) / 2; button_allocation.width = pix_width; button_allocation.height = pix_height; if (background_allocation_out) *background_allocation_out = background_allocation; if (layout_allocation_out) *layout_allocation_out = layout_allocation; if (button_allocation_out) *button_allocation_out = button_allocation; }