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

📄 pixbuf-draw.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GTK+ Pixbuf Engine * Copyright (C) 1998-2000 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Written by Owen Taylor <otaylor@redhat.com>, based on code by * Carsten Haitzler <raster@rasterman.com> */#include <math.h>#include <string.h>#undef GDK_DISABLE_DEPRECATED#include "pixbuf.h"#include "pixbuf-rc-style.h"#include "pixbuf-style.h"static void pixbuf_style_init       (PixbufStyle      *style);static void pixbuf_style_class_init (PixbufStyleClass *klass);static GtkStyleClass *parent_class = NULL;static ThemeImage *match_theme_image (GtkStyle       *style,		   ThemeMatchData *match_data){  GList *tmp_list;  tmp_list = PIXBUF_RC_STYLE (style->rc_style)->img_list;    while (tmp_list)    {      guint flags;      ThemeImage *image = tmp_list->data;      tmp_list = tmp_list->next;      if (match_data->function != image->match_data.function)	continue;      flags = match_data->flags & image->match_data.flags;            if (flags != image->match_data.flags) /* Required components not present */	continue;      if ((flags & THEME_MATCH_STATE) &&	  match_data->state != image->match_data.state)	continue;      if ((flags & THEME_MATCH_SHADOW) &&	  match_data->shadow != image->match_data.shadow)	continue;            if ((flags & THEME_MATCH_ARROW_DIRECTION) &&	  match_data->arrow_direction != image->match_data.arrow_direction)	continue;      if ((flags & THEME_MATCH_ORIENTATION) &&	  match_data->orientation != image->match_data.orientation)	continue;      if ((flags & THEME_MATCH_GAP_SIDE) &&	  match_data->gap_side != image->match_data.gap_side)	continue;      if (image->match_data.detail &&	  (!match_data->detail ||	   strcmp (match_data->detail, image->match_data.detail) != 0))      continue;      return image;    }    return NULL;}static gbooleandraw_simple_image(GtkStyle       *style,		  GdkWindow      *window,		  GdkRectangle   *area,		  GtkWidget      *widget,		  ThemeMatchData *match_data,		  gboolean        draw_center,		  gboolean        allow_setbg,		  gint            x,		  gint            y,		  gint            width,		  gint            height){  ThemeImage *image;  gboolean setbg = FALSE;    if ((width == -1) && (height == -1))    {      gdk_drawable_get_size(window, &width, &height);      if (allow_setbg)      	setbg = TRUE;    }  else if (width == -1)    gdk_drawable_get_size(window, &width, NULL);  else if (height == -1)    gdk_drawable_get_size(window, NULL, &height);  if (!(match_data->flags & THEME_MATCH_ORIENTATION))    {      match_data->flags |= THEME_MATCH_ORIENTATION;            if (height > width)	match_data->orientation = GTK_ORIENTATION_VERTICAL;      else	match_data->orientation = GTK_ORIENTATION_HORIZONTAL;    }      image = match_theme_image (style, match_data);  if (image)    {      if (image->background)	{	  theme_pixbuf_render (image->background,			       window, NULL, area,			       draw_center ? COMPONENT_ALL : COMPONENT_ALL | COMPONENT_CENTER,			       FALSE,			       x, y, width, height);	}            if (image->overlay && draw_center)	theme_pixbuf_render (image->overlay,			     window, NULL, area, COMPONENT_ALL,			     TRUE, 			     x, y, width, height);      return TRUE;    }  else    return FALSE;}static gbooleandraw_gap_image(GtkStyle       *style,	       GdkWindow      *window,	       GdkRectangle   *area,	       GtkWidget      *widget,	       ThemeMatchData *match_data,	       gboolean        draw_center,	       gint            x,	       gint            y,	       gint            width,	       gint            height,	       GtkPositionType gap_side,	       gint            gap_x,	       gint            gap_width){  ThemeImage *image;  gboolean setbg = FALSE;    if ((width == -1) && (height == -1))    {      gdk_drawable_get_size(window, &width, &height);      setbg = TRUE;    }  else if (width == -1)    gdk_drawable_get_size(window, &width, NULL);  else if (height == -1)    gdk_drawable_get_size(window, NULL, &height);  if (!(match_data->flags & THEME_MATCH_ORIENTATION))    {      match_data->flags |= THEME_MATCH_ORIENTATION;            if (height > width)	match_data->orientation = GTK_ORIENTATION_VERTICAL;      else	match_data->orientation = GTK_ORIENTATION_HORIZONTAL;    }  match_data->flags |= THEME_MATCH_GAP_SIDE;  match_data->gap_side = gap_side;      image = match_theme_image (style, match_data);  if (image)    {      gint thickness;      GdkRectangle r1, r2, r3;      GdkPixbuf *pixbuf = NULL;      guint components = COMPONENT_ALL;      if (!draw_center)	components |= COMPONENT_CENTER;      if (image->gap_start)	pixbuf = theme_pixbuf_get_pixbuf (image->gap_start);      switch (gap_side)	{	case GTK_POS_TOP:	  if (pixbuf)	    thickness = gdk_pixbuf_get_height (pixbuf);	  else	    thickness = style->ythickness;	  	  if (!draw_center)	    components |= COMPONENT_NORTH_WEST | COMPONENT_NORTH | COMPONENT_NORTH_EAST;	  r1.x      = x;	  r1.y      = y;	  r1.width  = gap_x;	  r1.height = thickness;	  r2.x      = x + gap_x;	  r2.y      = y;	  r2.width  = gap_width;	  r2.height = thickness;	  r3.x      = x + gap_x + gap_width;	  r3.y      = y;	  r3.width  = width - (gap_x + gap_width);	  r3.height = thickness;	  break;	  	case GTK_POS_BOTTOM:	  if (pixbuf)	    thickness = gdk_pixbuf_get_height (pixbuf);	  else	    thickness = style->ythickness;	  if (!draw_center)	    components |= COMPONENT_SOUTH_WEST | COMPONENT_SOUTH | COMPONENT_SOUTH_EAST;	  r1.x      = x;	  r1.y      = y + height - thickness;	  r1.width  = gap_x;	  r1.height = thickness;	  r2.x      = x + gap_x;	  r2.y      = y + height - thickness;	  r2.width  = gap_width;	  r2.height = thickness;	  r3.x      = x + gap_x + gap_width;	  r3.y      = y + height - thickness;	  r3.width  = width - (gap_x + gap_width);	  r3.height = thickness;	  break;	  	case GTK_POS_LEFT:	  if (pixbuf)	    thickness = gdk_pixbuf_get_width (pixbuf);	  else	    thickness = style->xthickness;	  if (!draw_center)	    components |= COMPONENT_NORTH_WEST | COMPONENT_WEST | COMPONENT_SOUTH_WEST;	  r1.x      = x;	  r1.y      = y;	  r1.width  = thickness;	  r1.height = gap_x;	  r2.x      = x;	  r2.y      = y + gap_x;	  r2.width  = thickness;	  r2.height = gap_width;	  r3.x      = x;	  r3.y      = y + gap_x + gap_width;	  r3.width  = thickness;	  r3.height = height - (gap_x + gap_width);	  break;	  	case GTK_POS_RIGHT:	  if (pixbuf)	    thickness = gdk_pixbuf_get_width (pixbuf);	  else	    thickness = style->xthickness;	  if (!draw_center)	    components |= COMPONENT_NORTH_EAST | COMPONENT_EAST | COMPONENT_SOUTH_EAST;	  r1.x      = x + width - thickness;	  r1.y      = y;	  r1.width  = thickness;	  r1.height = gap_x;	  r2.x      = x + width - thickness;	  r2.y      = y + gap_x;	  r2.width  = thickness;	  r2.height = gap_width;	  r3.x      = x + width - thickness;	  r3.y      = y + gap_x + gap_width;	  r3.width  = thickness;	  r3.height = height - (gap_x + gap_width);	  break;	}      if (image->background)	theme_pixbuf_render (image->background,			     window, NULL, area, components, FALSE,			     x, y, width, height);      if (image->gap_start)	theme_pixbuf_render (image->gap_start,			     window, NULL, area, COMPONENT_ALL, FALSE,			     r1.x, r1.y, r1.width, r1.height);      if (image->gap)	theme_pixbuf_render (image->gap,			     window, NULL, area, COMPONENT_ALL, FALSE,			     r2.x, r2.y, r2.width, r2.height);      if (image->gap_end)	theme_pixbuf_render (image->gap_end,			     window, NULL, area, COMPONENT_ALL, FALSE,			     r3.x, r3.y, r3.width, r3.height);      return TRUE;    }  else    return FALSE;}static voiddraw_hline (GtkStyle     *style,	    GdkWindow    *window,	    GtkStateType  state,	    GdkRectangle *area,	    GtkWidget    *widget,	    const gchar  *detail,	    gint          x1,	    gint          x2,	    gint          y){  ThemeImage *image;  ThemeMatchData   match_data;    g_return_if_fail(style != NULL);  g_return_if_fail(window != NULL);  match_data.function = TOKEN_D_HLINE;  match_data.detail = (gchar *)detail;  match_data.flags = THEME_MATCH_ORIENTATION | THEME_MATCH_STATE;  match_data.state = state;  match_data.orientation = GTK_ORIENTATION_HORIZONTAL;    image = match_theme_image (style, &match_data);  if (image)    {      if (image->background)	theme_pixbuf_render (image->background,			     window, NULL, area, COMPONENT_ALL, FALSE,			     x1, y, (x2 - x1) + 1, 2);    }  else    parent_class->draw_hline (style, window, state, area, widget, detail,			      x1, x2, y);}static voiddraw_vline (GtkStyle     *style,	    GdkWindow    *window,	    GtkStateType  state,	    GdkRectangle *area,	    GtkWidget    *widget,	    const gchar  *detail,	    gint          y1,	    gint          y2,	    gint          x){  ThemeImage    *image;  ThemeMatchData match_data;    g_return_if_fail (style != NULL);  g_return_if_fail (window != NULL);  match_data.function = TOKEN_D_VLINE;  match_data.detail = (gchar *)detail;  match_data.flags = THEME_MATCH_ORIENTATION | THEME_MATCH_STATE;  match_data.state = state;  match_data.orientation = GTK_ORIENTATION_VERTICAL;    image = match_theme_image (style, &match_data);  if (image)    {      if (image->background)	theme_pixbuf_render (image->background,			     window, NULL, area, COMPONENT_ALL, FALSE,			     x, y1, 2, (y2 - y1) + 1);    }  else    parent_class->draw_vline (style, window, state, area, widget, detail,			      y1, y2, x);}static voiddraw_shadow(GtkStyle     *style,	    GdkWindow    *window,	    GtkStateType  state,	    GtkShadowType shadow,	    GdkRectangle *area,	    GtkWidget    *widget,	    const gchar  *detail,	    gint          x,	    gint          y,	    gint          width,	    gint          height){  ThemeMatchData match_data;    g_return_if_fail(style != NULL);  g_return_if_fail(window != NULL);  match_data.function = TOKEN_D_SHADOW;  match_data.detail = (gchar *)detail;  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;  match_data.shadow = shadow;  match_data.state = state;  if (!draw_simple_image (style, window, area, widget, &match_data, FALSE, FALSE,			  x, y, width, height))    parent_class->draw_shadow (style, window, state, shadow, area, widget, detail,			       x, y, width, height);}/* This function makes up for some brokeness in gtkrange.c * where we never get the full arrow of the stepper button * and the type of button in a single drawing function. * * It doesn't work correctly when the scrollbar is squished * to the point we don't have room for full-sized steppers. */static voidreverse_engineer_stepper_box (GtkWidget    *range,			      GtkArrowType  arrow_type,			      gint         *x,			      gint         *y,			      gint         *width,			      gint         *height){  gint slider_width = 14, stepper_size = 14;  gint box_width;  gint box_height;    if (range)    {      gtk_widget_style_get (range,			    "slider_width", &slider_width,			    "stepper_size", &stepper_size,			    NULL);    }	  if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)    {      box_width = slider_width;      box_height = stepper_size;    }  else    {      box_width = stepper_size;      box_height = slider_width;    }  *x = *x - (box_width - *width) / 2;  *y = *y - (box_height - *height) / 2;  *width = box_width;  *height = box_height;}static voiddraw_arrow (GtkStyle     *style,	    GdkWindow    *window,	    GtkStateType  state,	    GtkShadowType shadow,	    GdkRectangle *area,	    GtkWidget    *widget,	    const gchar  *detail,	    GtkArrowType  arrow_direction,	    gint          fill,	    gint          x,	    gint          y,	    gint          width,	    gint          height){  ThemeMatchData match_data;    g_return_if_fail(style != NULL);  g_return_if_fail(window != NULL);  if (detail &&      (strcmp (detail, "hscrollbar") == 0 || strcmp (detail, "vscrollbar") == 0))    {      /* This is a hack to work around the fact that scrollbar steppers are drawn       * as a box + arrow, so we never have       *       *   The full bounding box of the scrollbar        *   The arrow direction       *       * At the same time. We simulate an extra paint function, "STEPPER", by doing       * nothing for the box, and then here, reverse engineering the box that       * was passed to draw box and using that       */      gint box_x = x;      gint box_y = y;      gint box_width = width;      gint box_height = height;      reverse_engineer_stepper_box (widget, arrow_direction,				    &box_x, &box_y, &box_width, &box_height);      match_data.function = TOKEN_D_STEPPER;      match_data.detail = (gchar *)detail;      match_data.flags = (THEME_MATCH_SHADOW | 			  THEME_MATCH_STATE | 			  THEME_MATCH_ARROW_DIRECTION);      match_data.shadow = shadow;      match_data.state = state;      match_data.arrow_direction = arrow_direction;      

⌨️ 快捷键说明

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