void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) { FloatRect srcRect(src); FloatRect dstRect(dst); if (dstRect.width() == 0.0f || dstRect.height() == 0.0f || srcRect.width() == 0.0f || srcRect.height() == 0.0f) return; startAnimation(); cairo_surface_t* image = frameAtIndex(m_currentFrame); if (!image) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op); return; } IntSize selfSize = size(); cairo_t* cr = context->platformContext(); context->save(); // Set the compositing operation. if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame)) context->setCompositeOperation(CompositeCopy); else context->setCompositeOperation(op); // If we're drawing a sub portion of the image or scaling then create // a pattern transformation on the image and draw the transformed pattern. // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); float scaleX = srcRect.width() / dstRect.width(); float scaleY = srcRect.height() / dstRect.height(); cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() }; cairo_pattern_set_matrix(pattern, &matrix); // Draw the shadow #if ENABLE(FILTERS) FloatSize shadowOffset; float shadowBlur; Color shadowColor; if (context->getShadow(shadowOffset, shadowBlur, shadowColor)) { IntSize shadowBufferSize; FloatRect shadowRect; float radius = 0; context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowOffset, shadowBlur); shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() * context->getAlpha()) / 255.f); //draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); cairo_t* shadowContext = shadowBuffer->context()->platformContext(); cairo_set_source(shadowContext, pattern); cairo_translate(shadowContext, -dstRect.x(), -dstRect.y()); cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height()); cairo_fill(shadowContext); context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); } #endif // Draw the image. cairo_translate(cr, dstRect.x(), dstRect.y()); cairo_set_source(cr, pattern); cairo_pattern_destroy(pattern); cairo_rectangle(cr, 0, 0, dstRect.width(), dstRect.height()); cairo_clip(cr); cairo_paint_with_alpha(cr, context->getAlpha()); context->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
static void update_surface (FishApplet *fish) { GtkWidget *widget = fish->drawing_area; GtkRequisition prev_requisition; GtkAllocation allocation; int width = -1; int height = -1; int pixbuf_width = -1; int pixbuf_height = -1; gboolean rotate = FALSE; cairo_t *cr; cairo_matrix_t matrix; cairo_pattern_t *pattern; gtk_widget_get_allocation (widget, &allocation); if (!gtk_widget_get_realized (widget) || allocation.width <= 0 || allocation.height <= 0) return; if (!fish->pixbuf && !load_fish_image (fish)) return; if (fish->rotate && (fish->orientation == PANEL_APPLET_ORIENT_LEFT || fish->orientation == PANEL_APPLET_ORIENT_RIGHT)) rotate = TRUE; pixbuf_width = gdk_pixbuf_get_width (fish->pixbuf); pixbuf_height = gdk_pixbuf_get_height (fish->pixbuf); prev_requisition = fish->requisition; if (fish->orientation == PANEL_APPLET_ORIENT_UP || fish->orientation == PANEL_APPLET_ORIENT_DOWN) { height = allocation.height; width = pixbuf_width * ((gdouble) height / pixbuf_height); fish->requisition.width = width / fish->n_frames; fish->requisition.height = height; } else { if (!rotate) { width = allocation.width * fish->n_frames; height = pixbuf_height * ((gdouble) width / pixbuf_width); fish->requisition.width = allocation.width; fish->requisition.height = height; } else { width = allocation.width; height = pixbuf_width * ((gdouble) width / pixbuf_height); fish->requisition.width = width; fish->requisition.height = height / fish->n_frames; } } if (prev_requisition.width != fish->requisition.width || prev_requisition.height != fish->requisition.height) { gtk_widget_set_size_request (widget, fish->requisition.width, fish->requisition.height); } g_assert (width != -1 && height != -1); if (width == 0 || height == 0) return; if (fish->surface) cairo_surface_destroy (fish->surface); fish->surface = gdk_window_create_similar_surface ( gtk_widget_get_window (widget), CAIRO_CONTENT_COLOR_ALPHA, width, height); gtk_widget_queue_resize (widget); g_assert (pixbuf_width != -1 && pixbuf_height != -1); cr = cairo_create (fish->surface); cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); gdk_cairo_set_source_pixbuf (cr, fish->pixbuf, 0, 0); pattern = cairo_get_source (cr); cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST); cairo_matrix_init_identity (&matrix); if (fish->april_fools) { cairo_matrix_translate (&matrix, pixbuf_width - 1, pixbuf_height - 1); cairo_matrix_rotate (&matrix, M_PI); } if (rotate) { if (fish->orientation == PANEL_APPLET_ORIENT_RIGHT) { cairo_matrix_translate (&matrix, pixbuf_width - 1, 0); cairo_matrix_rotate (&matrix, M_PI * 0.5); } else { cairo_matrix_translate (&matrix, 0, pixbuf_height - 1); cairo_matrix_rotate (&matrix, M_PI * 1.5); } cairo_matrix_scale (&matrix, (double) (pixbuf_height - 1) / width, (double) (pixbuf_width - 1) / height); } else { cairo_matrix_scale (&matrix, (double) (pixbuf_width - 1) / width, (double) (pixbuf_height - 1) / height); } cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); if (fish->april_fools) { cairo_set_source_rgb (cr, 1, 0.5, 0); cairo_paint_with_alpha (cr, 0.25); } cairo_destroy (cr); }
void lime_cairo_paint_with_alpha (value handle, double alpha) { cairo_paint_with_alpha ((cairo_t*)val_data (handle), alpha); }
static int m_display_draw_ninepatch(lua_State * L) { struct ldisplay_t * display = luaL_checkudata(L, 1, MT_DISPLAY); struct lobject_t * object = luaL_checkudata(L, 2, MT_OBJECT); struct lninepatch_t * ninepatch = luaL_checkudata(L, 3, MT_NINEPATCH); cairo_t * cr = display->cr[display->index]; cairo_save(cr); cairo_set_matrix(cr, &object->__transform_matrix); if(ninepatch->lt) { cairo_save(cr); cairo_translate(cr, 0, 0); cairo_set_source_surface(cr, ninepatch->lt, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_paint_with_alpha(cr, object->alpha); cairo_restore(cr); } if(ninepatch->mt) { cairo_save(cr); cairo_translate(cr, ninepatch->left, 0); cairo_scale(cr, ninepatch->__sx, 1); cairo_set_source_surface(cr, ninepatch->mt, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_paint_with_alpha(cr, object->alpha); cairo_restore(cr); } if(ninepatch->rt) { cairo_save(cr); cairo_translate(cr, ninepatch->__w - ninepatch->right, 0); cairo_set_source_surface(cr, ninepatch->rt, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_paint_with_alpha(cr, object->alpha); cairo_restore(cr); } if(ninepatch->lm) { cairo_save(cr); cairo_translate(cr, 0, ninepatch->top); cairo_scale(cr, 1, ninepatch->__sy); cairo_set_source_surface(cr, ninepatch->lm, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_paint_with_alpha(cr, object->alpha); cairo_restore(cr); } if(ninepatch->mm) { cairo_save(cr); cairo_translate(cr, ninepatch->left, ninepatch->top); cairo_scale(cr, ninepatch->__sx, ninepatch->__sy); cairo_set_source_surface(cr, ninepatch->mm, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_paint_with_alpha(cr, object->alpha); cairo_restore(cr); } if(ninepatch->rm) { cairo_save(cr); cairo_translate(cr, ninepatch->__w - ninepatch->right, ninepatch->top); cairo_scale(cr, 1, ninepatch->__sy); cairo_set_source_surface(cr, ninepatch->rm, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_paint_with_alpha(cr, object->alpha); cairo_restore(cr); } if(ninepatch->lb) { cairo_save(cr); cairo_translate(cr, 0, ninepatch->__h - ninepatch->bottom); cairo_set_source_surface(cr, ninepatch->lb, 0, 0); cairo_paint_with_alpha(cr, object->alpha); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_restore(cr); } if(ninepatch->mb) { cairo_save(cr); cairo_translate(cr, ninepatch->left, ninepatch->__h - ninepatch->bottom); cairo_scale(cr, ninepatch->__sx, 1); cairo_set_source_surface(cr, ninepatch->mb, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_paint_with_alpha(cr, object->alpha); cairo_restore(cr); } if(ninepatch->rb) { cairo_save(cr); cairo_translate(cr, ninepatch->__w - ninepatch->right, ninepatch->__h - ninepatch->bottom); cairo_set_source_surface(cr, ninepatch->rb, 0, 0); cairo_paint_with_alpha(cr, object->alpha); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_restore(cr); } cairo_restore(cr); return 0; }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* cr = context->platformContext(); cairo_save(cr); cairo_set_scaled_font(cr, font->platformData().scaledFont()); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); float offset = 0.0f; for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = 0.0f; offset += glyphBuffer.advanceAt(from + i); } Color fillColor = context->fillColor(); // Synthetic Oblique if(font->platformData().syntheticOblique()) { cairo_matrix_t mat = {1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, point.x(), point.y()}; cairo_transform(cr, &mat); } else { cairo_translate(cr, point.x(), point.y()); } // Text shadow, inspired by FontMac FloatSize shadowOffset; float shadowBlur = 0; Color shadowColor; bool hasShadow = context->textDrawingMode() & cTextFill && context->getShadow(shadowOffset, shadowBlur, shadowColor); // TODO: Blur support if (hasShadow) { // Disable graphics context shadows (not yet implemented) and paint them manually context->clearShadow(); Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); cairo_save(cr); float red, green, blue, alpha; shadowFillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); #if ENABLE(FILTERS) cairo_text_extents_t extents; cairo_scaled_font_glyph_extents(font->platformData().scaledFont(), glyphs, numGlyphs, &extents); FloatRect rect(FloatPoint(), FloatSize(extents.width, extents.height)); IntSize shadowBufferSize; FloatRect shadowRect; float radius = 0; context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur); // Draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); GraphicsContext* shadowContext = shadowBuffer->context(); cairo_t* shadowCr = shadowContext->platformContext(); cairo_translate(shadowCr, radius, extents.height + radius); cairo_set_scaled_font(shadowCr, font->platformData().scaledFont()); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(shadowCr); cairo_translate(shadowCr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); cairo_restore(shadowCr); } cairo_translate(cr, 0.0, -extents.height); context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); #else cairo_translate(cr, shadowOffset.width(), shadowOffset.height()); cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } #endif cairo_restore(cr); } if (context->textDrawingMode() & cTextFill) { if (context->fillGradient()) { cairo_set_source(cr, context->fillGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->fillPattern()) { AffineTransform affine; cairo_pattern_t* pattern = context->fillPattern()->createPlatformPattern(affine); cairo_set_source(cr, pattern); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } cairo_pattern_destroy(pattern); } else { float red, green, blue, alpha; fillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } } // Prevent running into a long computation within cairo. If the stroke width is // twice the size of the width of the text we will not ask cairo to stroke // the text as even one single stroke would cover the full wdth of the text. // See https://bugs.webkit.org/show_bug.cgi?id=33759. if (context->textDrawingMode() & cTextStroke && context->strokeThickness() < 2 * offset) { if (context->strokeGradient()) { cairo_set_source(cr, context->strokeGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->strokePattern()) { AffineTransform affine; cairo_pattern_t* pattern = context->strokePattern()->createPlatformPattern(affine); cairo_set_source(cr, pattern); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } cairo_pattern_destroy(pattern); } else { Color strokeColor = context->strokeColor(); float red, green, blue, alpha; strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_glyph_path(cr, glyphs, numGlyphs); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Re-enable the platform shadow we disabled earlier if (hasShadow) context->setShadow(shadowOffset, shadowBlur, shadowColor, DeviceColorSpace); cairo_restore(cr); }
static void render (cairo_t *pCairoContext, CairoDesklet *pDesklet) { CDPanelParameters *pPanel = (CDPanelParameters *) pDesklet->pRendererData; //g_print ("%s(%x)\n", __func__, pPanel); if (pPanel == NULL) return ; double fRadius = pPanel->iRadius; double fLineWidth = pPanel->iLineWidth; double fOffsetX = fRadius + fLineWidth/2; double fOffsetY = fLineWidth/2; double fFrameWidth = pDesklet->container.iWidth - 2 * fRadius - fLineWidth; double fFrameHeight = pDesklet->container.iHeight - fLineWidth; // le cadre. cairo_set_line_width (pCairoContext, pPanel->iLineWidth); cairo_move_to (pCairoContext, fOffsetX, fOffsetY); cairo_rel_curve_to (pCairoContext, fFrameWidth/2, 0, fFrameWidth/2, pPanel->iMainIconSize, fFrameWidth, pPanel->iMainIconSize); //\_________________ Coin haut droit. cairo_rel_curve_to (pCairoContext, 0, 0, fRadius, 0, fRadius, fRadius); cairo_rel_line_to (pCairoContext, 0, fFrameHeight - fRadius * 2 - pPanel->iMainIconSize); //\_________________ Coin bas droit. cairo_rel_curve_to (pCairoContext, 0, 0, 0, fRadius, -fRadius, fRadius); cairo_rel_line_to (pCairoContext, - fFrameWidth, 0); //\_________________ Coin bas gauche. cairo_rel_curve_to (pCairoContext, 0, 0, -fRadius, 0, -fRadius, - fRadius); cairo_rel_line_to (pCairoContext, 0, - (fFrameHeight - fRadius * 2)); //\_________________ Coin haut gauche. cairo_rel_curve_to (pCairoContext, 0, 0, 0, -fRadius, fRadius, -fRadius); cairo_set_source_rgba (pCairoContext, pPanel->fBgColor[0], pPanel->fBgColor[1], pPanel->fBgColor[2], 1.); cairo_stroke_preserve (pCairoContext); cairo_set_source_rgba (pCairoContext, pPanel->fBgColor[0], pPanel->fBgColor[1], pPanel->fBgColor[2], pPanel->fBgColor[3]); cairo_fill (pCairoContext); // les icones. Icon *pIcon; GList *ic; pIcon = pDesklet->pIcon; if (pIcon && pIcon->image.pSurface != NULL) { cairo_save (pCairoContext); cairo_translate (pCairoContext, pIcon->fDrawX, pIcon->fDrawY); cairo_dock_apply_image_buffer_surface_with_offset (&pIcon->image, pCairoContext, 0, 0, pIcon->fAlpha); cairo_dock_draw_icon_overlays_cairo (pIcon, pDesklet->container.fRatio, pCairoContext); cairo_restore (pCairoContext); } GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDesklet->icons); if (pFirstDrawnElement == NULL) return; ic = pFirstDrawnElement; do { pIcon = ic->data; if (pIcon->image.pSurface != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { cairo_save (pCairoContext); cairo_translate (pCairoContext, pIcon->fDrawX, pIcon->fDrawY); cairo_dock_apply_image_buffer_surface_with_offset (&pIcon->image, pCairoContext, 0, 0, pIcon->fAlpha); if (pIcon->label.pSurface != NULL) { cairo_save (pCairoContext); double fOffsetX = 0., fAlpha; if (pIcon->bPointed) { fAlpha = 1.; /**if (pIcon->fDrawX + pIcon->fWidth/2 + pIcon->label.iWidth/2 > pDesklet->container.iWidth) fOffsetX = pDesklet->container.iWidth - (pIcon->fDrawX + pIcon->fWidth/2 + pIcon->label.iWidth/2); if (pIcon->fDrawX + pIcon->fWidth/2 - pIcon->label.iWidth/2 < 0) fOffsetX = pIcon->label.iWidth/2 - (pIcon->fDrawX + pIcon->fWidth/2); cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX + pIcon->fWidth/2 - pIcon->label.iWidth/2, -myIconsParam.iLabelSize);*/ cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, 0., -myIconsParam.iLabelSize); cairo_paint_with_alpha (pCairoContext, fAlpha); } else { fAlpha = .6; if (pIcon->label.iWidth > 2*pIcon->fWidth + 0 * myIconsParam.iLabelSize) { ///fOffsetX = - myIconsParam.iLabelSize; cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (fOffsetX, 0., fOffsetX + 2*pIcon->fWidth + 0*myIconsParam.iLabelSize, 0.); cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0., 0., 0., 0., fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.75, 0., 0., 0., fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 1., 0., 0., 0., 0.); cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX, -myIconsParam.iLabelSize); cairo_mask (pCairoContext, pGradationPattern); cairo_pattern_destroy (pGradationPattern); } else { ///fOffsetX = pIcon->fWidth/2 - pIcon->label.iWidth/2; cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX, -myIconsParam.iLabelSize); cairo_paint_with_alpha (pCairoContext, fAlpha); } } cairo_restore (pCairoContext); } cairo_translate (pCairoContext, pIcon->fWidth, - pIcon->fHeight/2); // not ideal, it should be vertically centered. cairo_dock_draw_icon_overlays_cairo (pIcon, pDesklet->container.fRatio, pCairoContext); cairo_restore (pCairoContext); } ic = cairo_dock_get_next_element (ic, pDesklet->icons); } while (ic != pFirstDrawnElement); }
static gboolean screen_saver_floater_do_draw (ScreenSaver *screen_saver, ScreenSaverFloater *floater, cairo_t *context) { gint size; CachedSource *source; size = CLAMP ((int) (FLOATER_MAX_SIZE * floater->scale), FLOATER_MIN_SIZE, FLOATER_MAX_SIZE); source = g_hash_table_lookup (screen_saver->cached_sources, GINT_TO_POINTER (size)); if (source == NULL) { GdkPixbuf *pixbuf; GError *error; pixbuf = NULL; error = NULL; pixbuf = gdk_pixbuf_new_from_file_at_size (screen_saver->filename, size, -1, &error); if (pixbuf == NULL) { g_assert (error != NULL); g_printerr ("%s", _(error->message)); g_error_free (error); return FALSE; } if (gdk_pixbuf_get_has_alpha (pixbuf)) gamma_correct (pixbuf); gdk_cairo_set_source_pixbuf (context, pixbuf, 0.0, 0.0); source = cached_source_new (cairo_get_source (context), gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); g_object_unref (pixbuf); g_hash_table_insert (screen_saver->cached_sources, GINT_TO_POINTER (size), source); } cairo_save (context); if (screen_saver->should_do_rotations && (abs (floater->angle) > G_MINDOUBLE)) { floater->bounds.width = G_SQRT2 * source->width + 2; floater->bounds.height = G_SQRT2 * source->height + 2; floater->bounds.x = (int) (floater->position.x - .5 * G_SQRT2 * source->width) - 1; floater->bounds.y = (int) (floater->position.y - .5 * G_SQRT2 * source->height) - 1; cairo_translate (context, trunc (floater->position.x), trunc (floater->position.y)); cairo_rotate (context, floater->angle); cairo_translate (context, -trunc (floater->position.x), -trunc (floater->position.y)); } else { floater->bounds.width = source->width + 2; floater->bounds.height = source->height + 2; floater->bounds.x = (int) (floater->position.x - .5 * source->width) - 1; floater->bounds.y = (int) (floater->position.y - .5 * source->height) - 1; } cairo_translate (context, trunc (floater->position.x - .5 * source->width), trunc (floater->position.y - .5 * source->height)); cairo_set_source (context, source->pattern); cairo_rectangle (context, trunc (.5 * (source->width - floater->bounds.width)), trunc (.5 * (source->height - floater->bounds.height)), floater->bounds.width, floater->bounds.height); cairo_clip (context); cairo_paint_with_alpha (context, floater->opacity); cairo_restore (context); if (screen_saver->should_show_paths && (floater->path != NULL)) { gdouble dash_pattern[] = { 5.0 }; gint size; size = CLAMP ((int) (FLOATER_MAX_SIZE * floater->path_start_scale), FLOATER_MIN_SIZE, FLOATER_MAX_SIZE); cairo_save (context); cairo_set_source_rgba (context, 1.0, 1.0, 1.0, .2 * floater->opacity); cairo_move_to (context, floater->path->start_point.x, floater->path->start_point.y); cairo_curve_to (context, floater->path->start_control_point.x, floater->path->start_control_point.y, floater->path->end_control_point.x, floater->path->end_control_point.y, floater->path->end_point.x, floater->path->end_point.y); cairo_set_line_cap (context, CAIRO_LINE_CAP_ROUND); cairo_stroke (context); cairo_set_source_rgba (context, 1.0, 0.0, 0.0, .5 * floater->opacity); cairo_rectangle (context, floater->path->start_point.x - 3, floater->path->start_point.y - 3, 6, 6); cairo_fill (context); cairo_set_source_rgba (context, 0.0, 0.5, 0.0, .5 * floater->opacity); cairo_arc (context, floater->path->start_control_point.x, floater->path->start_control_point.y, 3, 0.0, 2.0 * G_PI); cairo_stroke (context); cairo_set_source_rgba (context, 0.5, 0.0, 0.5, .5 * floater->opacity); cairo_arc (context, floater->path->end_control_point.x, floater->path->end_control_point.y, 3, 0.0, 2.0 * G_PI); cairo_stroke (context); cairo_set_source_rgba (context, 0.0, 0.0, 1.0, .5 * floater->opacity); cairo_rectangle (context, floater->path->end_point.x - 3, floater->path->end_point.y - 3, 6, 6); cairo_fill (context); cairo_set_dash (context, dash_pattern, G_N_ELEMENTS (dash_pattern), 0); cairo_set_source_rgba (context, .5, .5, .5, .2 * floater->scale); cairo_move_to (context, floater->path->start_point.x, floater->path->start_point.y); cairo_line_to (context, floater->path->start_control_point.x, floater->path->start_control_point.y); cairo_stroke (context); cairo_move_to (context, floater->path->end_point.x, floater->path->end_point.y); cairo_line_to (context, floater->path->end_control_point.x, floater->path->end_control_point.y); cairo_stroke (context); cairo_restore (context); } return TRUE; }
void gfxContext::Paint(gfxFloat alpha) { cairo_paint_with_alpha(mCairo, alpha); }
gboolean cd_slider_fade_in_out (GldiModuleInstance *myApplet) { myData.iAnimCNT ++; if (myData.iAnimCNT <= myConfig.iNbAnimationStep) // courbe de alpha : \__/ myData.fAnimAlpha = 1. * (myConfig.iNbAnimationStep - myData.iAnimCNT) / myConfig.iNbAnimationStep; else if (myData.iAnimCNT <= 1.5 * myConfig.iNbAnimationStep) { return TRUE; // on ne fait rien, texture inchangee. } else myData.fAnimAlpha = 1. * (myData.iAnimCNT - 1.5 * myConfig.iNbAnimationStep) / myConfig.iNbAnimationStep; if (CD_APPLET_MY_CONTAINER_IS_OPENGL) { CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN (FALSE); if (myData.iAnimCNT < myConfig.iNbAnimationStep && myData.iPrevTexture != 0) // image precedente en train de disparaitre { //On empeche la transparence _cd_slider_add_background_to_prev_slide_opengl (myApplet, 0., 0., myData.fAnimAlpha); //Image glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f (1., 1., 1., myData.fAnimAlpha); cairo_dock_apply_texture_at_size (myData.iPrevTexture, myData.prevSlideArea.fImgW, myData.prevSlideArea.fImgH); } else if (myData.iAnimCNT > myConfig.iNbAnimationStep) // image courante en train d'apparaitre. { //On empeche la transparence _cd_slider_add_background_to_current_slide_opengl (myApplet, 0., 0., myData.fAnimAlpha); //Image glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f (1., 1., 1., myData.fAnimAlpha); cairo_dock_apply_texture_at_size (myData.iTexture, myData.slideArea.fImgW, myData.slideArea.fImgH); } glDisable (GL_TEXTURE_2D); glDisable (GL_BLEND); CD_APPLET_FINISH_DRAWING_MY_ICON; } else { CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN_CAIRO (FALSE); //On efface le fond ///_cd_slider_erase_surface (myApplet); if (myData.iAnimCNT < myConfig.iNbAnimationStep) // image precedente en train de disparaitre { //On empeche la transparence _cd_slider_add_background_to_prev_slide (myApplet, myData.prevSlideArea.fImgX, myData.prevSlideArea.fImgY, myData.fAnimAlpha); //Image cairo_set_source_surface (myDrawContext, myData.pPrevCairoSurface, myData.prevSlideArea.fImgX, myData.prevSlideArea.fImgY); } else if (myData.iAnimCNT > myConfig.iNbAnimationStep) // image courante en train d'apparaitre. { //On empeche la transparence _cd_slider_add_background_to_current_slide (myApplet, myData.slideArea.fImgX, myData.slideArea.fImgY, myData.fAnimAlpha); //Image cairo_set_source_surface (myDrawContext, myData.pCairoSurface, myData.slideArea.fImgX, myData.slideArea.fImgY); } cairo_paint_with_alpha (myDrawContext, myData.fAnimAlpha); CD_APPLET_FINISH_DRAWING_MY_ICON_CAIRO; } return (myData.fAnimAlpha < .99); }
cairo_surface_t * gb_widget_snapshot (GtkWidget *widget, gint width, gint height, gdouble alpha, gboolean draw_border) { cairo_surface_t *surface; GtkAllocation alloc; gdouble x_ratio = 1.0; gdouble y_ratio = 1.0; cairo_t *cr; /* * XXX: This function conflates the drawing of borders and snapshoting. * Totally not ideal, but we can clean that up later. */ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); gtk_widget_get_allocation (widget, &alloc); if ((width != alloc.width) || (height != alloc.height)) { if (alloc.width > alloc.height) { x_ratio = (gdouble) width / (gdouble) alloc.width; y_ratio = (gdouble) width / (gdouble) alloc.width; } else { x_ratio = (gdouble) height / (gdouble) alloc.height; y_ratio = (gdouble) height / (gdouble) alloc.height; } cairo_scale (cr, x_ratio, y_ratio); } gtk_widget_draw (widget, cr); cairo_destroy (cr); { cairo_surface_t *other; GdkRectangle rect = { 3, 3, ceil (alloc.width * x_ratio) - 6, ceil (alloc.height * y_ratio) - 6 }; other = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (other); cairo_save (cr); if (draw_border) { gdk_cairo_rectangle (cr, &rect); cairo_clip (cr); } cairo_set_source_surface (cr, surface, 0, 0); cairo_paint_with_alpha (cr, alpha); cairo_restore (cr); if (draw_border) { GdkRGBA rgba; gb_cairo_rounded_rectangle (cr, &rect, 3, 3); gdk_rgba_parse (&rgba, "#729fcf"); gb_rgba_shade (&rgba, &rgba, 0.8); gdk_cairo_set_source_rgba (cr, &rgba); cairo_set_line_width (cr, 3.0); cairo_stroke (cr); gb_cairo_rounded_rectangle (cr, &rect, 1, 1); gdk_rgba_parse (&rgba, "#729fcf"); gb_rgba_shade (&rgba, &rgba, 1.2); gdk_cairo_set_source_rgba (cr, &rgba); cairo_set_line_width (cr, 1.0); cairo_stroke (cr); } cairo_surface_destroy (surface); surface = other; } return surface; }
int draw(tr_params * render) { fontface * face = NULL; cairo_surface_t * sub_surface; cairo_t * sub_context; cairo_status_t status; cairo_text_extents_t text_extents, help_extents; int stride; cairo_matrix_t matrix; double elapsed; #ifdef __linux struct timespec tp_start, tp_end; #else clock_t start, end; #endif #ifdef __linux clock_gettime(CLOCK_REALTIME, &tp_start); #else start = clock(); #endif if ( render->text == NULL || strlen(render->text) == 0 ) { fwrite(nullpng, 1, sizeof(nullpng), stdout); return 0; } if ( render->font != NULL ) face = hash_get(faces, render->font); if ( face == NULL ) face = hash_get(faces, "__DEFAULT__"); cairo_set_font_size(main_context, render->size); cairo_set_font_face(main_context, face->cface); // the help parameter will probably alter the text to draw, so let's check it first if ( render->help != NULL && strncmp(render->help, "debug", sizeof("debug")) != 0 ) render->text = help_text(render); // how big will the rendered text be? cairo_text_extents(main_context, render->text, &text_extents); // we'll might also need to know the extents of the help text if ( render->help != NULL && strncmp(render->help, "debug", sizeof("debug")) == 0 ) cairo_text_extents(main_context, help_text(render), &help_extents); // since Cairo origins it's draw from the lower-left (for l2r text) we have to adjust y if ( render->y == _DEFAULT_Y ) render->y = text_extents.height; // TODO - if helptext, grow render w and h as needed... // 1.06 is a swizzle factor to compensate for the incorrect extents cairo produces if ( render->w == _DEFAULT_WIDTH ) { render->w = ceil(render->x) + ceil(text_extents.width * 1.06); } if ( render->h == _DEFAULT_HEIGHT ) { render->h = ceil(render->y) + ceil(text_extents.height); } stride = cairo_image_surface_get_stride(main_surface); // we know how big the image will be, create our sub_surface from the main_surface sub_surface = cairo_image_surface_create_for_data(cairo_image_surface_get_data(main_surface), CAIRO_FORMAT_ARGB32, render->w, render->h, stride); sub_context = cairo_create(sub_surface); // Remember, this is a new surface that just happens to share the same // buffer as main_surface so we have to set the font size and face for it cairo_set_font_size(sub_context, render->size); cairo_set_font_face(sub_context, face->cface); // clear the buffer of left-over data cairo_set_operator(sub_context, CAIRO_OPERATOR_CLEAR); cairo_paint(sub_context); // And now we're ready to draw! cairo_set_operator(sub_context, CAIRO_OPERATOR_OVER); // do we need to show a background color? if ( render->bgr != 0.0 || render->bgg != 0.0 || render->bgb != 0.0 || render->bga != 0.0 ) { cairo_set_source_rgba(sub_context, render->bgr, render->bgg, render->bgb, render->bga); cairo_paint_with_alpha(sub_context, render->bga); } // set text color cairo_set_source_rgba(sub_context, render->r, render->g, render->b, render->a); cairo_move_to(sub_context, render->x, render->y); /* // TODO: rotation currently rotates around the upper-left corner, fix to rotate around text center if ( render->th != 0.0 ) { cairo_get_font_matrix(sub_context, &matrix); cairo_matrix_rotate(&matrix, render->th); cairo_set_font_matrix(sub_context, &matrix); } */ cairo_show_text(sub_context, render->text); // if we're set to debug, we'll have attempted a render above, and now we draw a parameters placard if ( render->help != NULL && (strncmp(render->help, "debug", sizeof("debug")) == 0) ) { // half-transparent black fill cairo_set_source_rgba(sub_context, 0, 0, 0, 1.0); cairo_paint_with_alpha(sub_context, 0.5); face = hash_get(faces, "__DEFAULT__"); cairo_set_font_face(sub_context, face->cface); cairo_set_font_size(sub_context, 12); cairo_move_to(sub_context, 0, 12); cairo_set_source_rgba(sub_context, 1, 1, 1, 1.0); cairo_show_text(sub_context, help_text(render)); } status = cairo_surface_write_to_png_stream(sub_surface, FCGI_cairo_write_stream, NULL); cairo_destroy(sub_context); cairo_surface_destroy(sub_surface); #ifdef __linux clock_gettime(CLOCK_REALTIME, &tp_end); elapsed = tp_end.tv_sec - tp_start.tv_sec; elapsed += (tp_end.tv_nsec - tp_start.tv_nsec)/1000000000.0; #else end = clock(); elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; #endif // fprintf(stderr, "elapsed: %.3fms", elapsed*1000); // logging }
void wxSVGCanvasCairo::DrawCanvasImage(wxSVGCanvasImage& canvasImage, cairo_surface_t* cairoSurface, wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem) { if (cairoSurface == NULL) return; cairo_save(m_cr); // ClipPath if (style.GetClipPath().GetCSSPrimitiveType() == wxCSS_URI && style.GetClipPath().GetStringValue().length() > 1) { wxString clipPathId = style.GetClipPath().GetStringValue().substr(1); wxSVGClipPathElement* clipPathElem = (wxSVGClipPathElement*) svgElem.GetElementById(clipPathId); if (clipPathElem && clipPathElem->GetDtd() == wxSVG_CLIPPATH_ELEMENT) { clipPathElem->SetOwnerSVGElement(&svgElem); clipPathElem->SetViewportElement(&svgElem); wxSVGMatrix clipMatrix(matrix); clipPathElem->UpdateMatrix(clipMatrix); SetClipPath(clipPathElem, clipMatrix); } } SetMatrix(m_cr, matrix); // scale context double x = canvasImage.m_x; double y = canvasImage.m_y; double scaleX = canvasImage.m_width / canvasImage.m_image.GetWidth(); double scaleY = canvasImage.m_height / canvasImage.m_image.GetHeight(); wxSVG_PRESERVEASPECTRATIO align = canvasImage.GetPreserveAspectRatio().GetAlign(); bool alignX = false; if (align > wxSVG_PRESERVEASPECTRATIO_NONE) { scaleY = canvasImage.m_height / canvasImage.GetDefaultHeight(); if (canvasImage.GetPreserveAspectRatio().GetMeetOrSlice() != wxSVG_MEETORSLICE_SLICE) { alignX = scaleX > scaleY; } else { cairo_rectangle(m_cr, x, y, canvasImage.m_width, canvasImage.m_height); cairo_clip(m_cr); alignX = scaleX < scaleY; } if (alignX) { scaleX = scaleY; if (align == wxSVG_PRESERVEASPECTRATIO_XMIDYMIN || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMID || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMAX) x += (canvasImage.m_width - canvasImage.GetDefaultWidth() * scaleX) / 2; else if (align == wxSVG_PRESERVEASPECTRATIO_XMAXYMIN || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMID || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMAX) x += canvasImage.m_width - canvasImage.GetDefaultWidth() * scaleX; } else { scaleY = scaleX; if (align == wxSVG_PRESERVEASPECTRATIO_XMINYMID || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMID || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMID) y += (canvasImage.m_height - canvasImage.GetDefaultHeight() * scaleY) / 2; else if (align == wxSVG_PRESERVEASPECTRATIO_XMINYMAX || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMAX || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMAX) y += canvasImage.m_height - canvasImage.GetDefaultHeight() * scaleY; } scaleY = scaleY * canvasImage.GetDefaultHeight() / canvasImage.m_image.GetHeight(); } cairo_translate(m_cr, x, y); cairo_scale(m_cr, scaleX, scaleY); // prepare to draw the image cairo_set_source_surface(m_cr, cairoSurface, 0, 0); // use the original size here since the context is scaled already... cairo_rectangle(m_cr, 0, 0, canvasImage.m_image.GetWidth(), canvasImage.m_image.GetHeight()); // paint if (style.GetMask().GetCSSPrimitiveType() == wxCSS_URI && style.GetMask().GetStringValue().length() > 1) { wxString maskId = style.GetMask().GetStringValue().substr(1); wxSVGMaskElement* maskElem = (wxSVGMaskElement*) svgElem.GetElementById(maskId); if (maskElem && maskElem->GetDtd() == wxSVG_MASK_ELEMENT) { maskElem->SetOwnerSVGElement(&svgElem); maskElem->SetViewportElement(&svgElem); cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, svgElem.GetWidth().GetAnimVal()/scaleX, svgElem.GetHeight().GetAnimVal()/scaleY); cairo_t* cr = cairo_create(surface); wxSVGMatrix maskMatrix; maskMatrix = maskMatrix.Translate(x, y).ScaleNonUniform(scaleX, scaleY).Inverse(); DrawMask(cr, maskElem, maskMatrix, style, svgElem); cairo_mask_surface(m_cr, surface, 0, 0); cairo_destroy(cr); cairo_surface_destroy(surface); } } else { cairo_paint_with_alpha(m_cr, style.GetOpacity()); } cairo_new_path(m_cr); // clean up cairo_restore(m_cr); }
XfsmFadeout* xfsm_fadeout_new (GdkDisplay *display) { GdkWindowAttr attr; XfsmFadeout *fadeout; GdkWindow *root; GdkCursor *cursor; FoScreen *screen; cairo_t *cr; GList *lp; gint width; gint height; gint n; fadeout = g_new0 (XfsmFadeout, 1); gdk_color_parse (COLOR, &fadeout->color); cursor = gdk_cursor_new (GDK_WATCH); attr.x = 0; attr.y = 0; attr.event_mask = 0; attr.wclass = GDK_INPUT_OUTPUT; attr.window_type = GDK_WINDOW_TEMP; attr.cursor = cursor; attr.override_redirect = TRUE; for (n = 0; n < gdk_display_get_n_screens (display); ++n) { GdkPixbuf *root_pixbuf; screen = g_new (FoScreen, 1); root = gdk_screen_get_root_window (gdk_display_get_screen (display, n)); gdk_drawable_get_size (GDK_DRAWABLE (root), &width, &height); screen->backbuf = gdk_pixmap_new (GDK_DRAWABLE (root), width, height, -1); /* Copy the root window */ root_pixbuf = gdk_pixbuf_get_from_drawable (NULL, GDK_DRAWABLE (root), NULL, 0, 0, 0, 0, width, height); cr = gdk_cairo_create (GDK_DRAWABLE (screen->backbuf)); gdk_cairo_set_source_pixbuf (cr, root_pixbuf, 0, 0); cairo_paint (cr); gdk_cairo_set_source_color (cr, &fadeout->color); cairo_paint_with_alpha (cr, 0.5); attr.width = width; attr.height = height; screen->window = gdk_window_new (root, &attr, GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR | GDK_WA_CURSOR); gdk_window_set_back_pixmap (screen->window, screen->backbuf, FALSE); g_object_unref (root_pixbuf); cairo_destroy (cr); fadeout->screens = g_list_append (fadeout->screens, screen); } for (lp = fadeout->screens; lp != NULL; lp = lp->next) gdk_window_show (((FoScreen *) lp->data)->window); gdk_cursor_unref (cursor); return fadeout; }
static void render (cairo_t *pCairoContext, CairoDesklet *pDesklet) { CDSlideParameters *pSlide = (CDSlideParameters *) pDesklet->pRendererData; //g_print ("%s(%x)\n", __func__, pSlide); if (pSlide == NULL) return ; double fRadius = pSlide->iRadius; double fLineWidth = pSlide->iLineWidth; // le cadre. cairo_set_line_width (pCairoContext, pSlide->iLineWidth); if (pSlide->bRoundedRadius) { cairo_translate (pCairoContext, 0., .5 * fLineWidth); cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, pDesklet->container.iWidth - 2 * fRadius - fLineWidth, pDesklet->container.iHeight - 2*fLineWidth); } else { cairo_move_to (pCairoContext, 0., 0.); cairo_rel_line_to (pCairoContext, 0., pDesklet->container.iHeight - fRadius - fLineWidth); cairo_rel_line_to (pCairoContext, pSlide->iRadius, pSlide->iRadius); cairo_rel_line_to (pCairoContext, pDesklet->container.iWidth - fRadius - fLineWidth, 0.); } cairo_set_source_rgba (pCairoContext, pSlide->fLineColor[0], pSlide->fLineColor[1], pSlide->fLineColor[2], pSlide->fLineColor[3]); cairo_stroke (pCairoContext); // les icones. double w = pDesklet->container.iWidth - 2 * pSlide->fMargin; double h = pDesklet->container.iHeight - 2 * pSlide->fMargin; int dh = (h - pSlide->iNbLines * (pSlide->iIconSize + myIconsParam.iLabelSize)) / (pSlide->iNbLines != 1 ? pSlide->iNbLines - 1 : 1); // ecart entre 2 lignes. int dw = (w - pSlide->iNbColumns * pSlide->iIconSize) / pSlide->iNbColumns; // ecart entre 2 colonnes. // on determine la 1ere icone a tracer : l'icone suivant l'icone pointee. double x = pSlide->fMargin + dw/2, y = pSlide->fMargin + myIconsParam.iLabelSize; int q = 0; Icon *pIcon; GList *ic; for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) continue; pIcon->fDrawX = x; pIcon->fDrawY = y; x += pSlide->iIconSize + dw; q ++; if (q == pSlide->iNbColumns) { q = 0; x = pSlide->fMargin + dw/2; y += pSlide->iIconSize + myIconsParam.iLabelSize + dh; } } GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDesklet->icons); if (pFirstDrawnElement == NULL) return; ic = pFirstDrawnElement; do { pIcon = ic->data; if (pIcon->image.pSurface != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { cairo_save (pCairoContext); cairo_dock_render_one_icon_in_desklet (pIcon, CAIRO_CONTAINER (pDesklet), pCairoContext, FALSE); cairo_restore (pCairoContext); if (pIcon->label.pSurface != NULL) { cairo_save (pCairoContext); cairo_translate (pCairoContext, pIcon->fDrawX, pIcon->fDrawY); double fOffsetX = 0., fAlpha; if (pIcon->bPointed) { fAlpha = 1.; if (pIcon->fDrawX + pIcon->fWidth/2 + pIcon->label.iWidth/2 > pDesklet->container.iWidth) fOffsetX = pDesklet->container.iWidth - (pIcon->fDrawX + pIcon->fWidth/2 + pIcon->label.iWidth/2); if (pIcon->fDrawX + pIcon->fWidth/2 - pIcon->label.iWidth/2 < 0) fOffsetX = pIcon->label.iWidth/2 - (pIcon->fDrawX + pIcon->fWidth/2); cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX + pIcon->fWidth/2 - pIcon->label.iWidth/2, -myIconsParam.iLabelSize); cairo_paint_with_alpha (pCairoContext, fAlpha); } else { fAlpha = .6; if (pIcon->label.iWidth > pIcon->fWidth + 2 * myIconsParam.iLabelSize) { fOffsetX = - myIconsParam.iLabelSize; cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (fOffsetX, 0., fOffsetX + pIcon->fWidth + 2*myIconsParam.iLabelSize, 0.); cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0., 0., 0., 0., fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.75, 0., 0., 0., fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 1., 0., 0., 0., 0.); cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX, -myIconsParam.iLabelSize); cairo_mask (pCairoContext, pGradationPattern); cairo_pattern_destroy (pGradationPattern); } else { fOffsetX = pIcon->fWidth/2 - pIcon->label.iWidth/2; cairo_set_source_surface (pCairoContext, pIcon->label.pSurface, fOffsetX, -myIconsParam.iLabelSize); cairo_paint_with_alpha (pCairoContext, fAlpha); } } cairo_restore (pCairoContext); } } ic = cairo_dock_get_next_element (ic, pDesklet->icons); } while (ic != pFirstDrawnElement); }
task_item_expose_event (GtkWidget *widget, GdkEventExpose *event) #endif { #if !GTK_CHECK_VERSION (3, 0, 0) cairo_t *cr; #endif TaskItem *item; GdkRectangle area; TaskItemPrivate *priv; GdkPixbuf *desat; GdkPixbuf *pbuf; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (TASK_IS_ITEM (widget), FALSE); #if !GTK_CHECK_VERSION (3, 0, 0) g_return_val_if_fail (event != NULL, FALSE); #endif item = TASK_ITEM (widget); priv = item->priv; g_return_val_if_fail (WNCK_IS_WINDOW (priv->window), FALSE); area = priv->area; #if !GTK_CHECK_VERSION (3, 0, 0) cr = gdk_cairo_create (event->window); #endif pbuf = priv->pixbuf; desat = NULL; gint size = MIN (area.height, area.width); gboolean active = wnck_window_is_active (priv->window); gboolean attention = wnck_window_or_transient_needs_attention (priv->window); if (GDK_IS_PIXBUF (pbuf) && gdk_pixbuf_get_width (pbuf) != size && gdk_pixbuf_get_height (pbuf) != size) { g_object_unref (pbuf); pbuf = NULL; } if (active) { cairo_rectangle (cr, area.x + .5, area.y - 4, area.width - 1, area.height + 8); cairo_set_source_rgba (cr, .8, .8, .8, .2); cairo_fill_preserve (cr); cairo_set_line_width (cr, 1); cairo_set_source_rgba (cr, .8, .8, .8, .4); cairo_stroke (cr); } if (!pbuf) { pbuf = priv->pixbuf = task_item_sized_pixbuf_for_window (item, priv->window, size); } if (active || priv->mouse_over || attention) { gdk_cairo_set_source_pixbuf (cr, pbuf, (area.x + (area.width - gdk_pixbuf_get_width (pbuf)) / 2), (area.y + (area.height - gdk_pixbuf_get_height (pbuf)) / 2)); } else { desat = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, gdk_pixbuf_get_bits_per_sample (pbuf), gdk_pixbuf_get_width (pbuf), gdk_pixbuf_get_height (pbuf)); if (desat) { gdk_pixbuf_saturate_and_pixelate (pbuf, desat, 0, FALSE); } else /* just paint the colored version as a fallback */ { desat = pbuf; } gdk_cairo_set_source_pixbuf (cr, desat, (area.x + (area.width - gdk_pixbuf_get_width (desat)) / 2), (area.y + (area.height - gdk_pixbuf_get_height (desat)) / 2)); } if (!priv->mouse_over && attention) /* urgent */ { GTimeVal current_time; g_get_current_time (¤t_time); gdouble ms = (current_time.tv_sec - priv->urgent_time.tv_sec) * 1000 + (current_time.tv_usec - priv->urgent_time.tv_usec) / 1000; gdouble alpha = .66 + (cos (3.15 * ms / 600) / 3); cairo_paint_with_alpha (cr, alpha); } else if (priv->mouse_over || active) /* focused */ { cairo_paint (cr); } else /* not focused */ { cairo_paint_with_alpha (cr, .65); } if (GDK_IS_PIXBUF (desat)) g_object_unref (desat); #if !GTK_CHECK_VERSION (3, 0, 0) cairo_destroy (cr); #endif return FALSE; }
static gboolean widget_overlay_draw (GtkWidget *widget, cairo_t *cr) { WidgetOverlay *ovl = WIDGET_OVERLAY (widget); GdkWindow *window; GtkAllocation area; gtk_widget_get_allocation (widget, &area); window = gtk_widget_get_window (widget); if (gtk_cairo_should_draw_window (cr, window)) { GList *list; for (list = ovl->priv->children; list; list = list->next) { ChildData *cd = (ChildData*) list->data; if (gtk_widget_get_visible (cd->child)) { cairo_surface_t *surface; GtkAllocation child_area; double x, y; gtk_widget_get_allocation (cd->child, &child_area); child_area.width *= cd->scale; child_area.height *= cd->scale; switch (cd->halign) { case WIDGET_OVERLAY_ALIGN_FILL: case WIDGET_OVERLAY_ALIGN_START: x = 0; break; case WIDGET_OVERLAY_ALIGN_END: x = area.width - child_area.width; break; case WIDGET_OVERLAY_ALIGN_CENTER: x = (area.width - child_area.width) / 2.; break; } switch (cd->valign) { case WIDGET_OVERLAY_ALIGN_FILL: case WIDGET_OVERLAY_ALIGN_START: y = 0; break; case WIDGET_OVERLAY_ALIGN_END: y = area.height - child_area.height; break; case WIDGET_OVERLAY_ALIGN_CENTER: y = (area.height - child_area.height) / 2.; break; } surface = gdk_offscreen_window_get_surface (cd->offscreen_window); if (cd->scale == 1.) { cairo_set_source_surface (cr, surface, x, y); cairo_paint_with_alpha (cr, cd->alpha); } else { cairo_save (cr); cairo_scale (cr, cd->scale, cd->scale); cairo_set_source_surface (cr, surface, x/cd->scale, y/cd->scale); cairo_paint_with_alpha (cr, cd->alpha); cairo_restore (cr); } cd->x = x; cd->y = y; } if (list->next && ((ChildData*) list->next->data == ovl->priv->scale_child) && (ovl->priv->scale_child->alpha > 0.)) { cairo_set_source_rgba (cr, 0., 0., 0., .3); cairo_rectangle (cr, 0, 0, area.width, area.height); cairo_fill (cr); } } } else { GList *list; for (list = ovl->priv->children; list; list = list->next) { ChildData *cd = (ChildData*) list->data; if (gtk_cairo_should_draw_window (cr, cd->offscreen_window)) gtk_container_propagate_draw (GTK_CONTAINER (widget), cd->child, cr); } } return TRUE; }
void cairo_dock_render_overlays_to_context (CairoDataRenderer *pRenderer, int iNumValue, cairo_t *pCairoContext) { if (pRenderer->pEmblems != NULL) { CairoDataRendererEmblem *pEmblem; pEmblem = &pRenderer->pEmblems[iNumValue]; if (pEmblem->pSurface != NULL) { cairo_set_source_surface (pCairoContext, pEmblem->pSurface, (.5 + pEmblem->param.fX - pEmblem->param.fWidth/2) * pRenderer->iWidth, (.5 - pEmblem->param.fY - pEmblem->param.fHeight/2) * pRenderer->iHeight); cairo_paint_with_alpha (pCairoContext, pEmblem->param.fAlpha); } } if (pRenderer->pLabels != NULL) { CairoDataRendererText *pLabel; pLabel = &pRenderer->pLabels[iNumValue]; if (pLabel->pSurface != NULL) { double f = MIN (pLabel->param.fWidth * pRenderer->iWidth / pLabel->iTextWidth, pLabel->param.fHeight * pRenderer->iHeight / pLabel->iTextHeight); // on garde le ratio du texte. if (pLabel->iTextHeight * f > 7) // sinon illisible { cairo_save (pCairoContext); cairo_scale (pCairoContext, f, f); cairo_set_source_surface (pCairoContext, pLabel->pSurface, .5+floor ((.5 + pLabel->param.fX) * pRenderer->iWidth/f - pLabel->iTextWidth /2), .5+floor ((.5 - pLabel->param.fY) * pRenderer->iHeight/f - pLabel->iTextHeight /2)); cairo_paint_with_alpha (pCairoContext, pLabel->param.pColor[3]); cairo_restore (pCairoContext); } } } if (pRenderer->bWriteValues && pRenderer->bCanRenderValueAsText) { CairoDataRendererTextParam *pText; pText = &pRenderer->pValuesText[iNumValue]; if (pText->fWidth != 0 && pText->fHeight != 0) { cairo_data_renderer_format_value (pRenderer, iNumValue); cairo_save (pCairoContext); cairo_set_source_rgb (pCairoContext, pText->pColor[0], pText->pColor[1], pText->pColor[2]); PangoLayout *pLayout = pango_cairo_create_layout (pCairoContext); PangoFontDescription *fd = pango_font_description_from_string ("Monospace 12"); pango_layout_set_font_description (pLayout, fd); PangoRectangle log; pango_layout_set_text (pLayout, pRenderer->cFormatBuffer, -1); pango_layout_get_pixel_extents (pLayout, NULL, &log); double fZoom = MIN (pText->fWidth * pRenderer->iWidth / (log.width), pText->fHeight * pRenderer->iHeight / log.height); cairo_move_to (pCairoContext, floor ((.5 + pText->fX) * pRenderer->iWidth - log.width*fZoom/2), floor ((.5 - pText->fY) * pRenderer->iHeight - log.height*fZoom/2)); cairo_scale (pCairoContext, fZoom, fZoom); pango_cairo_show_layout (pCairoContext, pLayout); g_object_unref (pLayout); cairo_restore (pCairoContext); } } }
gboolean cd_drop_indicator_render (gpointer pUserData, CairoDock *pDock, cairo_t *pCairoContext) { CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock); if (pData == NULL) return GLDI_NOTIFICATION_LET_PASS; if (pCairoContext != NULL) { if (pData->fAlpha > 0) { cairo_save (pCairoContext); double fX = pDock->container.iMouseX - myData.dropIndicator.iWidth / 2; if (pDock->container.bIsHorizontal) cairo_rectangle (pCairoContext, (int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2, (int) (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight), (int) myData.dropIndicator.iWidth, (int) (pDock->container.bDirectionUp ? 2*myData.dropIndicator.iHeight : pDock->iActiveHeight)); else cairo_rectangle (pCairoContext, (int) (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iActiveHeight : pDock->iActiveHeight - 2*myData.dropIndicator.iHeight), (int) pDock->container.iMouseX - myData.dropIndicator.iWidth/2, (int) (pDock->container.bDirectionUp ? 2*myData.dropIndicator.iHeight : pDock->iActiveHeight), (int) myData.dropIndicator.iWidth); cairo_clip (pCairoContext); if (pDock->container.bIsHorizontal) cairo_translate (pCairoContext, fX, (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight)); else cairo_translate (pCairoContext, (pDock->container.bDirectionUp ? 0 : pDock->iActiveHeight), fX); double fRotationAngle = (pDock->container.bIsHorizontal ? (pDock->container.bDirectionUp ? 0 : G_PI) : (pDock->container.bDirectionUp ? -G_PI/2 : G_PI/2)); cairo_rotate (pCairoContext, fRotationAngle); cairo_translate (pCairoContext, 0, pData->iDropIndicatorOffset); cairo_pattern_t* pPattern = cairo_pattern_create_for_surface (myData.dropIndicator.pSurface); g_return_val_if_fail (cairo_pattern_status (pPattern) == CAIRO_STATUS_SUCCESS, GLDI_NOTIFICATION_LET_PASS); cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_REPEAT); cairo_set_source (pCairoContext, pPattern); cairo_translate (pCairoContext, 0, - pData->iDropIndicatorOffset); cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (0., 0., 0., 2*myData.dropIndicator.iHeight); // de haut en bas. g_return_val_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS, GLDI_NOTIFICATION_LET_PASS); cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0., 0., 0., 0., 0.); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.4, 0., 0., 0., pData->fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 0.5, 0., 0., 0., pData->fAlpha); cairo_pattern_add_color_stop_rgba (pGradationPattern, 1., 0., 0., 0., 0.); cairo_mask (pCairoContext, pGradationPattern); cairo_pattern_destroy (pPattern); cairo_pattern_destroy (pGradationPattern); cairo_restore (pCairoContext); } if (pData->fAlphaHover > 0 && myData.hoverIndicator.pSurface != NULL) { Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons); if (pIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { cairo_save (pCairoContext); if (pDock->container.bIsHorizontal) { cairo_translate (pCairoContext, pIcon->fDrawX + 2./3*pIcon->fWidth*pIcon->fScale, pIcon->fDrawY); // top right corner cairo_scale (pCairoContext, pIcon->fWidth*pIcon->fScale/3 / myData.hoverIndicator.iWidth, pIcon->fHeight*pIcon->fScale/3 / myData.hoverIndicator.iHeight); } else { cairo_translate (pCairoContext, pIcon->fDrawY + 2./3*pIcon->fWidth*pIcon->fScale, pIcon->fDrawX); cairo_scale (pCairoContext, pIcon->fHeight*pIcon->fScale/3 / myData.hoverIndicator.iWidth, pIcon->fWidth*pIcon->fScale/3 / myData.hoverIndicator.iHeight); } cairo_set_source_surface (pCairoContext, myData.hoverIndicator.pSurface, 0., 0.); cairo_paint_with_alpha (pCairoContext, pData->fAlphaHover); cairo_restore (pCairoContext); } } } else { if (pData->fAlpha > 0) { double fX = pDock->container.iMouseX; double fY = (pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : myData.dropIndicator.iHeight); glPushMatrix(); glLoadIdentity(); if (pDock->container.bIsHorizontal) { fX = pDock->container.iMouseX; fY = (pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : myData.dropIndicator.iHeight); glTranslatef (fX, fY, - myData.dropIndicator.iWidth-1.); if (! pDock->container.bDirectionUp) glScalef (1., -1., 1.); } else { fX = pDock->container.iWidth - pDock->container.iMouseX; fY = (! pDock->container.bDirectionUp ? pDock->iActiveHeight - myData.dropIndicator.iHeight : pDock->container.iHeight - pDock->iActiveHeight + myData.dropIndicator.iHeight); glTranslatef (fY, fX, - myData.dropIndicator.iWidth-1.); glRotatef ((pDock->container.bDirectionUp ? 90. : -90.), 0., 0., 1.); } glRotatef (pData->iDropIndicatorRotation, 0., 1., 0.); //\_________________ On decale la texture vers le bas. glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures glPushMatrix(); glLoadIdentity(); // On la reset glTranslatef(.0, - (double)pData->iDropIndicatorOffset / myData.dropIndicator.iHeight, 0.); glScalef (1., -2., 1.); glMatrixMode(GL_MODELVIEW); // On revient sur la matrice d'affichage //\_________________ On dessine l'indicateur. glEnable (GL_BLEND); if (pData->fAlpha != 1) _cairo_dock_set_blend_alpha (); else _cairo_dock_set_blend_over(); //glEnable(GL_DEPTH_TEST); glScalef (myData.dropIndicator.iWidth, myData.dropIndicator.iHeight, myData.dropIndicator.iWidth); glColor4f(1.0f, 1.0f, 1.0f, pData->fAlpha); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_TEXTURE); glActiveTextureARB(GL_TEXTURE0_ARB); // Go pour le multitexturing 1ere passe glEnable(GL_TEXTURE_2D); // On active le texturing sur cette passe glBindTexture(GL_TEXTURE_2D, myData.dropIndicator.iTexture); glActiveTextureARB(GL_TEXTURE1_ARB); // Go pour le texturing 2eme passe glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, myData.iBilinearGradationTexture); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Le mode de combinaison des textures ///glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); // multiplier les alpha. //glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_QUADS); glNormal3f(0,0,1); glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(-0.5, -1., 0.); // Bottom Left Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f( 0.5, -1., 0.); // Bottom Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f( 0.5, 1., 0.); // Top Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(-0.5, 1., 0.); // Top Left Of The Texture and Quad glNormal3f(1,0,0); glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(0., -1., -0.5); // Bottom Left Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f(0., -1., 0.5); // Bottom Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f(0., 1., 0.5); // Top Right Of The Texture and Quad glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(0., 1., -0.5); // Top Left Of The Texture and Quad glEnd(); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE0_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable (GL_BLEND); _cairo_dock_set_blend_alpha (); glPopMatrix(); //\_________________ On remet la matrice des textures. glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } if (pData->fAlphaHover > 0 && myData.hoverIndicator.iTexture != 0) { Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons); if (pIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) { _cairo_dock_enable_texture (); _cairo_dock_set_blend_alpha (); glPushMatrix (); if (pDock->container.bIsHorizontal) glTranslatef (pIcon->fDrawX + 5./6*pIcon->fWidth*pIcon->fScale, pDock->iActiveHeight - pIcon->fDrawY - 1./6*pIcon->fHeight*pIcon->fScale, 0.); else glTranslatef (pIcon->fDrawY + 5./6*pIcon->fHeight*pIcon->fScale, pDock->container.iWidth - (pIcon->fDrawX + 1./6*pIcon->fWidth*pIcon->fScale), 0.); _cairo_dock_apply_texture_at_size_with_alpha (myData.hoverIndicator.iTexture, myData.hoverIndicator.iWidth, myData.hoverIndicator.iHeight, pData->fAlphaHover); glPopMatrix (); _cairo_dock_disable_texture (); } } } return GLDI_NOTIFICATION_LET_PASS; }
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 Context::paintWithAlpha( double alpha ) { cairo_paint_with_alpha( mCairo, alpha ); }
/* This is our expose-event handler when the window is in a compositing manager. * We draw everything by hand, using Cairo, so that we can have a nice * transparent/rounded look. */ static void expose_when_composited (GtkWidget *widget, GdkEventExpose *event) { MsdOsdWindow *window; cairo_t *context; cairo_t *cr; cairo_surface_t *surface; int width; int height; GtkStyle *style; GdkColor color; double r, g, b; window = MSD_OSD_WINDOW (widget); context = gdk_cairo_create (gtk_widget_get_window (widget)); style = gtk_widget_get_style (widget); cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); gtk_window_get_size (GTK_WINDOW (widget), &width, &height); surface = cairo_surface_create_similar (cairo_get_target (context), CAIRO_CONTENT_COLOR_ALPHA, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { goto done; } cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { goto done; } cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint (cr); /* draw a box */ msd_osd_window_draw_rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); msd_osd_window_color_reverse (&style->bg[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA); cairo_fill_preserve (cr); msd_osd_window_color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2); cairo_set_line_width (cr, 1); cairo_stroke (cr); g_signal_emit (window, signals[EXPOSE_WHEN_COMPOSITED], 0, cr); cairo_destroy (cr); /* Make sure we have a transparent background */ cairo_rectangle (context, 0, 0, width, height); cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); cairo_fill (context); cairo_set_source_surface (context, surface, 0, 0); cairo_paint_with_alpha (context, window->priv->fade_out_alpha); done: if (surface != NULL) { cairo_surface_destroy (surface); } cairo_destroy (context); }
int closeLayerVectorCairo(imageObj *img, mapObj *map, layerObj *layer) { cairo_renderer *r = CAIRO_RENDERER(img); cairo_pop_group_to_source (r->cr); cairo_paint_with_alpha (r->cr, layer->opacity*0.01); return MS_SUCCESS; }
static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, GsdMediaKeysWindow *window) { cairo_t *context; cairo_t *cr; cairo_surface_t *surface; int width; int height; GtkStyle *style; GdkColor color; double r, g, b; context = gdk_cairo_create (gtk_widget_get_window (widget)); style = gtk_widget_get_style (widget); cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); gtk_window_get_size (GTK_WINDOW (widget), &width, &height); surface = cairo_surface_create_similar (cairo_get_target (context), CAIRO_CONTENT_COLOR_ALPHA, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { goto done; } cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { goto done; } cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint (cr); /* draw a box */ rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); color_reverse (&style->bg[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA); cairo_fill_preserve (cr); color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2); cairo_set_line_width (cr, 1); cairo_stroke (cr); /* draw action */ draw_action (window, cr); cairo_destroy (cr); /* Make sure we have a transparent background */ cairo_rectangle (context, 0, 0, width, height); cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); cairo_fill (context); cairo_set_source_surface (context, surface, 0, 0); cairo_paint_with_alpha (context, window->priv->fade_out_alpha); done: if (surface != NULL) { cairo_surface_destroy (surface); } cairo_destroy (context); return FALSE; }
static void render_card_init (char *card_fname) { int i; if (render_init) { for (i = 0; i < 52; i++) g_object_unref (card_pixbuf[i]); cairo_surface_destroy (grey_surface); render_init = 0; } /* gdk_pixbuf_new_from_file doesn't seem to support .svgz (while * librsvg does), so decompress it here. Code from aisleriot * src/lib/ar-svg.c */ GFile *cf = g_file_new_for_path (card_fname); GFileInfo *info; GError *error = NULL; if (!(info = g_file_query_info (cf, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &error))) { printf ("%s: %s\n", card_fname, error->message); g_object_unref (cf); g_error_free (error); return; } const char *type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE); char *gz_type = g_content_type_from_mime_type ("application/x-gzip"); gboolean is_gzip = (type != NULL && g_content_type_is_a (type, gz_type)); g_free (gz_type); g_object_unref (info); GInputStream *stream; if (!(stream = G_INPUT_STREAM (g_file_read (cf, NULL, &error)))) { printf ("%s: %s\n", card_fname, error->message); g_object_unref (cf); g_error_free (error); return; } g_object_unref (cf); if (is_gzip) { GZlibDecompressor *decompressor; GInputStream *converter_stream; decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); converter_stream = g_converter_input_stream_new (stream, G_CONVERTER (decompressor)); g_object_unref (stream); stream = converter_stream; } /* file contains cards in 13 columns (A/2..10/J/Q/K) and 5 rows (C/D/H/S/Jokers) */ /* actual card height is computed from resulting actual size */ GdkPixbuf *pb = gdk_pixbuf_new_from_stream_at_scale (stream, card_width * 13, -1, TRUE, NULL, &error); g_object_unref (stream); if (!pb) { printf ("%s: %s.\n", card_fname, error->message); g_error_free (error); return; } int buf_width = gdk_pixbuf_get_width (pb); int buf_height = gdk_pixbuf_get_height (pb); card_width = ceil (gdk_pixbuf_get_width (pb) / 13.0); card_height = ceil (gdk_pixbuf_get_height (pb) / 5.0); for (i = 0; i < 52; i++) { card_pixbuf[i] = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, card_width, card_height); if (!card_pixbuf[i]) { printf ("%s: rendering card_pixbuf failed\n", card_fname); return; } int col = (i + 1) % 13; int row = i / 13; gdk_pixbuf_copy_area (pb, buf_width * col / 13.0, buf_height * row / 5.0, //gdk_pixbuf_copy_area (pb, card_width * col, card_height * row, card_width, card_height, card_pixbuf[i], 0, 0); } g_object_unref (pb); /* construct a alpha channel in card shape for greying out cards */ grey_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, card_width, card_height); cairo_t *ct = cairo_create (grey_surface); gdk_cairo_set_source_pixbuf (ct, card_pixbuf[0], 0, 0); cairo_paint_with_alpha (ct, 0.3); cairo_destroy (ct); render_init = 1; }
static int cr_paint_with_alpha (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); cairo_paint_with_alpha(*obj, luaL_checknumber(L, 2)); return 0; }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* cr = context->platformContext(); cairo_save(cr); font->setFont(cr); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); float offset = point.x(); for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = point.y(); offset += glyphBuffer.advanceAt(from + i); } Color fillColor = context->fillColor(); // Text shadow, inspired by FontMac IntSize shadowSize; int shadowBlur = 0; Color shadowColor; bool hasShadow = context->textDrawingMode() == cTextFill && context->getShadow(shadowSize, shadowBlur, shadowColor); // TODO: Blur support if (hasShadow) { // Disable graphics context shadows (not yet implemented) and paint them manually context->clearShadow(); Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); cairo_save(cr); float red, green, blue, alpha; shadowFillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); cairo_translate(cr, shadowSize.width(), shadowSize.height()); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } if (context->textDrawingMode() & cTextFill) { if (context->fillGradient()) { cairo_set_source(cr, context->fillGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->fillPattern()) { TransformationMatrix affine; cairo_set_source(cr, context->fillPattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { float red, green, blue, alpha; fillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_show_glyphs(cr, glyphs, numGlyphs); } if (context->textDrawingMode() & cTextStroke) { if (context->strokeGradient()) { cairo_set_source(cr, context->strokeGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->strokePattern()) { TransformationMatrix affine; cairo_set_source(cr, context->strokePattern()->createPlatformPattern(affine)); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else { Color strokeColor = context->strokeColor(); float red, green, blue, alpha; strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_glyph_path(cr, glyphs, numGlyphs); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Re-enable the platform shadow we disabled earlier if (hasShadow) context->setShadow(shadowSize, shadowBlur, shadowColor); cairo_restore(cr); }
static gboolean zoom_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data) { CompositedZoomData *zoom; zoom = user_data; if (zoom->size >= zoom->size_end) { if (zoom->timeout_id) g_source_remove (zoom->timeout_id); zoom->timeout_id = 0; gtk_widget_hide (widget); g_idle_add (idle_destroy, widget); g_object_unref (zoom->pixbuf); zoom->pixbuf = NULL; g_slice_free (CompositedZoomData, zoom); } else { GdkPixbuf *scaled; int width, height; int x = 0, y = 0; gtk_window_get_size (GTK_WINDOW (widget), &width, &height); zoom->size += MAX ((zoom->size_end - zoom->size_start) / ZOOM_STEPS, 1); zoom->opacity -= 1.0 / ((double) ZOOM_STEPS + 1); scaled = gdk_pixbuf_scale_simple (zoom->pixbuf, zoom->size, zoom->size, GDK_INTERP_BILINEAR); switch (zoom->orientation) { case PANEL_ORIENTATION_TOP: x = (width - gdk_pixbuf_get_width (scaled)) / 2; y = 0; break; case PANEL_ORIENTATION_RIGHT: x = width - gdk_pixbuf_get_width (scaled); y = (height - gdk_pixbuf_get_height (scaled)) / 2; break; case PANEL_ORIENTATION_BOTTOM: x = (width - gdk_pixbuf_get_width (scaled)) / 2; y = height - gdk_pixbuf_get_height (scaled); break; case PANEL_ORIENTATION_LEFT: x = 0; y = (height - gdk_pixbuf_get_height (scaled)) / 2; break; default: break; } cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (cr, 0, 0, 0, 0.0); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); gdk_cairo_set_source_pixbuf (cr, scaled, x, y); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint_with_alpha (cr, MAX (zoom->opacity, 0)); g_object_unref (scaled); } return FALSE; }
void DrawInputBar(FcitxSkin* sc, InputWindow* inputWindow, int iCursorPos, FcitxMessages * msgup, FcitxMessages *msgdown , unsigned int * iheight, unsigned int *iwidth) { int i; char *strUp[MAX_MESSAGE_COUNT]; char *strDown[MAX_MESSAGE_COUNT]; int posUpX[MAX_MESSAGE_COUNT], posUpY[MAX_MESSAGE_COUNT]; int posDownX[MAX_MESSAGE_COUNT], posDownY[MAX_MESSAGE_COUNT]; int oldHeight = *iheight, oldWidth = *iwidth; int newHeight = 0, newWidth = 0; int cursor_pos = 0; int inputWidth = 0, outputWidth = 0; int outputHeight = 0; cairo_t *c = NULL; FcitxInputState* input = FcitxInstanceGetInputState(inputWindow->owner->owner); FcitxInstance* instance = inputWindow->owner->owner; FcitxClassicUI* classicui = inputWindow->owner; int iChar = iCursorPos; int strWidth = 0, strHeight = 0; SkinImage *inputimg, *prev, *next; inputimg = LoadImage(sc, sc->skinInputBar.backImg, false); prev = LoadImage(sc, sc->skinInputBar.backArrow, false); next = LoadImage(sc, sc->skinInputBar.forwardArrow, false); if (!FcitxMessagesIsMessageChanged(msgup) && !FcitxMessagesIsMessageChanged(msgdown)) return; inputWidth = 0; #ifdef _ENABLE_PANGO /* special case which only macro unable to handle */ SetFontContext(dummy, inputWindow->owner->font, sc->skinFont.fontSize); #endif for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) { char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgup, i)); if (trans) strUp[i] = trans; else strUp[i] = FcitxMessagesGetMessageString(msgup, i); posUpX[i] = sc->skinInputBar.marginLeft + inputWidth; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], strUp[i], &strWidth, &strHeight); posUpY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - strHeight; inputWidth += strWidth; if (FcitxInputStateGetShowCursor(input)) { int length = strlen(FcitxMessagesGetMessageString(msgup, i)); if (iChar >= 0) { if (iChar < length) { char strTemp[MESSAGE_MAX_LENGTH]; char *strGBKT = NULL; strncpy(strTemp, strUp[i], iChar); strTemp[iChar] = '\0'; strGBKT = strTemp; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], strGBKT, &strWidth, &strHeight); cursor_pos = posUpX[i] + strWidth + 2; } iChar -= length; } } } if (iChar >= 0) cursor_pos = inputWidth + sc->skinInputBar.marginLeft; outputWidth = 0; outputHeight = 0; int currentX = 0; for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) { char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgdown, i)); if (trans) strDown[i] = trans; else strDown[i] = FcitxMessagesGetMessageString(msgdown, i); if (inputWindow->owner->bVerticalList) { /* vertical */ if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX) { if (currentX > outputWidth) outputWidth = currentX; if (i != 0) { outputHeight += sc->skinFont.fontSize + 2; currentX = 0; } } posDownX[i] = sc->skinInputBar.marginLeft + currentX; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], strDown[i], &strWidth, &strHeight); currentX += strWidth; posDownY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iOutputPos + outputHeight - strHeight; } else { /* horizontal */ posDownX[i] = sc->skinInputBar.marginLeft + outputWidth; StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], strDown[i], &strWidth, &strHeight); posDownY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iOutputPos - strHeight; outputWidth += strWidth; } } if (inputWindow->owner->bVerticalList && currentX > outputWidth) outputWidth = currentX; newHeight = sc->skinInputBar.marginTop + sc->skinInputBar.iOutputPos + outputHeight + sc->skinInputBar.marginBottom; newWidth = (inputWidth < outputWidth) ? outputWidth : inputWidth; newWidth += sc->skinInputBar.marginLeft + sc->skinInputBar.marginRight; /* round to ROUND_SIZE in order to decrease resize */ newWidth = (newWidth / ROUND_SIZE) * ROUND_SIZE + ROUND_SIZE; if (inputWindow->owner->bVerticalList) { /* vertical */ newWidth = (newWidth < INPUT_BAR_VMIN_WIDTH) ? INPUT_BAR_VMIN_WIDTH : newWidth; } else { newWidth = (newWidth < INPUT_BAR_HMIN_WIDTH) ? INPUT_BAR_HMIN_WIDTH : newWidth; } *iwidth = newWidth; *iheight = newHeight; EnlargeCairoSurface(&inputWindow->cs_input_back, newWidth, newHeight); if (EnlargeCairoSurface(&inputWindow->cs_input_bar, newWidth, newHeight)) { LoadInputMessage(&classicui->skin, classicui->inputWindow, classicui->font); } if (oldHeight != newHeight || oldWidth != newWidth) { c = cairo_create(inputWindow->cs_input_back); DrawResizableBackground(c, inputimg->image, newHeight, newWidth, sc->skinInputBar.marginLeft, sc->skinInputBar.marginTop, sc->skinInputBar.marginRight, sc->skinInputBar.marginBottom, sc->skinInputBar.fillV, sc->skinInputBar.fillH ); cairo_destroy(c); } c = cairo_create(inputWindow->cs_input_bar); cairo_set_source_surface(c, inputWindow->cs_input_back, 0, 0); cairo_save(c); cairo_rectangle(c, 0, 0, newWidth, newHeight); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_clip(c); cairo_paint(c); cairo_restore(c); cairo_set_operator(c, CAIRO_OPERATOR_OVER); if (FcitxInputStateGetShowCursor(input)) { //画向前向后箭头 if (prev && next) { cairo_set_source_surface(inputWindow->c_back, prev->image, newWidth - sc->skinInputBar.iBackArrowX , sc->skinInputBar.iBackArrowY); if (FcitxCandidateWordHasPrev(FcitxInputStateGetCandidateList(input))) cairo_paint(inputWindow->c_back); else cairo_paint_with_alpha(inputWindow->c_back, 0.5); //画向前箭头 cairo_set_source_surface(inputWindow->c_back, next->image, newWidth - sc->skinInputBar.iForwardArrowX , sc->skinInputBar.iForwardArrowY); if (FcitxCandidateWordHasNext(FcitxInputStateGetCandidateList(input))) cairo_paint(inputWindow->c_back); else cairo_paint_with_alpha(inputWindow->c_back, 0.5); } } for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) { OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], strUp[i], posUpX[i], posUpY[i]); if (strUp[i] != FcitxMessagesGetMessageString(msgup, i)) free(strUp[i]); } for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) { OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], strDown[i], posDownX[i], posDownY[i]); if (strDown[i] != FcitxMessagesGetMessageString(msgdown, i)) free(strDown[i]); } ResetFontContext(); //画光标 if (FcitxInputStateGetShowCursor(input)) { cairo_move_to(inputWindow->c_cursor, cursor_pos, sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos); cairo_line_to(inputWindow->c_cursor, cursor_pos, sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - FontHeightWithContext(inputWindow->c_font[0]) - 4); cairo_stroke(inputWindow->c_cursor); } cairo_destroy(c); FcitxMessagesSetMessageChanged(msgup, false); FcitxMessagesSetMessageChanged(msgdown, false); }
int render_pdf_page(int pdf, int pg, Window win, bool fixed) { if (pg >= _pdf[pdf].npage) return 1; cairo_t *ctx; cairo_surface_t *s, *img; double pdfw, pdfh, scx, scy; int ig; unsigned int uig, ww, wh; /* get page size and scale to window */ PopplerPage *page = poppler_document_get_page(_pdf[pdf].doc, pg); poppler_page_get_size(page, &pdfw, &pdfh); XGetGeometry(dpy, win, (Window *) &ig, &ig, &ig, &ww, &wh, &uig, &uig); scx = ww / pdfw; scy = wh / pdfh; //if (pdf == 0) { _ww = ww; _wh = wh; } if (fixed) { /* adjust window size for fixed aspect ratio */ scx = (scx < scy ? (scy=scx) : scy); ww = scx * pdfw + 0.5; wh = scy * pdfh + 0.5; XResizeWindow(dpy, win, ww, wh); } /* create background pixmap and render page to it */ Pixmap pix = XCreatePixmap(dpy, win, ww, wh, DefaultDepth(dpy,scr)); s = cairo_xlib_surface_create(dpy, pix, DefaultVisual(dpy,scr), ww, wh); ctx = cairo_create(s); cairo_surface_destroy(s); cairo_scale(ctx, scx, scy); cairo_set_source_rgb(ctx, 1, 1, 1); cairo_paint(ctx); poppler_page_render(page, ctx); cairo_destroy(ctx); /* if this is the fader window, fade in */ if (win == _fade_win) { /* hide cursor for fade transitions */ #ifdef module_cursor bool pre = cursor_visible(query); cursor_visible(false); #endif /* get image, set up context, and render page */ img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ww, wh); ctx = cairo_create(img); cairo_scale(ctx, scx, scy); cairo_set_source_rgb(ctx, 1, 1, 1); cairo_paint(ctx); poppler_page_render(page, ctx); cairo_destroy(ctx); /* get window surface, reset context to draw img to window */ s = cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy,scr), ww, wh); ctx = cairo_create(s); cairo_surface_destroy(s); cairo_set_source_surface(ctx, img, 0, 0); // memory leak?! /* fade in */ for (ig = _fade_steps; ig; --ig) { cairo_paint_with_alpha(ctx, 1 / (float) ig); // memory leak?! //XFlush(dpy); usleep(200); } /* clean up */ cairo_destroy(ctx); cairo_surface_destroy(img); #ifdef module_cursor cursor_visible(pre); #endif } g_object_unref(page); /* set the pixmap to be the window background */ XSetWindowBackgroundPixmap(dpy, win, pix); XFreePixmap(dpy, pix); XClearWindow(dpy, win); #ifdef module_cursor if (pdf == 0) cursor_draw(-1, -1); #endif return 0; }