⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pixops.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GKrellM|  Copyright (C) 1999-2006 Bill Wilson||  Author:  Bill Wilson    billw@gkrellm.net|  Latest versions might be found at:  http://gkrellm.net||  This program is free software which I release under the GNU General Public|  License. You may redistribute and/or modify this program under the terms|  of that license as published by the Free Software Foundation; either|  version 2 of the License, or (at your option) any later version.||  This program is distributed in the hope that it will be useful,|  but WITHOUT ANY WARRANTY; without even the implied warranty of|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the|  GNU General Public License for more details.  Version 2 is in the|  COPYRIGHT file in the top level directory of this distribution.| |  To get a copy of the GNU General Puplic License, write to the Free Software|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include "gkrellm.h"#include "gkrellm-private.h"voidgkrellm_free_pixmap(GdkPixmap **pixmap)	{	if (!pixmap)		return;	if (*pixmap)		g_object_unref(G_OBJECT(*pixmap));	*pixmap = NULL;	}voidgkrellm_free_bitmap(GdkBitmap **bitmap)	{	if (!bitmap)		return;	if (*bitmap)		g_object_unref(G_OBJECT(*bitmap));	*bitmap = NULL;	}gbooleangkrellm_clone_pixmap(GdkPixmap **dest, GdkPixmap **src)	{	gint	w_dest = 0, h_dest = 0, w_src = 0, h_src = 0;	if (!dest)		return FALSE;	if (!src || !*src)		{		gkrellm_free_pixmap(dest);		return FALSE;		}	gdk_drawable_get_size(*src, &w_src, &h_src);	if (*dest)		{		gdk_drawable_get_size(*dest, &w_dest, &h_dest);		if (w_dest != w_src || h_dest != h_src)			gkrellm_free_pixmap(dest);		}	if (!*dest)		*dest = gdk_pixmap_new(gkrellm_get_top_window()->window,					w_src, h_src, -1);	gdk_draw_drawable(*dest, _GK.draw1_GC, *src, 0, 0, 0, 0, w_src, h_src);	return TRUE;		}gbooleangkrellm_clone_bitmap(GdkBitmap **dest, GdkBitmap **src)	{	gint	w_dest = 0, h_dest = 0, w_src = 0, h_src = 0;	if (!dest)		return FALSE;	if (!src || !*src)		{		gkrellm_free_bitmap(dest);		return FALSE;		}	gdk_drawable_get_size(*src, &w_src, &h_src);	if (*dest)		{		gdk_drawable_get_size(*dest, &w_dest, &h_dest);		if (w_dest != w_src || h_dest != h_src)			gkrellm_free_bitmap(dest);		}	if (!*dest)		*dest = gdk_pixmap_new(gkrellm_get_top_window()->window,					w_src, h_src, 1);	gdk_draw_drawable(*dest, _GK.bit1_GC, *src, 0, 0, 0, 0, w_src, h_src);	return TRUE;		}static void_render_to_pixmap(GdkPixbuf *pixbuf, GdkPixmap **pixmap, GdkBitmap **mask,		gint x_src, gint y_src, gint x_dst, gint y_dst, gint w, gint h)	{	gdk_pixbuf_render_to_drawable(pixbuf, *pixmap, _GK.draw1_GC,			x_src, y_src, x_dst, y_dst,			w, h, GDK_RGB_DITHER_NORMAL, 0, 0);	if (mask && *mask)		gdk_pixbuf_render_threshold_alpha(pixbuf, *mask,					x_src, y_src, x_dst, y_dst,					w, h, 128 /* alpha threshold */);	}gbooleangkrellm_scale_pixbuf_to_pixmap(GdkPixbuf *src_pixbuf, GdkPixmap **pixmap,			GdkBitmap **mask, gint w_dst, gint h_dst)	{	GdkWindow		*window = gkrellm_get_top_window()->window;	GdkPixbuf		*dst_pixbuf;	gint			w_src, h_src;	gboolean		has_alpha;	GdkInterpType	interp_type;	gkrellm_free_pixmap(pixmap);	gkrellm_free_bitmap(mask);	if (!src_pixbuf || !pixmap)		return FALSE;	has_alpha = gdk_pixbuf_get_has_alpha(src_pixbuf);	w_src = gdk_pixbuf_get_width(src_pixbuf);	h_src = gdk_pixbuf_get_height(src_pixbuf);	if (w_dst == 0)		w_dst = w_src;	else if (w_dst < 0 && (w_dst = w_src * _GK.theme_scale / 100) <= 0)		w_dst = 1;	if (h_dst == 0)		h_dst = h_src;	else if (h_dst < 0 && (h_dst = h_src * _GK.theme_scale / 100) <= 0)		h_dst = 1;	*pixmap = gdk_pixmap_new(window, w_dst, h_dst, -1);	if (mask && has_alpha)		*mask = gdk_pixmap_new(window, w_dst, h_dst, 1);	if (w_dst == w_src && h_dst == h_src)		{		_render_to_pixmap(src_pixbuf, pixmap, mask, 0, 0, 0, 0, w_dst, h_dst);		return TRUE;		}	if (w_dst > w_src && h_dst > h_src)		interp_type = GDK_INTERP_NEAREST;	else		interp_type = GDK_INTERP_BILINEAR;	dst_pixbuf = gdk_pixbuf_scale_simple(src_pixbuf, w_dst, h_dst,interp_type);	_render_to_pixmap(dst_pixbuf, pixmap, mask, 0, 0, 0, 0, w_dst, h_dst);	g_object_unref(G_OBJECT(dst_pixbuf));	return TRUE;	}static voidfix_border_overlap(gint *a, gint *b, gint l)	{	gint	A = 0, B = 0;	gint	lb;	lb = *a + *b;	if (l > 1 && lb > 0)		{		A = *a * (l - 1) / lb;		B = *b * (l - 1) / lb;		}	*a = A;	*b = B;	}GdkPixbuf *gkrellm_scale_piximage_to_pixbuf(GkrellmPiximage *piximage,			gint w_dst, gint h_dst)	{	GdkPixbuf		*src_pixbuf, *dst_pixbuf;	GkrellmBorder	b;	gint			w_src, h_src;	gint			src_width, src_height, dst_width, dst_height;	gboolean		has_alpha;	double			v_scale, h_scale;	GdkInterpType	interp_type;	src_pixbuf = piximage->pixbuf;	b = piximage->border;	has_alpha = gdk_pixbuf_get_has_alpha(src_pixbuf);	w_src = gdk_pixbuf_get_width(src_pixbuf);	h_src = gdk_pixbuf_get_height(src_pixbuf);	if (w_dst == 0)		w_dst = w_src;	else if (w_dst < 0 && (w_dst = w_src * _GK.theme_scale / 100) <= 0)		w_dst = 1;	if (h_dst == 0)		h_dst = h_src;	else if (h_dst < 0 && (h_dst = h_src * _GK.theme_scale / 100) <= 0)		h_dst = 1;	dst_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8, w_dst,h_dst);	if (b.left + b.right >= w_dst || b.left + b.right >= w_src)		fix_border_overlap(&b.left, &b.right, (w_dst > w_src) ? w_src : w_dst);	if (b.top + b.bottom >= h_dst || b.top + b.bottom >= h_src)		fix_border_overlap(&b.top, &b.bottom, (h_dst > h_src) ? h_src : h_dst);	/* Corner areas are not scaled	*/	if (b.left > 0 && b.top > 0)		gdk_pixbuf_copy_area(src_pixbuf, 0, 0,				b.left, b.top,				dst_pixbuf, 0, 0);	if (b.left > 0 && b.bottom > 0)		gdk_pixbuf_copy_area(src_pixbuf, 0, h_src - b.bottom,				b.left, b.bottom,				dst_pixbuf, 0, h_dst - b.bottom);	if (b.right > 0 && b.top > 0)		gdk_pixbuf_copy_area(src_pixbuf, w_src - b.right, 0,				b.right, b.top,				dst_pixbuf, w_dst - b.right, 0);	if (b.right > 0 && b.bottom > 0)		gdk_pixbuf_copy_area(src_pixbuf, w_src - b.right, h_src - b.bottom,				b.right, b.bottom,				dst_pixbuf, w_dst - b.right, h_dst - b.bottom);	dst_width = w_dst - b.left - b.right;	dst_height = h_dst - b.top - b.bottom;	src_width = w_src - b.left - b.right;	src_height = h_src - b.top - b.bottom;	if (src_width <= 0)		src_width = 1;	if (src_height <= 0)		src_height = 1;	v_scale = (double) dst_height / (double) src_height;	h_scale = (double) dst_width / (double) src_width;	if (v_scale > 1.0 && h_scale > 1.0)		interp_type = GDK_INTERP_NEAREST;	else		interp_type = GDK_INTERP_BILINEAR;	/* I don't want to hurt my brain again with figuring out what is going	|  on with these pixbuf offsets, so here's one dimensional clues for the	|  x scale > 1 case where I want to write a center stretched region into	|  the dst_pixbuf.  The 'o' pixels are a border of width L and R, the dest	|  center region width is dst_width.  Borders on src and dst are the same.	|  (You'll need a fixed width font for this diagram to make sense)	|	|                                 src_width	|                          L->|  |<-      ->|  |<-R	|  src_pixbuf                 oooo..........oooo	|  dst_pixbuf                 oooo....................oooo	|                          L->|  |<-  dst_width     ->|  |<-R	|  src scaled by S to get     oooooooooo....................oooooooooo	|  center to dst_width size ->|        |<- L * S         |	|                             |                          |	|  Shift left by (L * x)      |                          |	|  and then right by L        |  |                    |  |	|  to get the x_offset  oooooooooo....................oooooooooo	|                     ->|     |<- x_offset = -(L*S) + L  |	|                             |                          |	|  Now, write dst_width pixels from src_pixbuf L to dst_pixbuf L.  Look at	|  top border case below.     |                          |	|                             |                          |	|  To write the right border (bottom is similar) the situation is	|  the dst_pixbuf is larger than src_pixbuf (x scale > 1 case), but	|  border pixels should not be scaled.  ie x_scale = 1.0 for this write.	|                             |                          |	|                             |           ->|  |<- R     |	|  src_pixbuf                 oooo..........oooo         |	|  dst_pixbuf                 oooo....................oooo	|                             |                |    ->|  |<- R	|  Shift src right by         |         oooo..........oooo	|  (w_dst - w_src) and        |                |      |  |	|  write R pixels at          ----------------------------	|  (w_dst - R) from           |                |      |  |	|  src_pixbuf to dst_pixbuf.  0               w_src      w_dst	*/	if (b.left > 0 && dst_height > 0)	/* Left border */		gdk_pixbuf_scale(src_pixbuf, dst_pixbuf, 0, b.top,			b.left, dst_height,			0, (double) (b.top * -v_scale + b.top),			1.0, v_scale, interp_type);					if (b.right > 0 && dst_height > 0)	/* right border */		gdk_pixbuf_scale(src_pixbuf, dst_pixbuf, w_dst - b.right, b.top,			b.right, dst_height,			(double) (w_dst - w_src), (double) (b.top * -v_scale + b.top),			1.0, v_scale, interp_type);					if (b.top > 0 && dst_width > 0)	/* top border */		gdk_pixbuf_scale(src_pixbuf, dst_pixbuf, b.left, 0,			dst_width, b.top,			(double) (b.left * -h_scale + b.left), 0,			h_scale, 1.0, interp_type);					if (b.bottom > 0 && dst_width > 0)	/* bottom border */		gdk_pixbuf_scale(src_pixbuf, dst_pixbuf, b.left, h_dst - b.bottom,			dst_width, b.bottom,			(double) (b.left * -h_scale + b.left), (double) (h_dst - h_src),			h_scale, 1.0, interp_type);	if (dst_width > 0 && dst_height > 0)	/* Center area */		gdk_pixbuf_scale(src_pixbuf, dst_pixbuf, b.left, b.top,			dst_width, dst_height,			(double) (b.left * -h_scale + b.left),			(double) (b.top * -v_scale + b.top),			h_scale, v_scale, interp_type);	return dst_pixbuf;	}gbooleangkrellm_scale_piximage_to_pixmap(GkrellmPiximage *piximage, GdkPixmap **pixmap,			GdkBitmap **mask, gint w_dst, gint h_dst)	{	GdkWindow		*window = gkrellm_get_top_window()->window;	GdkPixbuf		*src_pixbuf, *dst_pixbuf;	gint			w_src, h_src;	gboolean		has_alpha;	/* I want the pixmap freed even if there is no image to render back	|  in.  Eg. theme switch to one with no data_in/out_piximage.	*/	gkrellm_free_pixmap(pixmap);	gkrellm_free_bitmap(mask);	if (!piximage || !piximage->pixbuf || !pixmap)		return FALSE;	src_pixbuf = piximage->pixbuf;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -