source: trunk/third/librsvg/gtk-engine/svg-draw.c @ 18609

Revision 18609, 27.9 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18608, which included commits to RCS files with non-trunk default branches.
Line 
1/* GTK+ Rsvg Engine
2 * Copyright (C) 1998-2000 Red Hat, Inc.
3 * Copyright (C) 2002 Dom Lachowicz
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Written by Owen Taylor <otaylor@redhat.com>, based on code by
21 * Carsten Haitzler <raster@rasterman.com>
22 */
23
24#include <math.h>
25#include <string.h>
26
27#include "svg.h"
28#include "svg-rc-style.h"
29#include "svg-style.h"
30
31static void rsvg_style_init       (RsvgStyle      *style);
32static void rsvg_style_class_init (RsvgStyleClass *klass);
33
34static GtkStyleClass *parent_class = NULL;
35
36static ThemeImage *
37match_theme_image (GtkStyle       *style,
38                   ThemeMatchData *match_data)
39{
40  GList *tmp_list;
41
42  tmp_list = RSVG_RC_STYLE (style->rc_style)->img_list;
43 
44  while (tmp_list)
45    {
46      guint flags;
47      ThemeImage *image = tmp_list->data;
48      tmp_list = tmp_list->next;
49
50      if (match_data->function != image->match_data.function)
51        continue;
52
53      flags = match_data->flags & image->match_data.flags;
54     
55      if (flags != image->match_data.flags) /* Required components not present */
56        continue;
57
58      if ((flags & THEME_MATCH_STATE) &&
59          match_data->state != image->match_data.state)
60        continue;
61
62      if ((flags & THEME_MATCH_SHADOW) &&
63          match_data->shadow != image->match_data.shadow)
64        continue;
65     
66      if ((flags & THEME_MATCH_ARROW_DIRECTION) &&
67          match_data->arrow_direction != image->match_data.arrow_direction)
68        continue;
69
70      if ((flags & THEME_MATCH_ORIENTATION) &&
71          match_data->orientation != image->match_data.orientation)
72        continue;
73
74      if ((flags & THEME_MATCH_GAP_SIDE) &&
75          match_data->gap_side != image->match_data.gap_side)
76        continue;
77
78      if (image->match_data.detail &&
79          (!image->match_data.detail ||
80           strcmp (match_data->detail, image->match_data.detail) != 0))
81      continue;
82
83      return image;
84    }
85 
86  return NULL;
87}
88
89static gboolean
90draw_simple_image(GtkStyle       *style,
91                  GdkWindow      *window,
92                  GdkRectangle   *area,
93                  GtkWidget      *widget,
94                  ThemeMatchData *match_data,
95                  gboolean        draw_center,
96                  gboolean        allow_setbg,
97                  gint            x,
98                  gint            y,
99                  gint            width,
100                  gint            height)
101{
102  ThemeImage *image;
103  gboolean setbg = FALSE;
104 
105  if ((width == -1) && (height == -1))
106    {
107      gdk_window_get_size(window, &width, &height);
108      if (allow_setbg)
109        setbg = TRUE;
110    }
111  else if (width == -1)
112    gdk_window_get_size(window, &width, NULL);
113  else if (height == -1)
114    gdk_window_get_size(window, NULL, &height);
115
116  if (!(match_data->flags & THEME_MATCH_ORIENTATION))
117    {
118      match_data->flags |= THEME_MATCH_ORIENTATION;
119     
120      if (height > width)
121        match_data->orientation = GTK_ORIENTATION_VERTICAL;
122      else
123        match_data->orientation = GTK_ORIENTATION_HORIZONTAL;
124    }
125   
126  image = match_theme_image (style, match_data);
127  if (image)
128    {
129      if (image->background)
130        {
131          theme_pixbuf_render (image->background,
132                               window, NULL, area,
133                               draw_center ? COMPONENT_ALL : COMPONENT_ALL | COMPONENT_CENTER,
134                               FALSE,
135                               x, y, width, height);
136        }
137     
138      if (image->overlay && draw_center)
139        theme_pixbuf_render (image->overlay,
140                             window, NULL, area, COMPONENT_ALL,
141                             TRUE,
142                             x, y, width, height);
143
144      return TRUE;
145    }
146  else
147    return FALSE;
148}
149
150static gboolean
151draw_gap_image(GtkStyle       *style,
152               GdkWindow      *window,
153               GdkRectangle   *area,
154               GtkWidget      *widget,
155               ThemeMatchData *match_data,
156               gboolean        draw_center,
157               gint            x,
158               gint            y,
159               gint            width,
160               gint            height,
161               GtkPositionType gap_side,
162               gint            gap_x,
163               gint            gap_width)
164{
165  ThemeImage *image;
166  gboolean setbg = FALSE;
167 
168  if ((width == -1) && (height == -1))
169    {
170      gdk_window_get_size(window, &width, &height);
171      setbg = TRUE;
172    }
173  else if (width == -1)
174    gdk_window_get_size(window, &width, NULL);
175  else if (height == -1)
176    gdk_window_get_size(window, NULL, &height);
177
178  if (!(match_data->flags & THEME_MATCH_ORIENTATION))
179    {
180      match_data->flags |= THEME_MATCH_ORIENTATION;
181     
182      if (height > width)
183        match_data->orientation = GTK_ORIENTATION_VERTICAL;
184      else
185        match_data->orientation = GTK_ORIENTATION_HORIZONTAL;
186    }
187
188  match_data->flags |= THEME_MATCH_GAP_SIDE;
189  match_data->gap_side = gap_side;
190   
191  image = match_theme_image (style, match_data);
192  if (image)
193    {
194      gint thickness;
195      GdkRectangle r1, r2, r3;
196      GdkPixbuf *pixbuf = NULL;
197      guint components = COMPONENT_ALL;
198
199      if (!draw_center)
200        components |= COMPONENT_CENTER;
201
202      if (image->gap_start)
203        pixbuf = theme_pixbuf_get_pixbuf (image->gap_start);
204
205      switch (gap_side)
206        {
207        case GTK_POS_TOP:
208          if (pixbuf)
209            thickness = gdk_pixbuf_get_height (pixbuf);
210          else
211            thickness = style->ythickness;
212         
213          if (!draw_center)
214            components |= COMPONENT_NORTH_WEST | COMPONENT_NORTH | COMPONENT_NORTH_EAST;
215
216          r1.x      = x;
217          r1.y      = y;
218          r1.width  = gap_x;
219          r1.height = thickness;
220          r2.x      = x + gap_x;
221          r2.y      = y;
222          r2.width  = gap_width;
223          r2.height = thickness;
224          r3.x      = x + gap_x + gap_width;
225          r3.y      = y;
226          r3.width  = width - (gap_x + gap_width);
227          r3.height = thickness;
228          break;
229         
230        case GTK_POS_BOTTOM:
231          if (pixbuf)
232            thickness = gdk_pixbuf_get_height (pixbuf);
233          else
234            thickness = style->ythickness;
235
236          if (!draw_center)
237            components |= COMPONENT_SOUTH_WEST | COMPONENT_SOUTH | COMPONENT_SOUTH_EAST;
238
239          r1.x      = x;
240          r1.y      = y + height - thickness;
241          r1.width  = gap_x;
242          r1.height = thickness;
243          r2.x      = x + gap_x;
244          r2.y      = y + height - thickness;
245          r2.width  = gap_width;
246          r2.height = thickness;
247          r3.x      = x + gap_x + gap_width;
248          r3.y      = y + height - thickness;
249          r3.width  = width - (gap_x + gap_width);
250          r3.height = thickness;
251          break;
252         
253        case GTK_POS_LEFT:
254          if (pixbuf)
255            thickness = gdk_pixbuf_get_width (pixbuf);
256          else
257            thickness = style->xthickness;
258
259          if (!draw_center)
260            components |= COMPONENT_NORTH_WEST | COMPONENT_WEST | COMPONENT_SOUTH_WEST;
261
262          r1.x      = x;
263          r1.y      = y;
264          r1.width  = thickness;
265          r1.height = gap_x;
266          r2.x      = x;
267          r2.y      = y + gap_x;
268          r2.width  = thickness;
269          r2.height = gap_width;
270          r3.x      = x;
271          r3.y      = y + gap_x + gap_width;
272          r3.width  = thickness;
273          r3.height = height - (gap_x + gap_width);
274          break;
275         
276        case GTK_POS_RIGHT:
277          if (pixbuf)
278            thickness = gdk_pixbuf_get_width (pixbuf);
279          else
280            thickness = style->xthickness;
281
282          if (!draw_center)
283            components |= COMPONENT_NORTH_EAST | COMPONENT_EAST | COMPONENT_SOUTH_EAST;
284
285          r1.x      = x + width - thickness;
286          r1.y      = y;
287          r1.width  = thickness;
288          r1.height = gap_x;
289          r2.x      = x + width - thickness;
290          r2.y      = y + gap_x;
291          r2.width  = thickness;
292          r2.height = gap_width;
293          r3.x      = x + width - thickness;
294          r3.y      = y + gap_x + gap_width;
295          r3.width  = thickness;
296          r3.height = height - (gap_x + gap_width);
297          break;
298        }
299
300      if (image->background)
301        theme_pixbuf_render (image->background,
302                             window, NULL, area, components, FALSE,
303                             x, y, width, height);
304      if (image->gap_start)
305        theme_pixbuf_render (image->gap_start,
306                             window, NULL, area, COMPONENT_ALL, FALSE,
307                             r1.x, r1.y, r1.width, r1.height);
308      if (image->gap)
309        theme_pixbuf_render (image->gap,
310                             window, NULL, area, COMPONENT_ALL, FALSE,
311                             r2.x, r2.y, r2.width, r2.height);
312      if (image->gap_end)
313        theme_pixbuf_render (image->gap_end,
314                             window, NULL, area, COMPONENT_ALL, FALSE,
315                             r3.x, r3.y, r3.width, r3.height);
316
317      return TRUE;
318    }
319  else
320    return FALSE;
321}
322
323static void
324draw_hline (GtkStyle     *style,
325            GdkWindow    *window,
326            GtkStateType  state,
327            GdkRectangle *area,
328            GtkWidget    *widget,
329            const gchar  *detail,
330            gint          x1,
331            gint          x2,
332            gint          y)
333{
334  ThemeImage *image;
335  ThemeMatchData   match_data;
336 
337  g_return_if_fail(style != NULL);
338  g_return_if_fail(window != NULL);
339
340  match_data.function = TOKEN_D_HLINE;
341  match_data.detail = (gchar *)detail;
342  match_data.flags = THEME_MATCH_ORIENTATION | THEME_MATCH_STATE;
343  match_data.state = state;
344  match_data.orientation = GTK_ORIENTATION_HORIZONTAL;
345 
346  image = match_theme_image (style, &match_data);
347  if (image)
348    {
349      if (image->background)
350        theme_pixbuf_render (image->background,
351                             window, NULL, area, COMPONENT_ALL, FALSE,
352                             x1, y, (x2 - x1) + 1, 2);
353    }
354  else
355    parent_class->draw_hline (style, window, state, area, widget, detail,
356                              x1, x2, y);
357}
358
359static void
360draw_vline (GtkStyle     *style,
361            GdkWindow    *window,
362            GtkStateType  state,
363            GdkRectangle *area,
364            GtkWidget    *widget,
365            const gchar  *detail,
366            gint          y1,
367            gint          y2,
368            gint          x)
369{
370  ThemeImage    *image;
371  ThemeMatchData match_data;
372 
373  g_return_if_fail (style != NULL);
374  g_return_if_fail (window != NULL);
375
376  match_data.function = TOKEN_D_VLINE;
377  match_data.detail = (gchar *)detail;
378  match_data.flags = THEME_MATCH_ORIENTATION | THEME_MATCH_STATE;
379  match_data.state = state;
380  match_data.orientation = GTK_ORIENTATION_VERTICAL;
381 
382  image = match_theme_image (style, &match_data);
383  if (image)
384    {
385      if (image->background)
386        theme_pixbuf_render (image->background,
387                             window, NULL, area, COMPONENT_ALL, FALSE,
388                             x, y1, 2, (y2 - y1) + 1);
389    }
390  else
391    parent_class->draw_vline (style, window, state, area, widget, detail,
392                              y1, y2, x);
393}
394
395static void
396draw_shadow(GtkStyle     *style,
397            GdkWindow    *window,
398            GtkStateType  state,
399            GtkShadowType shadow,
400            GdkRectangle *area,
401            GtkWidget    *widget,
402            const gchar  *detail,
403            gint          x,
404            gint          y,
405            gint          width,
406            gint          height)
407{
408  ThemeMatchData match_data;
409 
410  g_return_if_fail(style != NULL);
411  g_return_if_fail(window != NULL);
412
413  match_data.function = TOKEN_D_SHADOW;
414  match_data.detail = (gchar *)detail;
415  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
416  match_data.shadow = shadow;
417  match_data.state = state;
418
419  if (!draw_simple_image (style, window, area, widget, &match_data, FALSE, FALSE,
420                          x, y, width, height))
421    parent_class->draw_shadow (style, window, state, shadow, area, widget, detail,
422                               x, y, width, height);
423}
424
425/* This function makes up for some brokeness in gtkrange.c
426 * where we never get the full arrow of the stepper button
427 * and the type of button in a single drawing function.
428 *
429 * It doesn't work correctly when the scrollbar is squished
430 * to the point we don't have room for full-sized steppers.
431 */
432static void
433reverse_engineer_stepper_box (GtkWidget    *range,
434                              GtkArrowType  arrow_type,
435                              gint         *x,
436                              gint         *y,
437                              gint         *width,
438                              gint         *height)
439{
440  gint slider_width = 14, stepper_size = 14;
441  gint box_width;
442  gint box_height;
443 
444  if (range)
445    {
446      gtk_widget_style_get (range,
447                            "slider_width", &slider_width,
448                            "stepper_size", &stepper_size,
449                            NULL);
450    }
451       
452  if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
453    {
454      box_width = slider_width;
455      box_height = stepper_size;
456    }
457  else
458    {
459      box_width = stepper_size;
460      box_height = slider_width;
461    }
462
463  *x = *x - (box_width - *width) / 2;
464  *y = *y - (box_height - *height) / 2;
465  *width = box_width;
466  *height = box_height;
467}
468
469static void
470draw_arrow (GtkStyle     *style,
471            GdkWindow    *window,
472            GtkStateType  state,
473            GtkShadowType shadow,
474            GdkRectangle *area,
475            GtkWidget    *widget,
476            const gchar  *detail,
477            GtkArrowType  arrow_direction,
478            gint          fill,
479            gint          x,
480            gint          y,
481            gint          width,
482            gint          height)
483{
484  ThemeMatchData match_data;
485 
486  g_return_if_fail(style != NULL);
487  g_return_if_fail(window != NULL);
488
489  if (detail &&
490      (strcmp (detail, "hscrollbar") == 0 || strcmp (detail, "vscrollbar") == 0))
491    {
492      /* This is a hack to work around the fact that scrollbar steppers are drawn
493       * as a box + arrow, so we never have
494       *
495       *   The full bounding box of the scrollbar
496       *   The arrow direction
497       *
498       * At the same time. We simulate an extra paint function, "STEPPER", by doing
499       * nothing for the box, and then here, reverse engineering the box that
500       * was passed to draw box and using that
501       */
502      gint box_x = x;
503      gint box_y = y;
504      gint box_width = width;
505      gint box_height = height;
506
507      reverse_engineer_stepper_box (widget, arrow_direction,
508                                    &box_x, &box_y, &box_width, &box_height);
509
510      match_data.function = TOKEN_D_STEPPER;
511      match_data.detail = (gchar *)detail;
512      match_data.flags = (THEME_MATCH_SHADOW |
513                          THEME_MATCH_STATE |
514                          THEME_MATCH_ARROW_DIRECTION);
515      match_data.shadow = shadow;
516      match_data.state = state;
517      match_data.arrow_direction = arrow_direction;
518     
519      if (draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
520                             box_x, box_y, box_width, box_height))
521        {
522          /* The theme included stepper images, we're done */
523          return;
524        }
525
526      /* Otherwise, draw the full box, and fall through to draw the arrow
527       */
528      match_data.function = TOKEN_D_BOX;
529      match_data.detail = (gchar *)detail;
530      match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
531      match_data.shadow = shadow;
532      match_data.state = state;
533     
534      if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
535                              box_x, box_y, box_width, box_height))
536        parent_class->draw_box (style, window, state, shadow, area, widget, detail,
537                                box_x, box_y, box_width, box_height);
538    }
539
540
541  match_data.function = TOKEN_D_ARROW;
542  match_data.detail = (gchar *)detail;
543  match_data.flags = (THEME_MATCH_SHADOW |
544                      THEME_MATCH_STATE |
545                      THEME_MATCH_ARROW_DIRECTION);
546  match_data.shadow = shadow;
547  match_data.state = state;
548  match_data.arrow_direction = arrow_direction;
549 
550  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
551                          x, y, width, height))
552    parent_class->draw_arrow (style, window, state, shadow, area, widget, detail,
553                              arrow_direction, fill, x, y, width, height);
554}
555
556static void
557draw_diamond (GtkStyle     *style,
558              GdkWindow    *window,
559              GtkStateType  state,
560              GtkShadowType shadow,
561              GdkRectangle *area,
562              GtkWidget    *widget,
563              const gchar  *detail,
564              gint          x,
565              gint          y,
566              gint          width,
567              gint          height)
568{
569  ThemeMatchData match_data;
570 
571  g_return_if_fail(style != NULL);
572  g_return_if_fail(window != NULL);
573
574  match_data.function = TOKEN_D_DIAMOND;
575  match_data.detail = (gchar *)detail;
576  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
577  match_data.shadow = shadow;
578  match_data.state = state;
579 
580  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
581                          x, y, width, height))
582    parent_class->draw_diamond (style, window, state, shadow, area, widget, detail,
583                                x, y, width, height);
584}
585
586static void
587draw_string (GtkStyle * style,
588             GdkWindow * window,
589             GtkStateType state,
590             GdkRectangle * area,
591             GtkWidget * widget,
592             const gchar *detail,
593             gint x,
594             gint y,
595             const gchar * string)
596{
597  g_return_if_fail(style != NULL);
598  g_return_if_fail(window != NULL);
599
600  if (state == GTK_STATE_INSENSITIVE)
601    {
602      if (area)
603        {
604          gdk_gc_set_clip_rectangle(style->white_gc, area);
605          gdk_gc_set_clip_rectangle(style->fg_gc[state], area);
606        }
607
608      gdk_draw_string(window, gtk_style_get_font (style), style->fg_gc[state], x, y, string);
609     
610      if (area)
611        {
612          gdk_gc_set_clip_rectangle(style->white_gc, NULL);
613          gdk_gc_set_clip_rectangle(style->fg_gc[state], NULL);
614        }
615    }
616  else
617    {
618      gdk_gc_set_clip_rectangle(style->fg_gc[state], area);
619      gdk_draw_string(window, gtk_style_get_font (style), style->fg_gc[state], x, y, string);
620      gdk_gc_set_clip_rectangle(style->fg_gc[state], NULL);
621    }
622}
623
624static void
625draw_box (GtkStyle     *style,
626          GdkWindow    *window,
627          GtkStateType  state,
628          GtkShadowType shadow,
629          GdkRectangle *area,
630          GtkWidget    *widget,
631          const gchar  *detail,
632          gint          x,
633          gint          y,
634          gint          width,
635          gint          height)
636{
637  ThemeMatchData match_data;
638
639  g_return_if_fail(style != NULL);
640  g_return_if_fail(window != NULL);
641
642  if (detail &&
643      (strcmp (detail, "hscrollbar") == 0 || strcmp (detail, "vscrollbar") == 0))
644    {
645      /* We handle this in draw_arrow */
646      return;
647    }
648
649  match_data.function = TOKEN_D_BOX;
650  match_data.detail = (gchar *)detail;
651  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
652  match_data.shadow = shadow;
653  match_data.state = state;
654
655  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
656                          x, y, width, height)) {
657    parent_class->draw_box (style, window, state, shadow, area, widget, detail,
658                            x, y, width, height);
659  }
660}
661
662static void
663draw_flat_box (GtkStyle     *style,
664               GdkWindow    *window,
665               GtkStateType  state,
666               GtkShadowType shadow,
667               GdkRectangle *area,
668               GtkWidget    *widget,
669               const gchar  *detail,
670               gint          x,
671               gint          y,
672               gint          width,
673               gint          height)
674{
675  ThemeMatchData match_data;
676 
677  g_return_if_fail(style != NULL);
678  g_return_if_fail(window != NULL);
679
680  match_data.function = TOKEN_D_FLAT_BOX;
681  match_data.detail = (gchar *)detail;
682  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
683  match_data.shadow = shadow;
684  match_data.state = state;
685
686  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
687                          x, y, width, height))
688    parent_class->draw_flat_box (style, window, state, shadow, area, widget, detail,
689                                 x, y, width, height);
690}
691
692static void
693draw_check (GtkStyle     *style,
694            GdkWindow    *window,
695            GtkStateType  state,
696            GtkShadowType shadow,
697            GdkRectangle *area,
698            GtkWidget    *widget,
699            const gchar  *detail,
700            gint          x,
701            gint          y,
702            gint          width,
703            gint          height)
704{
705  ThemeMatchData match_data;
706 
707  g_return_if_fail(style != NULL);
708  g_return_if_fail(window != NULL);
709
710  match_data.function = TOKEN_D_CHECK;
711  match_data.detail = (gchar *)detail;
712  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
713  match_data.shadow = shadow;
714  match_data.state = state;
715 
716  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
717                          x, y, width, height))
718    parent_class->draw_check (style, window, state, shadow, area, widget, detail,
719                              x, y, width, height);
720}
721
722static void
723draw_option (GtkStyle      *style,
724             GdkWindow     *window,
725             GtkStateType  state,
726             GtkShadowType shadow,
727             GdkRectangle *area,
728             GtkWidget    *widget,
729             const gchar  *detail,
730             gint          x,
731             gint          y,
732             gint          width,
733             gint          height)
734{
735  ThemeMatchData match_data;
736 
737  g_return_if_fail(style != NULL);
738  g_return_if_fail(window != NULL);
739
740  match_data.function = TOKEN_D_OPTION;
741  match_data.detail = (gchar *)detail;
742  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
743  match_data.shadow = shadow;
744  match_data.state = state;
745 
746  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
747                          x, y, width, height))
748    parent_class->draw_option (style, window, state, shadow, area, widget, detail,
749                               x, y, width, height);
750}
751
752static void
753draw_tab (GtkStyle     *style,
754          GdkWindow    *window,
755          GtkStateType  state,
756          GtkShadowType shadow,
757          GdkRectangle *area,
758          GtkWidget    *widget,
759          const gchar  *detail,
760          gint          x,
761          gint          y,
762          gint          width,
763          gint          height)
764{
765  ThemeMatchData match_data;
766 
767  g_return_if_fail(style != NULL);
768  g_return_if_fail(window != NULL);
769
770  match_data.function = TOKEN_D_TAB;
771  match_data.detail = (gchar *)detail;
772  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
773  match_data.shadow = shadow;
774  match_data.state = state;
775 
776  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
777                          x, y, width, height))
778    parent_class->draw_tab (style, window, state, shadow, area, widget, detail,
779                            x, y, width, height);
780}
781
782static void
783draw_shadow_gap (GtkStyle       *style,
784                 GdkWindow      *window,
785                 GtkStateType    state,
786                 GtkShadowType   shadow,
787                 GdkRectangle   *area,
788                 GtkWidget      *widget,
789                 const gchar    *detail,
790                 gint            x,
791                 gint            y,
792                 gint            width,
793                 gint            height,
794                 GtkPositionType gap_side,
795                 gint            gap_x,
796                 gint            gap_width)
797{
798  ThemeMatchData match_data;
799 
800  match_data.function = TOKEN_D_SHADOW_GAP;
801  match_data.detail = (gchar *)detail;
802  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
803  match_data.flags = (THEME_MATCH_SHADOW |
804                      THEME_MATCH_STATE |
805                      THEME_MATCH_ORIENTATION);
806  match_data.shadow = shadow;
807  match_data.state = state;
808 
809  if (!draw_gap_image (style, window, area, widget, &match_data, FALSE,
810                       x, y, width, height, gap_side, gap_x, gap_width))
811    parent_class->draw_shadow_gap (style, window, state, shadow, area, widget, detail,
812                                   x, y, width, height, gap_side, gap_x, gap_width);
813}
814
815static void
816draw_box_gap (GtkStyle       *style,
817              GdkWindow      *window,
818              GtkStateType    state,
819              GtkShadowType   shadow,
820              GdkRectangle   *area,
821              GtkWidget      *widget,
822              const gchar    *detail,
823              gint            x,
824              gint            y,
825              gint            width,
826              gint            height,
827              GtkPositionType gap_side,
828              gint            gap_x,
829              gint            gap_width)
830{
831  ThemeMatchData match_data;
832 
833  match_data.function = TOKEN_D_BOX_GAP;
834  match_data.detail = (gchar *)detail;
835  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
836  match_data.flags = (THEME_MATCH_SHADOW |
837                      THEME_MATCH_STATE |
838                      THEME_MATCH_ORIENTATION);
839  match_data.shadow = shadow;
840  match_data.state = state;
841 
842  if (!draw_gap_image (style, window, area, widget, &match_data, TRUE,
843                       x, y, width, height, gap_side, gap_x, gap_width))
844    parent_class->draw_box_gap (style, window, state, shadow, area, widget, detail,
845                                x, y, width, height, gap_side, gap_x, gap_width);
846}
847
848static void
849draw_extension (GtkStyle       *style,
850                GdkWindow      *window,
851                GtkStateType    state,
852                GtkShadowType   shadow,
853                GdkRectangle   *area,
854                GtkWidget      *widget,
855                const gchar    *detail,
856                gint            x,
857                gint            y,
858                gint            width,
859                gint            height,
860                GtkPositionType gap_side)
861{
862  ThemeMatchData match_data;
863 
864  g_return_if_fail(style != NULL);
865  g_return_if_fail(window != NULL);
866
867  /* Why? */
868  if (width >=0)
869    width++;
870  if (height >=0)
871    height++;
872 
873  match_data.function = TOKEN_D_EXTENSION;
874  match_data.detail = (gchar *)detail;
875  match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE | THEME_MATCH_GAP_SIDE;
876  match_data.shadow = shadow;
877  match_data.state = state;
878  match_data.gap_side = gap_side;
879
880  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
881                          x, y, width, height))
882    parent_class->draw_extension (style, window, state, shadow, area, widget, detail,
883                                  x, y, width, height, gap_side);
884}
885
886static void
887draw_focus (GtkStyle     *style,
888            GdkWindow    *window,
889            GtkStateType  state_type,
890            GdkRectangle *area,
891            GtkWidget    *widget,
892            const gchar  *detail,
893            gint          x,
894            gint          y,
895            gint          width,
896            gint          height)
897{
898  ThemeMatchData match_data;
899 
900  g_return_if_fail(style != NULL);
901  g_return_if_fail(window != NULL);
902
903  match_data.function = TOKEN_D_FOCUS;
904  match_data.detail = (gchar *)detail;
905  match_data.flags = 0;
906 
907  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, FALSE,
908                          x, y, width, height))
909    parent_class->draw_focus (style, window, state_type, area, widget, detail,
910                              x, y, width, height);
911}
912
913static void
914draw_slider (GtkStyle      *style,
915             GdkWindow     *window,
916             GtkStateType   state,
917             GtkShadowType  shadow,
918             GdkRectangle  *area,
919             GtkWidget     *widget,
920             const gchar   *detail,
921             gint           x,
922             gint           y,
923             gint           width,
924             gint           height,
925             GtkOrientation orientation)
926{
927  ThemeMatchData           match_data;
928 
929  g_return_if_fail(style != NULL);
930  g_return_if_fail(window != NULL);
931
932  match_data.function = TOKEN_D_SLIDER;
933  match_data.detail = (gchar *)detail;
934  match_data.flags = (THEME_MATCH_SHADOW |
935                      THEME_MATCH_STATE |
936                      THEME_MATCH_ORIENTATION);
937  match_data.shadow = shadow;
938  match_data.state = state;
939  match_data.orientation = orientation;
940
941  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
942                          x, y, width, height))
943    parent_class->draw_slider (style, window, state, shadow, area, widget, detail,
944                               x, y, width, height, orientation);
945}
946
947
948static void
949draw_handle (GtkStyle      *style,
950             GdkWindow     *window,
951             GtkStateType   state,
952             GtkShadowType  shadow,
953             GdkRectangle  *area,
954             GtkWidget     *widget,
955             const gchar   *detail,
956             gint           x,
957             gint           y,
958             gint           width,
959             gint           height,
960             GtkOrientation orientation)
961{
962  ThemeMatchData match_data;
963 
964  g_return_if_fail (style != NULL);
965  g_return_if_fail (window != NULL);
966
967  match_data.function = TOKEN_D_HANDLE;
968  match_data.detail = (gchar *)detail;
969  match_data.flags = (THEME_MATCH_SHADOW |
970                      THEME_MATCH_STATE |
971                      THEME_MATCH_ORIENTATION);
972  match_data.shadow = shadow;
973  match_data.state = state;
974  match_data.orientation = orientation;
975
976  if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
977                          x, y, width, height))
978    parent_class->draw_handle (style, window, state, shadow, area, widget, detail,
979                               x, y, width, height, orientation);
980}
981
982GType rsvg_type_style = 0;
983
984void
985rsvg_style_register_type (GTypeModule *module)
986{
987  static const GTypeInfo object_info =
988  {
989    sizeof (RsvgStyleClass),
990    (GBaseInitFunc) NULL,
991    (GBaseFinalizeFunc) NULL,
992    (GClassInitFunc) rsvg_style_class_init,
993    NULL,           /* class_finalize */
994    NULL,           /* class_data */
995    sizeof (RsvgStyle),
996    0,              /* n_preallocs */
997    (GInstanceInitFunc) rsvg_style_init,
998  };
999 
1000  rsvg_type_style = g_type_module_register_type (module,
1001                                                   GTK_TYPE_STYLE,
1002                                                   "RsvgStyle",
1003                                                   &object_info, 0);
1004}
1005
1006static void
1007rsvg_style_init (RsvgStyle *style)
1008{
1009}
1010
1011static void
1012rsvg_style_class_init (RsvgStyleClass *klass)
1013{
1014  GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
1015
1016  parent_class = g_type_class_peek_parent (klass);
1017
1018  style_class->draw_hline = draw_hline;
1019  style_class->draw_vline = draw_vline;
1020  style_class->draw_shadow = draw_shadow;
1021  style_class->draw_arrow = draw_arrow;
1022  style_class->draw_diamond = draw_diamond;
1023  style_class->draw_string = draw_string;
1024  style_class->draw_box = draw_box;
1025  style_class->draw_flat_box = draw_flat_box;
1026  style_class->draw_check = draw_check;
1027  style_class->draw_option = draw_option;
1028  style_class->draw_tab = draw_tab;
1029  style_class->draw_shadow_gap = draw_shadow_gap;
1030  style_class->draw_box_gap = draw_box_gap;
1031  style_class->draw_extension = draw_extension;
1032  style_class->draw_focus = draw_focus;
1033  style_class->draw_slider = draw_slider;
1034  style_class->draw_handle = draw_handle;
1035}
Note: See TracBrowser for help on using the repository browser.