mirror of https://github.com/GNOME/gimp.git
----------------------------------------------------------------------
---------------------------------------------------------------------- Modified Files: ChangeLog app/brush_edit.c app/brush_edit.h app/brush_select.c app/gimpbrush.c app/gimpbrushgenerated.c app/gimpbrushgenerated.h app/gimpbrushlist.c added support for loading generated brushes and updated the brush_edit a bit. Added Files: data/brushes/round1.vbr A sample generated brush.
This commit is contained in:
parent
440f4220e6
commit
b2f1e85cf3
|
@ -1,3 +1,12 @@
|
|||
Thu Jul 16 04:38:19 PDT 1998 Jay Cox <jaycox@earthlink.net>
|
||||
|
||||
* brush_edit.[ch]: added a zoom indicator on the preview
|
||||
|
||||
* gimpbrushgenerated.[ch] gimpbrushlist.c: added support
|
||||
for loading generated brushes.
|
||||
|
||||
* data/brushes/round01.vbr: a sample generated brush
|
||||
|
||||
Wed Jul 15 22:06:32 CDT 1998 Shawn T. Amundson <amundson@gimp.org>
|
||||
|
||||
* Cursor location in statusbar
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
#include "math.h"
|
||||
|
||||
|
||||
static void
|
||||
brush_edit_close_callback (GtkWidget *w, void *data);
|
||||
static void brush_edit_close_callback (GtkWidget *w, void *data);
|
||||
static gint brush_edit_preview_resize (GtkWidget *widget, GdkEvent *event,
|
||||
BrushEditGeneratedWindow *begw);
|
||||
|
||||
/* the action area structure */
|
||||
static ActionAreaItem action_items[] =
|
||||
|
@ -98,7 +99,8 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
gchar *src, *buf;
|
||||
|
||||
brush_edit_clear_preview (begw);
|
||||
|
||||
if (brush == NULL)
|
||||
return TRUE;
|
||||
scale = MAX(ceil(brush->mask->width/(float)begw->preview->requisition.width),
|
||||
ceil(brush->mask->height/(float)begw->preview->requisition.height));
|
||||
|
||||
|
@ -113,11 +115,8 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
|
||||
for (y = ystart; y < yend; y++)
|
||||
{
|
||||
/* Invert the mask for display. We're doing this because
|
||||
* a value of 255 in the mask means it is full intensity.
|
||||
* However, it makes more sense for full intensity to show
|
||||
* up as black in this brush preview window...
|
||||
*/
|
||||
/* Invert the mask for display.
|
||||
*/
|
||||
for (x = 0; x < width; x++)
|
||||
buf[x] = 255 - src[x*scale];
|
||||
gtk_preview_draw_row (GTK_PREVIEW (begw->preview), (guchar *)buf, xo, y,
|
||||
|
@ -125,6 +124,14 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
src += brush->mask->width*scale;
|
||||
}
|
||||
g_free(buf);
|
||||
if (begw->scale != scale)
|
||||
{
|
||||
char str[255];
|
||||
begw->scale = scale;
|
||||
g_snprintf(str, 200, "%d:1", scale);
|
||||
gtk_label_set(GTK_LABEL(begw->scale_label), str);
|
||||
gtk_widget_draw(begw->scale_label, NULL);
|
||||
}
|
||||
gtk_widget_draw(begw->preview, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -142,7 +149,10 @@ brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
|||
}
|
||||
brush = GIMP_BRUSH_GENERATED(gbrush);
|
||||
if (begw->brush)
|
||||
{
|
||||
gtk_signal_disconnect_by_data(GTK_OBJECT(begw->brush), begw);
|
||||
gtk_object_unref(GTK_OBJECT(begw->brush));
|
||||
}
|
||||
if (begw)
|
||||
{
|
||||
gtk_signal_connect(GTK_OBJECT (brush), "dirty",
|
||||
|
@ -158,6 +168,7 @@ brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
|||
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->aspect_ratio_data),
|
||||
gimp_brush_generated_get_aspect_ratio(brush));
|
||||
begw->brush = brush;
|
||||
gtk_object_ref(GTK_OBJECT(begw->brush));
|
||||
brush_edit_brush_dirty_callback(GIMP_BRUSH(brush), begw);
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +186,6 @@ brush_edit_generated_new ()
|
|||
|
||||
begw = g_malloc (sizeof (BrushEditGeneratedWindow));
|
||||
begw->brush = NULL;
|
||||
begw->redraw = TRUE;
|
||||
|
||||
begw->shell = gtk_dialog_new ();
|
||||
gtk_window_set_wmclass (GTK_WINDOW (begw->shell), "generatedbrusheditor",
|
||||
|
@ -201,12 +211,20 @@ brush_edit_generated_new ()
|
|||
gtk_box_pack_start (GTK_BOX (vbox), begw->frame, TRUE, TRUE, 0);
|
||||
|
||||
begw->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview), 100, 100);
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview), 125, 100);
|
||||
gtk_signal_connect_after (GTK_OBJECT(begw->frame), "size_allocate",
|
||||
(GtkSignalFunc) brush_edit_preview_resize,
|
||||
begw);
|
||||
gtk_container_add (GTK_CONTAINER (begw->frame), begw->preview);
|
||||
|
||||
gtk_widget_show(begw->preview);
|
||||
gtk_widget_show(begw->frame);
|
||||
|
||||
/* table for sliders/labels */
|
||||
begw->scale_label = gtk_label_new ("-1:1");
|
||||
gtk_box_pack_start (GTK_BOX (vbox), begw->scale_label, FALSE, FALSE, 0);
|
||||
begw->scale = -1;
|
||||
gtk_widget_show(begw->scale_label);
|
||||
/* table for sliders/labels */
|
||||
table = gtk_table_new(2, 4, FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
||||
|
@ -290,6 +308,21 @@ brush_edit_generated_new ()
|
|||
return begw;
|
||||
}
|
||||
|
||||
static gint
|
||||
brush_edit_preview_resize (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
BrushEditGeneratedWindow *begw)
|
||||
{
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview),
|
||||
widget->allocation.width - 4,
|
||||
widget->allocation.height - 4);
|
||||
|
||||
/* update the display */
|
||||
if (begw->brush)
|
||||
brush_edit_brush_dirty_callback(GIMP_BRUSH(begw->brush), begw);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
brush_edit_close_callback (GtkWidget *w, void *data)
|
||||
{
|
||||
|
|
|
@ -28,17 +28,16 @@ typedef struct _BrushEditGeneratedWindow
|
|||
GtkWidget *shell;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *scale_label;
|
||||
GtkWidget *options_box;
|
||||
GtkAdjustment *radius_data;
|
||||
GtkAdjustment *hardness_data;
|
||||
GtkAdjustment *angle_data;
|
||||
GtkAdjustment *aspect_ratio_data;
|
||||
int width, height;
|
||||
int cell_width, cell_height;
|
||||
int redraw;
|
||||
/* Brush preview */
|
||||
GtkWidget *brush_preview;
|
||||
GimpBrushGenerated *brush;
|
||||
int scale;
|
||||
} BrushEditGeneratedWindow;
|
||||
|
||||
void brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
||||
|
|
|
@ -857,15 +857,18 @@ edit_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
|
|||
}
|
||||
}
|
||||
else
|
||||
g_message("We are all out of brush editors today, please try again tomorrow\n");
|
||||
g_message("We are all fresh out of brush editors today,\n"
|
||||
"please write your own or try back tomorrow\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
new_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
|
||||
{
|
||||
gimp_brush_list_add(brush_list,
|
||||
GIMP_BRUSH(gimp_brush_generated_new(10, .5, 0.0, 1.0)));
|
||||
GimpBrushGenerated *brush;
|
||||
brush = gimp_brush_generated_new(10, .5, 0.0, 1.0);
|
||||
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
|
||||
select_brush(GIMP_BRUSH(brush));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -196,11 +196,6 @@ gimp_brush_load(GimpBrush *brush, char *filename)
|
|||
fp)) < header.width * header.height)
|
||||
g_message ("GIMP brush file appears to be truncated.");
|
||||
break;
|
||||
case 3:
|
||||
fprintf(stderr, "loading generated brush\n");
|
||||
fprintf(stderr, "currently unimplemeted expect a crash to occur any second\n");
|
||||
fprintf(stderr, "finished loading generated brush\n");
|
||||
break;
|
||||
default:
|
||||
g_message ("Unknown brush format version #%d in \"%s\"\n",
|
||||
header.version, filename);
|
||||
|
@ -216,9 +211,6 @@ gimp_brush_load(GimpBrush *brush, char *filename)
|
|||
if (stingy_memory_use)
|
||||
temp_buf_swap (brush->mask);
|
||||
|
||||
/* TODO: get rid of this call */
|
||||
gimp_brush_list_add(brush_list, brush);
|
||||
|
||||
/* Check if the current brush is the default one */
|
||||
/* lets see if it works with out this for now */
|
||||
/* if (strcmp(default_brush, prune_filename(filename)) == 0) {
|
||||
|
|
|
@ -196,11 +196,6 @@ gimp_brush_load(GimpBrush *brush, char *filename)
|
|||
fp)) < header.width * header.height)
|
||||
g_message ("GIMP brush file appears to be truncated.");
|
||||
break;
|
||||
case 3:
|
||||
fprintf(stderr, "loading generated brush\n");
|
||||
fprintf(stderr, "currently unimplemeted expect a crash to occur any second\n");
|
||||
fprintf(stderr, "finished loading generated brush\n");
|
||||
break;
|
||||
default:
|
||||
g_message ("Unknown brush format version #%d in \"%s\"\n",
|
||||
header.version, filename);
|
||||
|
@ -216,9 +211,6 @@ gimp_brush_load(GimpBrush *brush, char *filename)
|
|||
if (stingy_memory_use)
|
||||
temp_buf_swap (brush->mask);
|
||||
|
||||
/* TODO: get rid of this call */
|
||||
gimp_brush_list_add(brush_list, brush);
|
||||
|
||||
/* Check if the current brush is the default one */
|
||||
/* lets see if it works with out this for now */
|
||||
/* if (strcmp(default_brush, prune_filename(filename)) == 0) {
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "appenv.h"
|
||||
#include "gimpbrushgenerated.h"
|
||||
#include "gimpbrushlist.h"
|
||||
#include "paint_core.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define OVERSAMPLING 5
|
||||
|
||||
|
@ -96,14 +96,89 @@ GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
|
|||
/* render brush mask */
|
||||
gimp_brush_generated_generate(brush);
|
||||
|
||||
/* add brush to brush list */
|
||||
/* FIXME: Get rid of this */
|
||||
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
|
||||
select_brush(GIMP_BRUSH(brush));
|
||||
return brush;
|
||||
}
|
||||
|
||||
GimpBrushGenerated *
|
||||
gimp_brush_generated_load (char *file_name)
|
||||
{
|
||||
GimpBrushGenerated *brush;
|
||||
FILE *fp;
|
||||
char string[256];
|
||||
float fl;
|
||||
float version;
|
||||
if ((fp = fopen(file_name, "r")) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* make sure the file we are reading is the right type */
|
||||
fscanf(fp, "%8s", string);
|
||||
g_return_val_if_fail(strcmp(string, "GIMP-VBR") == 0, NULL);
|
||||
/* make sure we are reading a compatible version */
|
||||
fscanf(fp, "%f", &version);
|
||||
g_return_val_if_fail(version < 2.0, NULL);
|
||||
|
||||
/* create new brush */
|
||||
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type()));
|
||||
GIMP_BRUSH(brush)->filename = g_strdup (file_name);
|
||||
gimp_brush_generated_freeze(brush);
|
||||
|
||||
/* read name */
|
||||
fscanf(fp, "%255s", string);
|
||||
GIMP_BRUSH(brush)->name = g_strdup (string);
|
||||
/* read brush spacing */
|
||||
fscanf(fp, "%f", &fl);
|
||||
GIMP_BRUSH(brush)->spacing = fl;
|
||||
/* read brush radius */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_radius(brush, fl);
|
||||
/* read brush hardness */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_hardness(brush, fl);
|
||||
/* read brush aspect_ratio */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_aspect_ratio(brush, fl);
|
||||
/* read brush angle */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_angle(brush, fl);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
gimp_brush_generated_thaw(brush);
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_save (GimpBrushGenerated *brush,
|
||||
char *file_name)
|
||||
{
|
||||
/* WARNING: untested function */
|
||||
FILE *fp;
|
||||
if ((fp = fopen(file_name, "w")) == NULL)
|
||||
{
|
||||
g_warning("Unable to save file %s", file_name);
|
||||
return;
|
||||
}
|
||||
/* write magic header */
|
||||
fprintf(fp, "GIMP-VBR\n");
|
||||
/* write version */
|
||||
fprintf(fp, "1.0\n");
|
||||
/* write name */
|
||||
fprintf(fp, "%s", GIMP_BRUSH(brush)->name);
|
||||
/* write brush spacing */
|
||||
fprintf(fp, "%f", (float)GIMP_BRUSH(brush)->spacing);
|
||||
/* write brush radius */
|
||||
fprintf(fp, "%f", brush->radius);
|
||||
/* write brush hardness */
|
||||
fprintf(fp, "%f", brush->hardness);
|
||||
/* write brush aspect_ratio */
|
||||
fprintf(fp, "%f", brush->aspect_ratio);
|
||||
/* write brush angle */
|
||||
fprintf(fp, "%f", brush->angle);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_freeze(GimpBrushGenerated *brush)
|
||||
{
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "appenv.h"
|
||||
#include "gimpbrushgenerated.h"
|
||||
#include "gimpbrushlist.h"
|
||||
#include "paint_core.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define OVERSAMPLING 5
|
||||
|
||||
|
@ -96,14 +96,89 @@ GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
|
|||
/* render brush mask */
|
||||
gimp_brush_generated_generate(brush);
|
||||
|
||||
/* add brush to brush list */
|
||||
/* FIXME: Get rid of this */
|
||||
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
|
||||
select_brush(GIMP_BRUSH(brush));
|
||||
return brush;
|
||||
}
|
||||
|
||||
GimpBrushGenerated *
|
||||
gimp_brush_generated_load (char *file_name)
|
||||
{
|
||||
GimpBrushGenerated *brush;
|
||||
FILE *fp;
|
||||
char string[256];
|
||||
float fl;
|
||||
float version;
|
||||
if ((fp = fopen(file_name, "r")) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* make sure the file we are reading is the right type */
|
||||
fscanf(fp, "%8s", string);
|
||||
g_return_val_if_fail(strcmp(string, "GIMP-VBR") == 0, NULL);
|
||||
/* make sure we are reading a compatible version */
|
||||
fscanf(fp, "%f", &version);
|
||||
g_return_val_if_fail(version < 2.0, NULL);
|
||||
|
||||
/* create new brush */
|
||||
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type()));
|
||||
GIMP_BRUSH(brush)->filename = g_strdup (file_name);
|
||||
gimp_brush_generated_freeze(brush);
|
||||
|
||||
/* read name */
|
||||
fscanf(fp, "%255s", string);
|
||||
GIMP_BRUSH(brush)->name = g_strdup (string);
|
||||
/* read brush spacing */
|
||||
fscanf(fp, "%f", &fl);
|
||||
GIMP_BRUSH(brush)->spacing = fl;
|
||||
/* read brush radius */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_radius(brush, fl);
|
||||
/* read brush hardness */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_hardness(brush, fl);
|
||||
/* read brush aspect_ratio */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_aspect_ratio(brush, fl);
|
||||
/* read brush angle */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_angle(brush, fl);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
gimp_brush_generated_thaw(brush);
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_save (GimpBrushGenerated *brush,
|
||||
char *file_name)
|
||||
{
|
||||
/* WARNING: untested function */
|
||||
FILE *fp;
|
||||
if ((fp = fopen(file_name, "w")) == NULL)
|
||||
{
|
||||
g_warning("Unable to save file %s", file_name);
|
||||
return;
|
||||
}
|
||||
/* write magic header */
|
||||
fprintf(fp, "GIMP-VBR\n");
|
||||
/* write version */
|
||||
fprintf(fp, "1.0\n");
|
||||
/* write name */
|
||||
fprintf(fp, "%s", GIMP_BRUSH(brush)->name);
|
||||
/* write brush spacing */
|
||||
fprintf(fp, "%f", (float)GIMP_BRUSH(brush)->spacing);
|
||||
/* write brush radius */
|
||||
fprintf(fp, "%f", brush->radius);
|
||||
/* write brush hardness */
|
||||
fprintf(fp, "%f", brush->hardness);
|
||||
/* write brush aspect_ratio */
|
||||
fprintf(fp, "%f", brush->aspect_ratio);
|
||||
/* write brush angle */
|
||||
fprintf(fp, "%f", brush->angle);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_freeze(GimpBrushGenerated *brush)
|
||||
{
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "appenv.h"
|
||||
#include "gimpbrushgenerated.h"
|
||||
#include "gimpbrushlist.h"
|
||||
#include "paint_core.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define OVERSAMPLING 5
|
||||
|
||||
|
@ -96,14 +96,89 @@ GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
|
|||
/* render brush mask */
|
||||
gimp_brush_generated_generate(brush);
|
||||
|
||||
/* add brush to brush list */
|
||||
/* FIXME: Get rid of this */
|
||||
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
|
||||
select_brush(GIMP_BRUSH(brush));
|
||||
return brush;
|
||||
}
|
||||
|
||||
GimpBrushGenerated *
|
||||
gimp_brush_generated_load (char *file_name)
|
||||
{
|
||||
GimpBrushGenerated *brush;
|
||||
FILE *fp;
|
||||
char string[256];
|
||||
float fl;
|
||||
float version;
|
||||
if ((fp = fopen(file_name, "r")) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* make sure the file we are reading is the right type */
|
||||
fscanf(fp, "%8s", string);
|
||||
g_return_val_if_fail(strcmp(string, "GIMP-VBR") == 0, NULL);
|
||||
/* make sure we are reading a compatible version */
|
||||
fscanf(fp, "%f", &version);
|
||||
g_return_val_if_fail(version < 2.0, NULL);
|
||||
|
||||
/* create new brush */
|
||||
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type()));
|
||||
GIMP_BRUSH(brush)->filename = g_strdup (file_name);
|
||||
gimp_brush_generated_freeze(brush);
|
||||
|
||||
/* read name */
|
||||
fscanf(fp, "%255s", string);
|
||||
GIMP_BRUSH(brush)->name = g_strdup (string);
|
||||
/* read brush spacing */
|
||||
fscanf(fp, "%f", &fl);
|
||||
GIMP_BRUSH(brush)->spacing = fl;
|
||||
/* read brush radius */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_radius(brush, fl);
|
||||
/* read brush hardness */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_hardness(brush, fl);
|
||||
/* read brush aspect_ratio */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_aspect_ratio(brush, fl);
|
||||
/* read brush angle */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_angle(brush, fl);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
gimp_brush_generated_thaw(brush);
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_save (GimpBrushGenerated *brush,
|
||||
char *file_name)
|
||||
{
|
||||
/* WARNING: untested function */
|
||||
FILE *fp;
|
||||
if ((fp = fopen(file_name, "w")) == NULL)
|
||||
{
|
||||
g_warning("Unable to save file %s", file_name);
|
||||
return;
|
||||
}
|
||||
/* write magic header */
|
||||
fprintf(fp, "GIMP-VBR\n");
|
||||
/* write version */
|
||||
fprintf(fp, "1.0\n");
|
||||
/* write name */
|
||||
fprintf(fp, "%s", GIMP_BRUSH(brush)->name);
|
||||
/* write brush spacing */
|
||||
fprintf(fp, "%f", (float)GIMP_BRUSH(brush)->spacing);
|
||||
/* write brush radius */
|
||||
fprintf(fp, "%f", brush->radius);
|
||||
/* write brush hardness */
|
||||
fprintf(fp, "%f", brush->hardness);
|
||||
/* write brush aspect_ratio */
|
||||
fprintf(fp, "%f", brush->aspect_ratio);
|
||||
/* write brush angle */
|
||||
fprintf(fp, "%f", brush->angle);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_freeze(GimpBrushGenerated *brush)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,10 @@ guint gimp_brush_generated_get_type (void);
|
|||
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
|
||||
float angle, float aspect_ratio);
|
||||
|
||||
GimpBrushGenerated *gimp_brush_generated_load (char *file_name);
|
||||
|
||||
void gimp_brush_generated_save (GimpBrushGenerated *brush,
|
||||
char *file_name);
|
||||
void gimp_brush_generated_freeze (GimpBrushGenerated *brush);
|
||||
void gimp_brush_generated_thaw (GimpBrushGenerated *brush);
|
||||
|
||||
|
|
|
@ -196,11 +196,6 @@ gimp_brush_load(GimpBrush *brush, char *filename)
|
|||
fp)) < header.width * header.height)
|
||||
g_message ("GIMP brush file appears to be truncated.");
|
||||
break;
|
||||
case 3:
|
||||
fprintf(stderr, "loading generated brush\n");
|
||||
fprintf(stderr, "currently unimplemeted expect a crash to occur any second\n");
|
||||
fprintf(stderr, "finished loading generated brush\n");
|
||||
break;
|
||||
default:
|
||||
g_message ("Unknown brush format version #%d in \"%s\"\n",
|
||||
header.version, filename);
|
||||
|
@ -216,9 +211,6 @@ gimp_brush_load(GimpBrush *brush, char *filename)
|
|||
if (stingy_memory_use)
|
||||
temp_buf_swap (brush->mask);
|
||||
|
||||
/* TODO: get rid of this call */
|
||||
gimp_brush_list_add(brush_list, brush);
|
||||
|
||||
/* Check if the current brush is the default one */
|
||||
/* lets see if it works with out this for now */
|
||||
/* if (strcmp(default_brush, prune_filename(filename)) == 0) {
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "appenv.h"
|
||||
#include "gimpbrushgenerated.h"
|
||||
#include "gimpbrushlist.h"
|
||||
#include "paint_core.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define OVERSAMPLING 5
|
||||
|
||||
|
@ -96,14 +96,89 @@ GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
|
|||
/* render brush mask */
|
||||
gimp_brush_generated_generate(brush);
|
||||
|
||||
/* add brush to brush list */
|
||||
/* FIXME: Get rid of this */
|
||||
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
|
||||
select_brush(GIMP_BRUSH(brush));
|
||||
return brush;
|
||||
}
|
||||
|
||||
GimpBrushGenerated *
|
||||
gimp_brush_generated_load (char *file_name)
|
||||
{
|
||||
GimpBrushGenerated *brush;
|
||||
FILE *fp;
|
||||
char string[256];
|
||||
float fl;
|
||||
float version;
|
||||
if ((fp = fopen(file_name, "r")) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* make sure the file we are reading is the right type */
|
||||
fscanf(fp, "%8s", string);
|
||||
g_return_val_if_fail(strcmp(string, "GIMP-VBR") == 0, NULL);
|
||||
/* make sure we are reading a compatible version */
|
||||
fscanf(fp, "%f", &version);
|
||||
g_return_val_if_fail(version < 2.0, NULL);
|
||||
|
||||
/* create new brush */
|
||||
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type()));
|
||||
GIMP_BRUSH(brush)->filename = g_strdup (file_name);
|
||||
gimp_brush_generated_freeze(brush);
|
||||
|
||||
/* read name */
|
||||
fscanf(fp, "%255s", string);
|
||||
GIMP_BRUSH(brush)->name = g_strdup (string);
|
||||
/* read brush spacing */
|
||||
fscanf(fp, "%f", &fl);
|
||||
GIMP_BRUSH(brush)->spacing = fl;
|
||||
/* read brush radius */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_radius(brush, fl);
|
||||
/* read brush hardness */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_hardness(brush, fl);
|
||||
/* read brush aspect_ratio */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_aspect_ratio(brush, fl);
|
||||
/* read brush angle */
|
||||
fscanf(fp, "%f", &fl);
|
||||
gimp_brush_generated_set_angle(brush, fl);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
gimp_brush_generated_thaw(brush);
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_save (GimpBrushGenerated *brush,
|
||||
char *file_name)
|
||||
{
|
||||
/* WARNING: untested function */
|
||||
FILE *fp;
|
||||
if ((fp = fopen(file_name, "w")) == NULL)
|
||||
{
|
||||
g_warning("Unable to save file %s", file_name);
|
||||
return;
|
||||
}
|
||||
/* write magic header */
|
||||
fprintf(fp, "GIMP-VBR\n");
|
||||
/* write version */
|
||||
fprintf(fp, "1.0\n");
|
||||
/* write name */
|
||||
fprintf(fp, "%s", GIMP_BRUSH(brush)->name);
|
||||
/* write brush spacing */
|
||||
fprintf(fp, "%f", (float)GIMP_BRUSH(brush)->spacing);
|
||||
/* write brush radius */
|
||||
fprintf(fp, "%f", brush->radius);
|
||||
/* write brush hardness */
|
||||
fprintf(fp, "%f", brush->hardness);
|
||||
/* write brush aspect_ratio */
|
||||
fprintf(fp, "%f", brush->aspect_ratio);
|
||||
/* write brush angle */
|
||||
fprintf(fp, "%f", brush->angle);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_generated_freeze(GimpBrushGenerated *brush)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,10 @@ guint gimp_brush_generated_get_type (void);
|
|||
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
|
||||
float angle, float aspect_ratio);
|
||||
|
||||
GimpBrushGenerated *gimp_brush_generated_load (char *file_name);
|
||||
|
||||
void gimp_brush_generated_save (GimpBrushGenerated *brush,
|
||||
char *file_name);
|
||||
void gimp_brush_generated_freeze (GimpBrushGenerated *brush);
|
||||
void gimp_brush_generated_thaw (GimpBrushGenerated *brush);
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ static gint brush_compare_func (gconstpointer, gconstpointer);
|
|||
|
||||
static void gimp_brush_list_recalc_indexes(GimpBrushList *brush_list);
|
||||
static void gimp_brush_list_uniquefy_names(GimpBrushList *brush_list);
|
||||
static void brush_load (char *filename);
|
||||
|
||||
/* class functions */
|
||||
static GimpObjectClass* parent_class;
|
||||
|
@ -183,13 +184,26 @@ brushes_init (int no_data)
|
|||
if (brush_path == NULL || (no_data))
|
||||
create_default_brush ();
|
||||
else
|
||||
datafiles_read_directories (brush_path,
|
||||
(datafile_loader_t)gimp_brush_new, 0);
|
||||
datafiles_read_directories (brush_path,(datafile_loader_t)brush_load, 0);
|
||||
|
||||
gimp_brush_list_recalc_indexes(brush_list);
|
||||
gimp_brush_list_uniquefy_names(brush_list);
|
||||
}
|
||||
|
||||
static void
|
||||
brush_load(char *filename)
|
||||
{
|
||||
if (strcmp(&filename[strlen(filename) - 4], ".gbr") == 0)
|
||||
{
|
||||
gimp_brush_list_add(brush_list, gimp_brush_new(filename));
|
||||
}
|
||||
else if (strcmp(&filename[strlen(filename) - 4], ".vbr") == 0)
|
||||
{
|
||||
gimp_brush_list_add(brush_list,
|
||||
GIMP_BRUSH(gimp_brush_generated_load(filename)));
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
brush_compare_func (gconstpointer first, gconstpointer second)
|
||||
{
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
#include "math.h"
|
||||
|
||||
|
||||
static void
|
||||
brush_edit_close_callback (GtkWidget *w, void *data);
|
||||
static void brush_edit_close_callback (GtkWidget *w, void *data);
|
||||
static gint brush_edit_preview_resize (GtkWidget *widget, GdkEvent *event,
|
||||
BrushEditGeneratedWindow *begw);
|
||||
|
||||
/* the action area structure */
|
||||
static ActionAreaItem action_items[] =
|
||||
|
@ -98,7 +99,8 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
gchar *src, *buf;
|
||||
|
||||
brush_edit_clear_preview (begw);
|
||||
|
||||
if (brush == NULL)
|
||||
return TRUE;
|
||||
scale = MAX(ceil(brush->mask->width/(float)begw->preview->requisition.width),
|
||||
ceil(brush->mask->height/(float)begw->preview->requisition.height));
|
||||
|
||||
|
@ -113,11 +115,8 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
|
||||
for (y = ystart; y < yend; y++)
|
||||
{
|
||||
/* Invert the mask for display. We're doing this because
|
||||
* a value of 255 in the mask means it is full intensity.
|
||||
* However, it makes more sense for full intensity to show
|
||||
* up as black in this brush preview window...
|
||||
*/
|
||||
/* Invert the mask for display.
|
||||
*/
|
||||
for (x = 0; x < width; x++)
|
||||
buf[x] = 255 - src[x*scale];
|
||||
gtk_preview_draw_row (GTK_PREVIEW (begw->preview), (guchar *)buf, xo, y,
|
||||
|
@ -125,6 +124,14 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
src += brush->mask->width*scale;
|
||||
}
|
||||
g_free(buf);
|
||||
if (begw->scale != scale)
|
||||
{
|
||||
char str[255];
|
||||
begw->scale = scale;
|
||||
g_snprintf(str, 200, "%d:1", scale);
|
||||
gtk_label_set(GTK_LABEL(begw->scale_label), str);
|
||||
gtk_widget_draw(begw->scale_label, NULL);
|
||||
}
|
||||
gtk_widget_draw(begw->preview, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -142,7 +149,10 @@ brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
|||
}
|
||||
brush = GIMP_BRUSH_GENERATED(gbrush);
|
||||
if (begw->brush)
|
||||
{
|
||||
gtk_signal_disconnect_by_data(GTK_OBJECT(begw->brush), begw);
|
||||
gtk_object_unref(GTK_OBJECT(begw->brush));
|
||||
}
|
||||
if (begw)
|
||||
{
|
||||
gtk_signal_connect(GTK_OBJECT (brush), "dirty",
|
||||
|
@ -158,6 +168,7 @@ brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
|||
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->aspect_ratio_data),
|
||||
gimp_brush_generated_get_aspect_ratio(brush));
|
||||
begw->brush = brush;
|
||||
gtk_object_ref(GTK_OBJECT(begw->brush));
|
||||
brush_edit_brush_dirty_callback(GIMP_BRUSH(brush), begw);
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +186,6 @@ brush_edit_generated_new ()
|
|||
|
||||
begw = g_malloc (sizeof (BrushEditGeneratedWindow));
|
||||
begw->brush = NULL;
|
||||
begw->redraw = TRUE;
|
||||
|
||||
begw->shell = gtk_dialog_new ();
|
||||
gtk_window_set_wmclass (GTK_WINDOW (begw->shell), "generatedbrusheditor",
|
||||
|
@ -201,12 +211,20 @@ brush_edit_generated_new ()
|
|||
gtk_box_pack_start (GTK_BOX (vbox), begw->frame, TRUE, TRUE, 0);
|
||||
|
||||
begw->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview), 100, 100);
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview), 125, 100);
|
||||
gtk_signal_connect_after (GTK_OBJECT(begw->frame), "size_allocate",
|
||||
(GtkSignalFunc) brush_edit_preview_resize,
|
||||
begw);
|
||||
gtk_container_add (GTK_CONTAINER (begw->frame), begw->preview);
|
||||
|
||||
gtk_widget_show(begw->preview);
|
||||
gtk_widget_show(begw->frame);
|
||||
|
||||
/* table for sliders/labels */
|
||||
begw->scale_label = gtk_label_new ("-1:1");
|
||||
gtk_box_pack_start (GTK_BOX (vbox), begw->scale_label, FALSE, FALSE, 0);
|
||||
begw->scale = -1;
|
||||
gtk_widget_show(begw->scale_label);
|
||||
/* table for sliders/labels */
|
||||
table = gtk_table_new(2, 4, FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
||||
|
@ -290,6 +308,21 @@ brush_edit_generated_new ()
|
|||
return begw;
|
||||
}
|
||||
|
||||
static gint
|
||||
brush_edit_preview_resize (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
BrushEditGeneratedWindow *begw)
|
||||
{
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview),
|
||||
widget->allocation.width - 4,
|
||||
widget->allocation.height - 4);
|
||||
|
||||
/* update the display */
|
||||
if (begw->brush)
|
||||
brush_edit_brush_dirty_callback(GIMP_BRUSH(begw->brush), begw);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
brush_edit_close_callback (GtkWidget *w, void *data)
|
||||
{
|
||||
|
|
|
@ -28,17 +28,16 @@ typedef struct _BrushEditGeneratedWindow
|
|||
GtkWidget *shell;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *scale_label;
|
||||
GtkWidget *options_box;
|
||||
GtkAdjustment *radius_data;
|
||||
GtkAdjustment *hardness_data;
|
||||
GtkAdjustment *angle_data;
|
||||
GtkAdjustment *aspect_ratio_data;
|
||||
int width, height;
|
||||
int cell_width, cell_height;
|
||||
int redraw;
|
||||
/* Brush preview */
|
||||
GtkWidget *brush_preview;
|
||||
GimpBrushGenerated *brush;
|
||||
int scale;
|
||||
} BrushEditGeneratedWindow;
|
||||
|
||||
void brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
||||
|
|
|
@ -857,15 +857,18 @@ edit_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
|
|||
}
|
||||
}
|
||||
else
|
||||
g_message("We are all out of brush editors today, please try again tomorrow\n");
|
||||
g_message("We are all fresh out of brush editors today,\n"
|
||||
"please write your own or try back tomorrow\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
new_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
|
||||
{
|
||||
gimp_brush_list_add(brush_list,
|
||||
GIMP_BRUSH(gimp_brush_generated_new(10, .5, 0.0, 1.0)));
|
||||
GimpBrushGenerated *brush;
|
||||
brush = gimp_brush_generated_new(10, .5, 0.0, 1.0);
|
||||
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
|
||||
select_brush(GIMP_BRUSH(brush));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
#include "math.h"
|
||||
|
||||
|
||||
static void
|
||||
brush_edit_close_callback (GtkWidget *w, void *data);
|
||||
static void brush_edit_close_callback (GtkWidget *w, void *data);
|
||||
static gint brush_edit_preview_resize (GtkWidget *widget, GdkEvent *event,
|
||||
BrushEditGeneratedWindow *begw);
|
||||
|
||||
/* the action area structure */
|
||||
static ActionAreaItem action_items[] =
|
||||
|
@ -98,7 +99,8 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
gchar *src, *buf;
|
||||
|
||||
brush_edit_clear_preview (begw);
|
||||
|
||||
if (brush == NULL)
|
||||
return TRUE;
|
||||
scale = MAX(ceil(brush->mask->width/(float)begw->preview->requisition.width),
|
||||
ceil(brush->mask->height/(float)begw->preview->requisition.height));
|
||||
|
||||
|
@ -113,11 +115,8 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
|
||||
for (y = ystart; y < yend; y++)
|
||||
{
|
||||
/* Invert the mask for display. We're doing this because
|
||||
* a value of 255 in the mask means it is full intensity.
|
||||
* However, it makes more sense for full intensity to show
|
||||
* up as black in this brush preview window...
|
||||
*/
|
||||
/* Invert the mask for display.
|
||||
*/
|
||||
for (x = 0; x < width; x++)
|
||||
buf[x] = 255 - src[x*scale];
|
||||
gtk_preview_draw_row (GTK_PREVIEW (begw->preview), (guchar *)buf, xo, y,
|
||||
|
@ -125,6 +124,14 @@ brush_edit_brush_dirty_callback(GimpBrush *brush,
|
|||
src += brush->mask->width*scale;
|
||||
}
|
||||
g_free(buf);
|
||||
if (begw->scale != scale)
|
||||
{
|
||||
char str[255];
|
||||
begw->scale = scale;
|
||||
g_snprintf(str, 200, "%d:1", scale);
|
||||
gtk_label_set(GTK_LABEL(begw->scale_label), str);
|
||||
gtk_widget_draw(begw->scale_label, NULL);
|
||||
}
|
||||
gtk_widget_draw(begw->preview, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -142,7 +149,10 @@ brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
|||
}
|
||||
brush = GIMP_BRUSH_GENERATED(gbrush);
|
||||
if (begw->brush)
|
||||
{
|
||||
gtk_signal_disconnect_by_data(GTK_OBJECT(begw->brush), begw);
|
||||
gtk_object_unref(GTK_OBJECT(begw->brush));
|
||||
}
|
||||
if (begw)
|
||||
{
|
||||
gtk_signal_connect(GTK_OBJECT (brush), "dirty",
|
||||
|
@ -158,6 +168,7 @@ brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
|||
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->aspect_ratio_data),
|
||||
gimp_brush_generated_get_aspect_ratio(brush));
|
||||
begw->brush = brush;
|
||||
gtk_object_ref(GTK_OBJECT(begw->brush));
|
||||
brush_edit_brush_dirty_callback(GIMP_BRUSH(brush), begw);
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +186,6 @@ brush_edit_generated_new ()
|
|||
|
||||
begw = g_malloc (sizeof (BrushEditGeneratedWindow));
|
||||
begw->brush = NULL;
|
||||
begw->redraw = TRUE;
|
||||
|
||||
begw->shell = gtk_dialog_new ();
|
||||
gtk_window_set_wmclass (GTK_WINDOW (begw->shell), "generatedbrusheditor",
|
||||
|
@ -201,12 +211,20 @@ brush_edit_generated_new ()
|
|||
gtk_box_pack_start (GTK_BOX (vbox), begw->frame, TRUE, TRUE, 0);
|
||||
|
||||
begw->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview), 100, 100);
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview), 125, 100);
|
||||
gtk_signal_connect_after (GTK_OBJECT(begw->frame), "size_allocate",
|
||||
(GtkSignalFunc) brush_edit_preview_resize,
|
||||
begw);
|
||||
gtk_container_add (GTK_CONTAINER (begw->frame), begw->preview);
|
||||
|
||||
gtk_widget_show(begw->preview);
|
||||
gtk_widget_show(begw->frame);
|
||||
|
||||
/* table for sliders/labels */
|
||||
begw->scale_label = gtk_label_new ("-1:1");
|
||||
gtk_box_pack_start (GTK_BOX (vbox), begw->scale_label, FALSE, FALSE, 0);
|
||||
begw->scale = -1;
|
||||
gtk_widget_show(begw->scale_label);
|
||||
/* table for sliders/labels */
|
||||
table = gtk_table_new(2, 4, FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
||||
|
@ -290,6 +308,21 @@ brush_edit_generated_new ()
|
|||
return begw;
|
||||
}
|
||||
|
||||
static gint
|
||||
brush_edit_preview_resize (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
BrushEditGeneratedWindow *begw)
|
||||
{
|
||||
gtk_preview_size (GTK_PREVIEW (begw->preview),
|
||||
widget->allocation.width - 4,
|
||||
widget->allocation.height - 4);
|
||||
|
||||
/* update the display */
|
||||
if (begw->brush)
|
||||
brush_edit_brush_dirty_callback(GIMP_BRUSH(begw->brush), begw);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
brush_edit_close_callback (GtkWidget *w, void *data)
|
||||
{
|
||||
|
|
|
@ -28,17 +28,16 @@ typedef struct _BrushEditGeneratedWindow
|
|||
GtkWidget *shell;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *scale_label;
|
||||
GtkWidget *options_box;
|
||||
GtkAdjustment *radius_data;
|
||||
GtkAdjustment *hardness_data;
|
||||
GtkAdjustment *angle_data;
|
||||
GtkAdjustment *aspect_ratio_data;
|
||||
int width, height;
|
||||
int cell_width, cell_height;
|
||||
int redraw;
|
||||
/* Brush preview */
|
||||
GtkWidget *brush_preview;
|
||||
GimpBrushGenerated *brush;
|
||||
int scale;
|
||||
} BrushEditGeneratedWindow;
|
||||
|
||||
void brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
GIMP-VBR
|
||||
1.0
|
||||
round01
|
||||
15.0
|
||||
10.0
|
||||
0.75
|
||||
1.0
|
||||
0.0
|
Loading…
Reference in New Issue