void context_brush_shape_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpContext *context; GimpBrush *brush; return_if_no_context (context, data); brush = gimp_context_get_brush (context); if (GIMP_IS_BRUSH_GENERATED (brush) && gimp_data_is_writable (GIMP_DATA (brush))) { GimpBrushGenerated *generated = GIMP_BRUSH_GENERATED (brush); GimpDisplay *display; const char *value_desc; gimp_brush_generated_set_shape (generated, (GimpBrushGeneratedShape) value); gimp_enum_get_value (GIMP_TYPE_BRUSH_GENERATED_SHAPE, value, NULL, NULL, &value_desc, NULL); display = action_data_get_display (data); if (value_desc && display) { action_message (display, G_OBJECT (brush), _("Brush Shape: %s"), value_desc); } } }
static void gimp_brush_generated_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (object); switch (property_id) { case PROP_SHAPE: g_value_set_enum (value, brush->shape); break; case PROP_RADIUS: g_value_set_double (value, brush->radius); break; case PROP_SPIKES: g_value_set_int (value, brush->spikes); break; case PROP_HARDNESS: g_value_set_double (value, brush->hardness); break; case PROP_ASPECT_RATIO: g_value_set_double (value, brush->aspect_ratio); break; case PROP_ANGLE: g_value_set_double (value, brush->angle); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
void gimp_paint_options_set_default_brush_hardness (GimpPaintOptions *paint_options, GimpBrush *brush) { g_return_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options)); g_return_if_fail (brush == NULL || GIMP_IS_BRUSH (brush)); if (! brush) brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options)); if (GIMP_IS_BRUSH_GENERATED (brush)) { GimpBrushGenerated *generated_brush = GIMP_BRUSH_GENERATED (brush); g_object_set (paint_options, "brush-hardness", (gdouble) gimp_brush_generated_get_hardness (generated_brush), NULL); } else { g_object_set (paint_options, "brush-hardness", DEFAULT_BRUSH_HARDNESS, NULL); } }
void context_brush_radius_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpContext *context; GimpBrush *brush; return_if_no_context (context, data); brush = gimp_context_get_brush (context); if (GIMP_IS_BRUSH_GENERATED (brush) && gimp_data_is_writable (GIMP_DATA (brush))) { GimpBrushGenerated *generated = GIMP_BRUSH_GENERATED (brush); GimpDisplay *display; gdouble radius; gdouble min_radius; radius = gimp_brush_generated_get_radius (generated); /* If the user uses a high precision radius adjustment command * then we allow a minimum radius of 0.1 px, otherwise we set the * minimum radius to 1.0 px and adjust the radius to 1.0 px if it * is less than 1.0 px. This prevents irritating 0.1, 1.1, 2.1 etc * radius sequences when 1.0 px steps are used. */ switch ((GimpActionSelectType) value) { case GIMP_ACTION_SELECT_SMALL_PREVIOUS: case GIMP_ACTION_SELECT_SMALL_NEXT: case GIMP_ACTION_SELECT_PERCENT_PREVIOUS: case GIMP_ACTION_SELECT_PERCENT_NEXT: min_radius = 0.1; break; default: min_radius = 1.0; if (radius < 1.0) radius = 1.0; break; } radius = action_select_value ((GimpActionSelectType) value, radius, min_radius, 4000.0, min_radius, 0.1, 1.0, 10.0, 0.05, FALSE); gimp_brush_generated_set_radius (generated, radius); display = action_data_get_display (data); if (display) { action_message (action_data_get_display (data), G_OBJECT (brush), _("Brush Radius: %2.2f"), radius); } } }
static void gimp_brush_editor_set_data (GimpDataEditor *editor, GimpData *data) { GimpBrushEditor *brush_editor = GIMP_BRUSH_EDITOR (editor); GimpBrushGeneratedShape shape = GIMP_BRUSH_GENERATED_CIRCLE; gdouble radius = 0.0; gint spikes = 2; gdouble hardness = 0.0; gdouble ratio = 0.0; gdouble angle = 0.0; gdouble spacing = 0.0; if (editor->data) g_signal_handlers_disconnect_by_func (editor->data, gimp_brush_editor_notify_brush, editor); GIMP_DATA_EDITOR_CLASS (parent_class)->set_data (editor, data); if (editor->data) g_signal_connect (editor->data, "notify", G_CALLBACK (gimp_brush_editor_notify_brush), editor); gimp_view_set_viewable (GIMP_VIEW (editor->view), GIMP_VIEWABLE (data)); if (editor->data) { spacing = gimp_brush_get_spacing (GIMP_BRUSH (editor->data)); if (GIMP_IS_BRUSH_GENERATED (editor->data)) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (editor->data); shape = gimp_brush_generated_get_shape (brush); radius = gimp_brush_generated_get_radius (brush); spikes = gimp_brush_generated_get_spikes (brush); hardness = gimp_brush_generated_get_hardness (brush); ratio = gimp_brush_generated_get_aspect_ratio (brush); angle = gimp_brush_generated_get_angle (brush); } } gtk_widget_set_sensitive (brush_editor->options_box, editor->data_editable); gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (brush_editor->shape_group), shape); gtk_adjustment_set_value (brush_editor->radius_data, radius); gtk_adjustment_set_value (brush_editor->spikes_data, spikes); gtk_adjustment_set_value (brush_editor->hardness_data, hardness); gtk_adjustment_set_value (brush_editor->aspect_ratio_data, ratio); gtk_adjustment_set_value (brush_editor->angle_data, angle); gtk_adjustment_set_value (brush_editor->spacing_data, spacing); }
static void gimp_brush_editor_update_brush (GtkAdjustment *adjustment, GimpBrushEditor *editor) { GimpBrushGenerated *brush; gdouble radius; gint spikes; gdouble hardness; gdouble ratio; gdouble angle; gdouble spacing; if (! GIMP_IS_BRUSH_GENERATED (GIMP_DATA_EDITOR (editor)->data)) return; brush = GIMP_BRUSH_GENERATED (GIMP_DATA_EDITOR (editor)->data); radius = gtk_adjustment_get_value (editor->radius_data); spikes = ROUND (gtk_adjustment_get_value (editor->spikes_data)); hardness = gtk_adjustment_get_value (editor->hardness_data); ratio = gtk_adjustment_get_value (editor->aspect_ratio_data); angle = gtk_adjustment_get_value (editor->angle_data); spacing = gtk_adjustment_get_value (editor->spacing_data); if (radius != gimp_brush_generated_get_radius (brush) || spikes != gimp_brush_generated_get_spikes (brush) || hardness != gimp_brush_generated_get_hardness (brush) || ratio != gimp_brush_generated_get_aspect_ratio (brush) || angle != gimp_brush_generated_get_angle (brush) || spacing != gimp_brush_get_spacing (GIMP_BRUSH (brush))) { g_signal_handlers_block_by_func (brush, gimp_brush_editor_notify_brush, editor); gimp_data_freeze (GIMP_DATA (brush)); g_object_freeze_notify (G_OBJECT (brush)); gimp_brush_generated_set_radius (brush, radius); gimp_brush_generated_set_spikes (brush, spikes); gimp_brush_generated_set_hardness (brush, hardness); gimp_brush_generated_set_aspect_ratio (brush, ratio); gimp_brush_generated_set_angle (brush, angle); gimp_brush_set_spacing (GIMP_BRUSH (brush), spacing); g_object_thaw_notify (G_OBJECT (brush)); gimp_data_thaw (GIMP_DATA (brush)); g_signal_handlers_unblock_by_func (brush, gimp_brush_editor_notify_brush, editor); } }
static GimpData * gimp_brush_generated_duplicate (GimpData *data) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data); return gimp_brush_generated_new (GIMP_OBJECT (brush)->name, brush->shape, brush->radius, brush->spikes, brush->hardness, brush->aspect_ratio, brush->angle); }
static TempBuf * gimp_brush_generated_scale_mask (GimpBrush *gbrush, gdouble scale) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush); return gimp_brush_generated_calc (brush, brush->shape, brush->radius * scale, brush->spikes, brush->hardness, brush->aspect_ratio, brush->angle, NULL, NULL); }
static void gimp_brush_generated_transform_size (GimpBrush *gbrush, gdouble scale, gdouble aspect_ratio, gdouble angle, gint *width, gint *height) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush); gint half_width; gint half_height; gdouble ratio; if (aspect_ratio == 0.0) { ratio = brush->aspect_ratio; } else { ratio = MIN (fabs (aspect_ratio) + 1, 20); /* Since generated brushes are symmetric the dont have input * for aspect ratios < 1.0. its same as rotate by 90 degrees and * 1 / ratio. So we fix the input up for this case. */ if (aspect_ratio < 0.0) { angle = angle + 0.25; } } gimp_brush_generated_get_half_size (brush, brush->shape, brush->radius * scale, brush->spikes, brush->hardness, ratio, (brush->angle + 360 * angle), &half_width, &half_height, NULL, NULL, NULL, NULL); *width = half_width * 2 + 1; *height = half_height * 2 + 1; }
void context_brush_angle_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpContext *context; GimpBrush *brush; return_if_no_context (context, data); brush = gimp_context_get_brush (context); if (GIMP_IS_BRUSH_GENERATED (brush) && gimp_data_is_writable (GIMP_DATA (brush))) { GimpBrushGenerated *generated = GIMP_BRUSH_GENERATED (brush); GimpDisplay *display; gdouble angle; angle = gimp_brush_generated_get_angle (generated); if (value == GIMP_ACTION_SELECT_FIRST) angle = 0.0; else if (value == GIMP_ACTION_SELECT_LAST) angle = 90.0; else angle = action_select_value ((GimpActionSelectType) value, angle, 0.0, 180.0, 0.0, 0.1, 1.0, 15.0, 0.1, TRUE); gimp_brush_generated_set_angle (generated, angle); display = action_data_get_display (data); if (display) { action_message (action_data_get_display (data), G_OBJECT (brush), _("Brush Angle: %2.2f"), angle); } } }
static void gimp_brush_generated_dirty (GimpData *data) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data); GimpBrush *gbrush = GIMP_BRUSH (brush); if (gbrush->mask) temp_buf_free (gbrush->mask); gbrush->mask = gimp_brush_generated_calc (brush, brush->shape, brush->radius, brush->spikes, brush->hardness, brush->aspect_ratio, brush->angle, &gbrush->x_axis, &gbrush->y_axis); GIMP_DATA_CLASS (parent_class)->dirty (data); }
static void gimp_brush_editor_update_shape (GtkWidget *widget, GimpBrushEditor *editor) { GimpBrushGenerated *brush; if (! GIMP_IS_BRUSH_GENERATED (GIMP_DATA_EDITOR (editor)->data)) return; brush = GIMP_BRUSH_GENERATED (GIMP_DATA_EDITOR (editor)->data); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { GimpBrushGeneratedShape shape; shape = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "gimp-item-data")); if (gimp_brush_generated_get_shape (brush) != shape) gimp_brush_generated_set_shape (brush, shape); } }
static void gimp_brush_generated_transform_size (GimpBrush *gbrush, gdouble scale, gdouble aspect_ratio, gdouble angle, gint *width, gint *height) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush); gdouble ratio; ratio = fabs (aspect_ratio) * 19.0 / 20.0 + 1.0; ratio = MIN (ratio, 20); /* Since generated brushes are symmetric they don't have aspect * ratios < 1.0. it's the same as rotating by 90 degrees and 1 / * ratio, so we fix the input for this case. */ if (aspect_ratio < 0.0) angle = angle + 0.25; angle *= 360; if (angle < 0.0) angle = -1.0 * fmod (angle, 180.0); else if (angle > 180.0) angle = fmod (angle, 180.0); gimp_brush_generated_get_size (brush, brush->shape, brush->radius * scale, brush->spikes, brush->hardness, ratio, angle, width, height, NULL, NULL, NULL, NULL); }
static void gimp_brush_generated_scale_size (GimpBrush *gbrush, gdouble scale, gint *width, gint *height) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush); gint half_width; gint half_height; gimp_brush_generated_get_half_size (brush, brush->shape, brush->radius * scale, brush->spikes, brush->hardness, brush->aspect_ratio, brush->angle, &half_width, &half_height, NULL, NULL, NULL, NULL); *width = half_width * 2 + 1; *height = half_height * 2 + 1; }
static TempBuf * gimp_brush_generated_transform_mask (GimpBrush *gbrush, gdouble scale, gdouble aspect_ratio, gdouble angle, gdouble hardness) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush); gdouble ratio; if (aspect_ratio == 0.0) { ratio = brush->aspect_ratio; } else { ratio = MIN (fabs (aspect_ratio) + 1, 20); /* Since generated brushes are symmetric the dont have input * for aspect ratios < 1.0. its same as rotate by 90 degrees and * 1 / ratio. So we fix the input up for this case. */ if (aspect_ratio < 0.0) { angle = angle + 0.25; } } return gimp_brush_generated_calc (brush, brush->shape, brush->radius * scale, brush->spikes, brush->hardness * hardness, ratio, (brush->angle + 360 * angle), NULL, NULL); }
gboolean gimp_brush_generated_save (GimpData *data, GOutputStream *output, GError **error) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data); const gchar *name = gimp_object_get_name (data); GString *string; gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; gboolean have_shape = FALSE; g_return_val_if_fail (name != NULL && *name != '\0', FALSE); /* write magic header */ string = g_string_new ("GIMP-VBR\n"); /* write version */ if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE || brush->spikes > 2) { g_string_append (string, "1.5\n"); have_shape = TRUE; } else { g_string_append (string, "1.0\n"); } /* write name */ g_string_append_printf (string, "%.255s\n", name); if (have_shape) { GEnumClass *enum_class; GEnumValue *shape_val; enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE); /* write shape */ shape_val = g_enum_get_value (enum_class, brush->shape); g_string_append_printf (string, "%s\n", shape_val->value_nick); } /* write brush spacing */ g_string_append_printf (string, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", gimp_brush_get_spacing (GIMP_BRUSH (brush)))); /* write brush radius */ g_string_append_printf (string, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->radius)); if (have_shape) { /* write brush spikes */ g_string_append_printf (string, "%d\n", brush->spikes); } /* write brush hardness */ g_string_append_printf (string, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->hardness)); /* write brush aspect_ratio */ g_string_append_printf (string, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->aspect_ratio)); /* write brush angle */ g_string_append_printf (string, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->angle)); if (! g_output_stream_write_all (output, string->str, string->len, NULL, NULL, error)) { g_string_free (string, TRUE); return FALSE; } g_string_free (string, TRUE); return TRUE; }
gboolean gimp_brush_generated_save (GimpData *data, GError **error) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data); const gchar *name = gimp_object_get_name (data); FILE *file; gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; gboolean have_shape = FALSE; g_return_val_if_fail (name != NULL && *name != '\0', FALSE); file = g_fopen (gimp_data_get_filename (data), "wb"); if (! file) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN, _("Could not open '%s' for writing: %s"), gimp_filename_to_utf8 (gimp_data_get_filename (data)), g_strerror (errno)); return FALSE; } /* write magic header */ fprintf (file, "GIMP-VBR\n"); /* write version */ if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE || brush->spikes > 2) { fprintf (file, "1.5\n"); have_shape = TRUE; } else { fprintf (file, "1.0\n"); } /* write name */ fprintf (file, "%.255s\n", name); if (have_shape) { GEnumClass *enum_class; GEnumValue *shape_val; enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE); /* write shape */ shape_val = g_enum_get_value (enum_class, brush->shape); fprintf (file, "%s\n", shape_val->value_nick); } /* write brush spacing */ fprintf (file, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", gimp_brush_get_spacing (GIMP_BRUSH (brush)))); /* write brush radius */ fprintf (file, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->radius)); if (have_shape) { /* write brush spikes */ fprintf (file, "%d\n", brush->spikes); } /* write brush hardness */ fprintf (file, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->hardness)); /* write brush aspect_ratio */ fprintf (file, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->aspect_ratio)); /* write brush angle */ fprintf (file, "%s\n", g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", brush->angle)); fclose (file); return TRUE; }