void draw_cairo(cairo_surface_t *in) { cairo_t *cr; int mid ; if(0)printf("%p\n", in); if(!psize ) return; if(!in) return; cr = cairo_create (in); draw_path(cr); draw_fill(cr); draw_text(cr); draw_mask(cr); return; cairo_set_source_rgb (cr, 0, 1, 0); cairo_rectangle (cr, 0, 0, 640,480); cairo_fill (cr); cairo_set_source_rgb (cr, 0, 0, 0.9); cairo_rectangle (cr, 0, 0, 64,480); cairo_fill (cr); // cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); // cairo_set_source_rgba (cr, 0, 0, 0, 0); // cairo_paint (cr); cairo_set_source_rgb (cr, 1, 1, 1); cairo_rectangle (cr, 0, 0, 100, 100); cairo_paint_with_alpha (cr, 0.5); // /cairo_fill (cr); //*surface_inout = cairo_surface_reference (cairo_get_target (cr)); #define M_PI 3.1415 cairo_arc (cr, 128.0, 128.0, 76.8, 0, 2 * M_PI); cairo_clip (cr); cairo_new_path (cr); cairo_rectangle (cr, 0, 0, 256, 256); cairo_fill (cr); cairo_set_source_rgb (cr, 0, 1, 0); cairo_move_to (cr, 0, 0); cairo_line_to (cr, 256, 256); cairo_move_to (cr, 256, 0); cairo_line_to (cr, 0, 256); cairo_set_line_width (cr, 10.0); cairo_stroke (cr); cairo_destroy (cr); }
static bool draw_with_mask_filter(GrDrawContext* drawContext, GrTextureProvider* textureProvider, GrRenderTarget* rt, const GrClip& clipData, const SkMatrix& viewMatrix, const SkPath& devPath, SkMaskFilter* filter, const SkIRect& clipBounds, GrPaint* grp, SkPaint::Style style) { SkMask srcM, dstM; if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM, SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) { return false; } SkAutoMaskFreeImage autoSrc(srcM.fImage); if (!filter->filterMask(&dstM, srcM, viewMatrix, nullptr)) { return false; } // this will free-up dstM when we're done (allocated in filterMask()) SkAutoMaskFreeImage autoDst(dstM.fImage); if (clip_bounds_quick_reject(clipBounds, dstM.fBounds)) { return false; } // we now have a device-aligned 8bit mask in dstM, ready to be drawn using // the current clip (and identity matrix) and GrPaint settings GrSurfaceDesc desc; desc.fWidth = dstM.fBounds.width(); desc.fHeight = dstM.fBounds.height(); desc.fConfig = kAlpha_8_GrPixelConfig; SkAutoTUnref<GrTexture> texture(textureProvider->createApproxTexture(desc)); if (!texture) { return false; } texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, dstM.fImage, dstM.fRowBytes); SkRect maskRect = SkRect::Make(dstM.fBounds); return draw_mask(drawContext, rt, clipData, viewMatrix, maskRect, grp, texture); }
static void draw (const cairo_test_context_t *ctx, cairo_t *cr, cairo_rectangle_t *region, int n_regions) { cairo_save (cr); if (region != NULL) { int i; for (i = 0; i < n_regions; i++) { cairo_rectangle (cr, region[i].x, region[i].y, region[i].width, region[i].height); } cairo_clip (cr); } cairo_push_group (cr); draw_image (ctx, cr); draw_mask (cr); cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); cairo_restore (cr); }
BitmapShaderGM() { this->setBGColor(SK_ColorGRAY); draw_bm(&fBitmap); draw_mask(&fMask); }
static void draw_path_with_mask_filter(GrContext* context, GrDrawContext* drawContext, const GrClip& clip, GrPaint* paint, const SkMatrix& viewMatrix, const SkMaskFilter* maskFilter, const GrStyle& style, const SkPath* path, bool pathIsMutable) { SkASSERT(maskFilter); SkIRect clipBounds; clip.getConservativeBounds(drawContext->width(), drawContext->height(), &clipBounds); SkTLazy<SkPath> tmpPath; SkStrokeRec::InitStyle fillOrHairline; // We just fully apply the style here. if (style.applies()) { if (!style.applyToPath(tmpPath.init(), &fillOrHairline, *path, GrStyle::MatrixToScaleFactor(viewMatrix))) { return; } pathIsMutable = true; path = tmpPath.get(); } else if (style.isSimpleHairline()) { fillOrHairline = SkStrokeRec::kHairline_InitStyle; } else { SkASSERT(style.isSimpleFill()); fillOrHairline = SkStrokeRec::kFill_InitStyle; } // transform the path into device space if (!viewMatrix.isIdentity()) { SkPath* result; if (pathIsMutable) { result = const_cast<SkPath*>(path); } else { if (!tmpPath.isValid()) { tmpPath.init(); } result = tmpPath.get(); } path->transform(viewMatrix, result); path = result; result->setIsVolatile(true); pathIsMutable = true; } SkRect maskRect; if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(path->getBounds()), clipBounds, viewMatrix, &maskRect)) { // This mask will ultimately be drawn as a non-AA rect (see draw_mask). // Non-AA rects have a bad habit of snapping arbitrarily. Integerize here // so the mask draws in a reproducible manner. SkIRect finalIRect; maskRect.roundOut(&finalIRect); if (clip_bounds_quick_reject(clipBounds, finalIRect)) { // clipped out return; } if (maskFilter->directFilterMaskGPU(context->textureProvider(), drawContext, paint, clip, viewMatrix, SkStrokeRec(fillOrHairline), *path)) { // the mask filter was able to draw itself directly, so there's nothing // left to do. return; } sk_sp<GrTexture> mask(create_mask_GPU(context, finalIRect, *path, fillOrHairline, paint->isAntiAlias(), drawContext->numColorSamples())); if (mask) { GrTexture* filtered; if (maskFilter->filterMaskGPU(mask.get(), viewMatrix, finalIRect, &filtered, true)) { // filterMaskGPU gives us ownership of a ref to the result SkAutoTUnref<GrTexture> atu(filtered); if (draw_mask(drawContext, clip, viewMatrix, finalIRect, paint, filtered)) { // This path is completely drawn return; } } } } sw_draw_with_mask_filter(drawContext, context->textureProvider(), clip, viewMatrix, *path, maskFilter, clipBounds, paint, fillOrHairline); }
static void draw_path_with_mask_filter(GrContext* context, GrDrawContext* drawContext, const GrClip& clip, GrPaint* paint, const SkMatrix& viewMatrix, const SkMaskFilter* maskFilter, const SkPathEffect* pathEffect, const GrStrokeInfo& origStrokeInfo, SkPath* pathPtr, bool pathIsMutable) { SkASSERT(maskFilter); SkIRect clipBounds; clip.getConservativeBounds(drawContext->width(), drawContext->height(), &clipBounds); SkTLazy<SkPath> tmpPath; GrStrokeInfo strokeInfo(origStrokeInfo); static const SkRect* cullRect = nullptr; // TODO: what is our bounds? SkASSERT(strokeInfo.isDashed() || !pathEffect); if (!strokeInfo.isHairlineStyle()) { SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init(); if (strokeInfo.isDashed()) { if (pathEffect->filterPath(strokedPath, *pathPtr, &strokeInfo, cullRect)) { pathPtr = strokedPath; pathPtr->setIsVolatile(true); pathIsMutable = true; } strokeInfo.removeDash(); } if (strokeInfo.applyToPath(strokedPath, *pathPtr)) { // Apply the stroke to the path if there is one pathPtr = strokedPath; pathPtr->setIsVolatile(true); pathIsMutable = true; strokeInfo.setFillStyle(); } } // avoid possibly allocating a new path in transform if we can SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init(); if (!pathIsMutable) { devPathPtr->setIsVolatile(true); } // transform the path into device space pathPtr->transform(viewMatrix, devPathPtr); SkRect maskRect; if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(devPathPtr->getBounds()), clipBounds, viewMatrix, &maskRect)) { SkIRect finalIRect; maskRect.roundOut(&finalIRect); if (clip_bounds_quick_reject(clipBounds, finalIRect)) { // clipped out return; } if (maskFilter->directFilterMaskGPU(context->textureProvider(), drawContext, paint, clip, viewMatrix, strokeInfo, *devPathPtr)) { // the mask filter was able to draw itself directly, so there's nothing // left to do. return; } SkAutoTUnref<GrTexture> mask(create_mask_GPU(context, &maskRect, *devPathPtr, strokeInfo, paint->isAntiAlias(), drawContext->numColorSamples())); if (mask) { GrTexture* filtered; if (maskFilter->filterMaskGPU(mask, viewMatrix, maskRect, &filtered, true)) { // filterMaskGPU gives us ownership of a ref to the result SkAutoTUnref<GrTexture> atu(filtered); if (draw_mask(drawContext, clip, viewMatrix, maskRect, paint, filtered)) { // This path is completely drawn return; } } } } // draw the mask on the CPU - this is a fallthrough path in case the // GPU path fails SkPaint::Style style = strokeInfo.isHairlineStyle() ? SkPaint::kStroke_Style : SkPaint::kFill_Style; sw_draw_with_mask_filter(drawContext, context->textureProvider(), clip, viewMatrix, *devPathPtr, maskFilter, clipBounds, paint, style); }
static void draw_mosaic (GtkLayout *where, GtkWidget **widgets, int rsize, int focus_on, int rwidth, int rheight) { boxes_drawn = 0; int cur_x = options.center_x - rwidth/2; int cur_y = options.center_y - rheight/2; if (rsize) { int i = 0; int offset = 0; int max_offset = (width*2) / rwidth + (height*2) / rheight; int side = 0; while (i < rsize) { int j = 0; do { if (i == rsize) break; if (cur_x >= 0 && cur_x+rwidth <= width && cur_y >= 0 && cur_y+rheight <= height) { offset = 0; if (gtk_widget_get_parent (widgets[i])) gtk_layout_move (GTK_LAYOUT (where), widgets[i], cur_x, cur_y); else gtk_layout_put (GTK_LAYOUT (where), widgets[i], cur_x, cur_y); gtk_widget_set_size_request (widgets[i], rwidth, rheight); gtk_widget_show (widgets[i]); if (!options.screenshot) { box_rects[i].x = cur_x; box_rects[i].y = cur_y; boxes_drawn++; } i++; } else { offset++; } if (side) { if (j % (side * 4) < side || j % (side * 4) >= side * 3) cur_x += rwidth; else cur_x -= rwidth; if (j % (side * 4) < side * 2) cur_y += rheight; else cur_y -= rheight; } j++; } while (j < side * 4); if (offset >= max_offset) break; side++; cur_x = options.center_x - rwidth/2; cur_y -= rheight; } if (focus_on >= rsize) // If some window was killed and focus was on the last element focus_on = rsize-1; gtk_widget_grab_focus (widgets[focus_on]); } if (!options.screenshot) { draw_mask (window_shape_bitmap, rsize); gtk_widget_shape_combine_mask (window, window_shape_bitmap, 0, 0); } }
int main (int argc, char **argv) { gtk_init (&argc, &argv); read_config (); // Read options from command-line arguments. GError *error = NULL; GOptionContext *context; context = g_option_context_new (" - show X11 windows as colour mosaic"); g_option_context_add_main_entries (context, entries, NULL); g_option_context_add_group (context, gtk_get_option_group (TRUE)); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("option parsing failed: %s\n", error->message); exit (1); } g_option_context_free (context); if(options.format && !options.read_stdin) { g_printerr("You must provide option --read-stdin!"); exit(1); } #ifdef X11 atoms_init (); #endif if (already_opened ()) { g_printerr ("Another instance of xwinmosaic is opened.\n"); exit (1); } if (options.read_stdin) { if(!options.format) { options.show_icons = FALSE; options.show_desktop = FALSE; } read_stdin (); } else { #ifdef X11 // Checks whether WM supports EWMH specifications. if (!wm_supports_ewmh ()) { GtkWidget *dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "Error: your WM does not support EWMH specifications."); gtk_dialog_run (GTK_DIALOG (dialog)); g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_main_quit), NULL); return 1; } active_window = (Window *) property (gdk_x11_get_default_root_xwindow (), a_NET_ACTIVE_WINDOW, XA_WINDOW, NULL); #endif } if (options.color_file) read_colors (); #ifdef WIN32 if (options.persistent) { #ifdef DEBUG g_printerr ("Installing Alt-Tab hook"); #endif install_alt_tab_hook(); } #endif window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "XWinMosaic"); GdkRectangle rect = current_monitor_size (); width = rect.width; height = rect.height; if (options.at_pointer) { gdk_display_get_pointer (gdk_display_get_default (), NULL, &options.center_x, &options.center_y, NULL); gint monitors = gdk_screen_get_n_monitors (gdk_screen_get_default ()); if (monitors > 1) { guint xm = 0, ym = 0; gint current_monitor = gdk_screen_get_monitor_at_point (gdk_screen_get_default (), options.center_x, options.center_y); for (int i = 0; i < current_monitor; i++) { GdkRectangle mon_rect; gdk_screen_get_monitor_geometry (gdk_screen_get_default (), i, &mon_rect); xm += mon_rect.width; ym += mon_rect.height; } if (xm && ym) { options.center_x %= xm; options.center_y %= ym; } } if (options.center_x < options.box_width/2) options.center_x = options.box_width/2 + 1; else if (options.center_x > width - options.box_width/2) options.center_x = width - options.box_width/2 - 1; if (options.center_y < options.box_height/2) options.center_y = options.box_height/2 + 1; else if (options.center_y > height - options.box_height/2) options.center_y = height - options.box_height/2 - 1; } else { options.center_x = width/2; options.center_y = height/2; } gtk_window_set_default_size (GTK_WINDOW (window), width, height); gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); gtk_window_set_decorated (GTK_WINDOW (window), 0); gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), 1); gtk_window_set_skip_pager_hint (GTK_WINDOW (window), 1); /**/ gtk_widget_add_events (GTK_WIDGET (window), GDK_FOCUS_CHANGE); g_signal_connect (G_OBJECT (window), "focus-out-event", G_CALLBACK (on_focus_change), NULL); /**/ layout = gtk_layout_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (window), layout); if (options.screenshot) { gtk_window_fullscreen (GTK_WINDOW (window)); GdkPixbuf *screenshot; GdkPixmap *background = NULL; GtkStyle *style = NULL; screenshot = get_screenshot (); gdk_pixbuf_render_pixmap_and_mask (screenshot, &background, NULL, 0); style = gtk_style_new (); style->bg_pixmap [0] = background; gtk_widget_set_style (window, style); gtk_widget_set_style (layout, style); } search = mosaic_search_box_new (); mosaic_box_set_font (MOSAIC_BOX (search), options.font); gtk_widget_set_can_focus (search, FALSE); GtkRequisition s_req; gtk_widget_size_request (search, &s_req); gtk_layout_put (GTK_LAYOUT (layout), search, (width - s_req.width)/2, height - s_req.height - options.box_height); g_signal_connect (G_OBJECT (search), "changed", G_CALLBACK (refilter), NULL); g_signal_connect (G_OBJECT (window), "key-press-event", G_CALLBACK (on_key_press), NULL); g_signal_connect_swapped(G_OBJECT (window), "destroy", G_CALLBACK(gtk_main_quit), NULL); if (!options.screenshot) { window_shape_bitmap = (GdkDrawable *) gdk_pixmap_new (NULL, width, height, 1); draw_mask (window_shape_bitmap, 0); gtk_widget_shape_combine_mask (window, window_shape_bitmap, 0, 0); } gtk_widget_show_all (window); gtk_widget_hide (search); gtk_window_present (GTK_WINDOW (window)); gtk_window_set_keep_above (GTK_WINDOW (window), TRUE); if (options.persistent) gtk_widget_hide (window); GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (window)); #ifdef X11 myown_window = GDK_WINDOW_XID (gdk_window); if (!options.read_stdin) { // Get PropertyNotify events from root window. XSelectInput (gdk_x11_get_default_xdisplay (), gdk_x11_get_default_root_xwindow (), PropertyChangeMask); gdk_window_add_filter (NULL, (GdkFilterFunc) event_filter, NULL); } #endif #ifdef WIN32 myown_window = GDK_WINDOW_HWND (gdk_window); #endif update_box_list (); draw_mosaic (GTK_LAYOUT (layout), boxes, wsize, 0, options.box_width, options.box_height); #ifdef X11 // Window will be shown on all desktops (and so hidden in windows list) unsigned int desk = 0xFFFFFFFF; // -1 XChangeProperty(gdk_x11_get_default_xdisplay (), myown_window, a_NET_WM_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&desk, 1); #endif gtk_main (); #ifdef X11 if (!options.read_stdin) XFree (wins); #endif return 0; }