Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  path_fill.c

  Sprache: C
 

/* Path/Fill and Stroke
 *
 * This demo shows how to use GskPath to draw shapes that are (a bit)
 * more complex than a rounded rectangle.
 *
 * It also demonstrates printing to a stream with GtkPrintDialog.
 *
 * Finally, it shows how to use GtkPopoverBin to add a context menu
 * to a widget that does not have one.
 */


#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <cairo-pdf.h>

#include "paintable.h"

#define GTK_TYPE_LOGO_PAINTABLE (gtk_logo_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkLogoPaintable, gtk_logo_paintable, GTK, LOGO_PAINTABLE, GObject)

struct _GtkLogoPaintable
{
  GObject parent_instance;

  int width;
  int height;
  GskPath *path[3];
  GdkRGBA color[3];

  GskPath *stroke_path;
  GskStroke *stroke1;
  GskStroke *stroke2;
  GdkRGBA stroke_color;
};

struct _GtkLogoPaintableClass
{
  GObjectClass parent_class;
};

static int
gtk_logo_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
  GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);

  return self->width;
}

static int
gtk_logo_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
  GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);

  return self->height;
}

static void
gtk_logo_paintable_snapshot (GdkPaintable *paintable,
                             GdkSnapshot  *snapshot,
                             double        width,
                             double        height)
{
  GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);

  for (unsigned int i = 0; i < 3; i++)
    {
      gtk_snapshot_push_fill (snapshot, self->path[i], GSK_FILL_RULE_WINDING);
      gtk_snapshot_append_color (snapshot,
                                 &self->color[i],
                                 &GRAPHENE_RECT_INIT (00, width, height));
      gtk_snapshot_pop (snapshot);
    }
  for (unsigned int i = 0; i < 3; i++)
    {
      gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke1);
      gtk_snapshot_append_color (snapshot,
                                 &self->stroke_color,
                                 &GRAPHENE_RECT_INIT (00, width, height));
      gtk_snapshot_pop (snapshot);
    }

  gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke2);
  gtk_snapshot_append_color (snapshot,
                             &self->stroke_color,
                             &GRAPHENE_RECT_INIT (00, width, height));
  gtk_snapshot_pop (snapshot);
}

static GdkPaintableFlags
gtk_logo_paintable_get_flags (GdkPaintable *paintable)
{
  return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
}

static void
gtk_logo_paintable_paintable_init (GdkPaintableInterface *iface)
{
  iface->get_intrinsic_width = gtk_logo_paintable_get_intrinsic_width;
  iface->get_intrinsic_height = gtk_logo_paintable_get_intrinsic_height;
  iface->snapshot = gtk_logo_paintable_snapshot;
  iface->get_flags = gtk_logo_paintable_get_flags;
}

/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkLogoPaintable, gtk_logo_paintable, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
                                                gtk_logo_paintable_paintable_init))

static void
gtk_logo_paintable_dispose (GObject *object)
{
  GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (object);

  for (unsigned int i = 0; i < 3; i++)
    gsk_path_unref (self->path[i]);

  gsk_path_unref (self->stroke_path);

  gsk_stroke_free (self->stroke1);
  gsk_stroke_free (self->stroke2);

  G_OBJECT_CLASS (gtk_logo_paintable_parent_class)->dispose (object);
}

static void
gtk_logo_paintable_class_init (GtkLogoPaintableClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->dispose = gtk_logo_paintable_dispose;
}

static void
gtk_logo_paintable_init (GtkLogoPaintable *self)
{
}

static GdkPaintable *
gtk_logo_paintable_new (void)
{
  GtkLogoPaintable *self;
  graphene_rect_t bounds, bounds2;

  self = g_object_new (GTK_TYPE_LOGO_PAINTABLE, NULL);

  /* Paths and colors extracted from gtk-logo.svg */
  self->path[0] = gsk_path_parse ("m3.12,66.17 -2.06,-51.46 32.93,24.7 v55.58 l-30.87,-28.82 z");
  self->path[1] = gsk_path_parse ("m34,95 49.4,-20.58 4.12,-51.46 -53.52,16.47 v55.58 z");
  self->path[2] = gsk_path_parse ("m1.06,14.71 32.93,24.7 53.52,-16.47 -36.75,-21.88 -49.7,13.65 z");

  gdk_rgba_parse (&self->color[0], "#e40000");
  gdk_rgba_parse (&self->color[1], "#7fe719");
  gdk_rgba_parse (&self->color[2], "#729fcf");

  self->stroke_path = gsk_path_parse ("m50.6,51.3 -47.3,14 z l33,23 z v-50");
  self->stroke1 = gsk_stroke_new (2.12);
  self->stroke2 = gsk_stroke_new (1.25);
  gdk_rgba_parse (&self->stroke_color, "#ffffff");

  gsk_path_get_stroke_bounds (self->path[0], self->stroke1, &bounds);
  gsk_path_get_stroke_bounds (self->path[1], self->stroke1, &bounds2);
  graphene_rect_union (&bounds, &bounds2, &bounds);
  gsk_path_get_stroke_bounds (self->path[2], self->stroke1, &bounds2);
  graphene_rect_union (&bounds, &bounds2, &bounds);
  gsk_path_get_stroke_bounds (self->stroke_path, self->stroke2, &bounds2);
  graphene_rect_union (&bounds, &bounds2, &bounds);

  self->width = bounds.origin.x + bounds.size.width;
  self->height = bounds.origin.y + bounds.size.height;

  return GDK_PAINTABLE (self);
}

static cairo_status_t
write_cairo (void                *closure,
             const unsigned char *data,
             unsigned int         length)
{
  GOutputStream *stream = closure;
  gsize written;
  GError *error = NULL;

  if (!g_output_stream_write_all (stream, data, length, &written, NULL, &error))
    {
      g_print ("Error writing pdf stream: %s\n", error->message);
      g_error_free (error);
      return CAIRO_STATUS_WRITE_ERROR;
    }

  return CAIRO_STATUS_SUCCESS;
}

static void
print_ready (GObject      *source,
             GAsyncResult *result,
             gpointer      data)
{
  GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
  GError *error = NULL;
  GOutputStream *stream;
  GtkSnapshot *snapshot;
  GdkPaintable *paintable;
  GskRenderNode *node;
  cairo_surface_t *surface;
  cairo_t *cr;

  stream = gtk_print_dialog_print_finish (dialog, result, &error);
  if (stream == NULL)
    {
      g_print ("Failed to get output stream: %s\n", error->message);
      g_error_free (error);
      return;
    }

  snapshot = gtk_snapshot_new ();
  paintable = gtk_picture_get_paintable (GTK_PICTURE (data));
  gdk_paintable_snapshot (paintable, snapshot, 100100);
  node = gtk_snapshot_free_to_node (snapshot);

  surface = cairo_pdf_surface_create_for_stream (write_cairo, stream, 100100);
  cr = cairo_create (surface);

  gsk_render_node_draw (node, cr);

  cairo_destroy (cr);
  cairo_surface_destroy (surface);
  gsk_render_node_unref (node);

  if (!g_output_stream_close (stream, NULL, &error))
    {
      if (!g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED))
        g_print ("Error from close: %s\n", error->message);
      g_error_free (error);
    }

  g_object_unref (stream);
}

static void
print (GtkWidget *picture)
{
  GtkPrintDialog *dialog;

  dialog = gtk_print_dialog_new ();

  gtk_print_dialog_print (dialog,
                          GTK_WINDOW (gtk_widget_get_root (picture)),
                          NULL,
                          NULL,
                          print_ready,
                          picture);

  g_object_unref (dialog);
}

static GMenuModel *
get_menu (void)
{
  GMenu *menu;
  GMenuItem *item;

  menu = g_menu_new ();
  item = g_menu_item_new ("Print""widget.print");
  g_menu_append_item (menu, item);
  item = g_menu_item_new ("About""app.about");
  g_menu_append_item (menu, item);
  g_object_unref (item);

  return G_MENU_MODEL (menu);
}

static void
activate_print (GSimpleAction *action,
                GVariant      *parameter,
                gpointer       user_data)
{
  print (GTK_WIDGET (user_data));
}

static GActionGroup *
get_actions (GtkWidget *widget)
{
  GSimpleActionGroup *actions;
  GActionEntry entries[] = {
    { "print", activate_print, NULL, NULL, NULL, },
  };

  actions = g_simple_action_group_new ();
  g_action_map_add_action_entries (G_ACTION_MAP (actions),
                                   entries, G_N_ELEMENTS (entries),
                                   widget);

  return G_ACTION_GROUP (actions);
}

GtkWidget *
do_path_fill (GtkWidget *do_widget)
{
  static GtkWidget *window = NULL;

  if (!window)
    {
      GtkWidget *header, *button, *label;
      GtkWidget *picture;
      GdkPaintable *paintable;
      GtkWidget *bin;
      GMenuModel *menu;
      GActionGroup *actions;

      window = gtk_window_new ();
      gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
      gtk_window_set_default_size (GTK_WINDOW (window), 100100);
      gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");

      gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (g_application_get_default ()));

      header = gtk_header_bar_new ();
      button = gtk_button_new_from_icon_name ("printer-symbolic");
      gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
      label = gtk_label_new ("Fill and Stroke");
      gtk_widget_add_css_class (label, "title");
      gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), label);
      gtk_window_set_titlebar (GTK_WINDOW (window), header);
      g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);

      paintable = gtk_logo_paintable_new ();
      picture = gtk_picture_new_for_paintable (paintable);
      gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
      gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
      g_object_unref (paintable);

      bin = gtk_popover_bin_new ();

      actions = get_actions (picture);
      gtk_widget_insert_action_group (bin, "widget", actions);
      g_object_unref (actions);

      gtk_popover_bin_set_child (GTK_POPOVER_BIN (bin), picture);

      menu = get_menu ();
      gtk_popover_bin_set_menu_model (GTK_POPOVER_BIN (bin), menu);
      g_object_unref (menu);

      gtk_popover_bin_set_handle_input (GTK_POPOVER_BIN (bin), TRUE);

      g_signal_connect_swapped (button, "clicked", G_CALLBACK (print), picture);

      gtk_window_set_child (GTK_WINDOW (window), bin);
    }

  if (!gtk_widget_get_visible (window))
    gtk_window_present (GTK_WINDOW (window));
  else
    gtk_window_destroy (GTK_WINDOW (window));

  return window;
}

Messung V0.5 in Prozent
C=98 H=94 G=95

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik