plug-ins: port ifs-compose to GeglColor.

This commit is contained in:
Jehan 2024-04-20 19:02:31 +02:00
parent 6428e51f2a
commit b31a465a9e
4 changed files with 207 additions and 150 deletions

View file

@ -89,10 +89,11 @@ static struct
}; };
static GTokenType static GTokenType
ifsvals_parse_color (GScanner *scanner, ifsvals_parse_color (GScanner *scanner,
GimpRGB *result) GeglColor *result)
{ {
GTokenType token; GTokenType token;
gdouble rgb[3];
token = g_scanner_get_next_token (scanner); token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_LEFT_CURLY) if (token != G_TOKEN_LEFT_CURLY)
@ -100,9 +101,9 @@ ifsvals_parse_color (GScanner *scanner,
token = g_scanner_get_next_token (scanner); token = g_scanner_get_next_token (scanner);
if (token == G_TOKEN_FLOAT) if (token == G_TOKEN_FLOAT)
result->r = scanner->value.v_float; rgb[0] = scanner->value.v_float;
else if (token == G_TOKEN_INT) else if (token == G_TOKEN_INT)
result->r = scanner->value.v_int; rgb[0] = (gdouble) scanner->value.v_int;
else else
return G_TOKEN_FLOAT; return G_TOKEN_FLOAT;
@ -112,9 +113,9 @@ ifsvals_parse_color (GScanner *scanner,
token = g_scanner_get_next_token (scanner); token = g_scanner_get_next_token (scanner);
if (token == G_TOKEN_FLOAT) if (token == G_TOKEN_FLOAT)
result->g = scanner->value.v_float; rgb[1] = scanner->value.v_float;
else if (token == G_TOKEN_INT) else if (token == G_TOKEN_INT)
result->g = scanner->value.v_int; rgb[1] = (gdouble) scanner->value.v_int;
else else
return G_TOKEN_FLOAT; return G_TOKEN_FLOAT;
@ -124,9 +125,9 @@ ifsvals_parse_color (GScanner *scanner,
token = g_scanner_get_next_token (scanner); token = g_scanner_get_next_token (scanner);
if (token == G_TOKEN_FLOAT) if (token == G_TOKEN_FLOAT)
result->b = scanner->value.v_float; rgb[2] = scanner->value.v_float;
else if (token == G_TOKEN_INT) else if (token == G_TOKEN_INT)
result->b = scanner->value.v_int; rgb[2] = (gdouble) scanner->value.v_int;
else else
return G_TOKEN_FLOAT; return G_TOKEN_FLOAT;
@ -134,6 +135,8 @@ ifsvals_parse_color (GScanner *scanner,
if (token != G_TOKEN_RIGHT_CURLY) if (token != G_TOKEN_RIGHT_CURLY)
return G_TOKEN_RIGHT_CURLY; return G_TOKEN_RIGHT_CURLY;
gegl_color_set_pixel (result, babl_format ("R'G'B' double"), rgb);
return G_TOKEN_NONE; return G_TOKEN_NONE;
} }
@ -229,31 +232,31 @@ ifsvals_parse_element (GScanner *scanner,
break; break;
case TOKEN_RED_COLOR: case TOKEN_RED_COLOR:
token = ifsvals_parse_color (scanner, &result->red_color); token = ifsvals_parse_color (scanner, result->red_color);
if (token != G_TOKEN_NONE) if (token != G_TOKEN_NONE)
return token; return token;
break; break;
case TOKEN_GREEN_COLOR: case TOKEN_GREEN_COLOR:
token = ifsvals_parse_color (scanner, &result->green_color); token = ifsvals_parse_color (scanner, result->green_color);
if (token != G_TOKEN_NONE) if (token != G_TOKEN_NONE)
return token; return token;
break; break;
case TOKEN_BLUE_COLOR: case TOKEN_BLUE_COLOR:
token = ifsvals_parse_color (scanner, &result->blue_color); token = ifsvals_parse_color (scanner, result->blue_color);
if (token != G_TOKEN_NONE) if (token != G_TOKEN_NONE)
return token; return token;
break; break;
case TOKEN_BLACK_COLOR: case TOKEN_BLACK_COLOR:
token = ifsvals_parse_color (scanner, &result->black_color); token = ifsvals_parse_color (scanner, result->black_color);
if (token != G_TOKEN_NONE) if (token != G_TOKEN_NONE)
return token; return token;
break; break;
case TOKEN_TARGET_COLOR: case TOKEN_TARGET_COLOR:
token = ifsvals_parse_color (scanner, &result->target_color); token = ifsvals_parse_color (scanner, result->target_color);
if (token != G_TOKEN_NONE) if (token != G_TOKEN_NONE)
return token; return token;
break; break;
@ -320,15 +323,16 @@ ifsvals_parse (GScanner *scanner,
GTokenType token, expected_token; GTokenType token, expected_token;
AffElement *el; AffElement *el;
IfsComposeVals new_vals; IfsComposeVals new_vals;
GimpRGB color; GeglColor *color;
GList *el_list = NULL; GList *el_list = NULL;
GList *tmp_list; GList *tmp_list;
gint i; gint i;
new_vals = *vals; new_vals = *vals;
new_vals.num_elements = 0; new_vals.num_elements = 0;
i = 0; color = gegl_color_new ("black");
i = 0;
expected_token = G_TOKEN_NONE; expected_token = G_TOKEN_NONE;
while (expected_token == G_TOKEN_NONE) while (expected_token == G_TOKEN_NONE)
@ -381,7 +385,7 @@ ifsvals_parse (GScanner *scanner,
break; break;
case TOKEN_ELEMENT: case TOKEN_ELEMENT:
el = aff_element_new (0.0,0.0, &color, ++i); el = aff_element_new (0.0,0.0, color, ++i);
expected_token = ifsvals_parse_element (scanner, &el->v); expected_token = ifsvals_parse_element (scanner, &el->v);
if (expected_token == G_TOKEN_NONE) if (expected_token == G_TOKEN_NONE)
@ -399,6 +403,8 @@ ifsvals_parse (GScanner *scanner,
} }
} }
g_object_unref (color);
if (expected_token != G_TOKEN_NONE) if (expected_token != G_TOKEN_NONE)
{ {
g_scanner_unexp_token (scanner, g_scanner_unexp_token (scanner,
@ -491,6 +497,8 @@ ifsvals_stringify (IfsComposeVals *vals,
for (i=0; i<vals->num_elements; i++) for (i=0; i<vals->num_elements; i++)
{ {
gdouble rgb[3];
g_string_append (result, "element {\n"); g_string_append (result, "element {\n");
g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.x); g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.x);
g_string_append_printf (result, " x %s\n", buf); g_string_append_printf (result, " x %s\n", buf);
@ -506,33 +514,38 @@ ifsvals_stringify (IfsComposeVals *vals,
g_string_append_printf (result, " shear %s\n", buf); g_string_append_printf (result, " shear %s\n", buf);
g_string_append_printf (result, " flip %d\n", elements[i]->v.flip); g_string_append_printf (result, " flip %d\n", elements[i]->v.flip);
g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.red_color.r); gegl_color_get_pixel (elements[i]->v.red_color, babl_format ("R'G'B' double"), rgb);
g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.red_color.g); g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, rgb[0]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.red_color.b); g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, rgb[1]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, rgb[2]);
g_string_append_printf (result, " red_color { %s,%s,%s }\n", g_string_append_printf (result, " red_color { %s,%s,%s }\n",
cbuf[0], cbuf[1], cbuf[2]); cbuf[0], cbuf[1], cbuf[2]);
g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.green_color.r); gegl_color_get_pixel (elements[i]->v.green_color, babl_format ("R'G'B' double"), rgb);
g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.green_color.g); g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, rgb[0]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.green_color.b); g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, rgb[1]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, rgb[2]);
g_string_append_printf (result, " green_color { %s,%s,%s }\n", g_string_append_printf (result, " green_color { %s,%s,%s }\n",
cbuf[0], cbuf[1], cbuf[2]); cbuf[0], cbuf[1], cbuf[2]);
g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.blue_color.r); gegl_color_get_pixel (elements[i]->v.blue_color, babl_format ("R'G'B' double"), rgb);
g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.blue_color.g); g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, rgb[0]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.blue_color.b); g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, rgb[1]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, rgb[2]);
g_string_append_printf (result, " blue_color { %s,%s,%s }\n", g_string_append_printf (result, " blue_color { %s,%s,%s }\n",
cbuf[0], cbuf[1], cbuf[2]); cbuf[0], cbuf[1], cbuf[2]);
g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.black_color.r); gegl_color_get_pixel (elements[i]->v.black_color, babl_format ("R'G'B' double"), rgb);
g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.black_color.g); g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, rgb[0]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.black_color.b); g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, rgb[1]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, rgb[2]);
g_string_append_printf (result, " black_color { %s,%s,%s }\n", g_string_append_printf (result, " black_color { %s,%s,%s }\n",
cbuf[0], cbuf[1], cbuf[2]); cbuf[0], cbuf[1], cbuf[2]);
g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.target_color.r); gegl_color_get_pixel (elements[i]->v.target_color, babl_format ("R'G'B' double"), rgb);
g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.target_color.g); g_ascii_dtostr (cbuf[0], G_ASCII_DTOSTR_BUF_SIZE, rgb[0]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, elements[i]->v.target_color.b); g_ascii_dtostr (cbuf[1], G_ASCII_DTOSTR_BUF_SIZE, rgb[1]);
g_ascii_dtostr (cbuf[2], G_ASCII_DTOSTR_BUF_SIZE, rgb[2]);
g_string_append_printf (result, " target_color { %s,%s,%s }\n", g_string_append_printf (result, " target_color { %s,%s,%s }\n",
cbuf[0], cbuf[1], cbuf[2]); cbuf[0], cbuf[1], cbuf[2]);

View file

@ -400,15 +400,26 @@ ipolygon_contains (IPolygon *poly,
void void
aff_element_compute_color_trans (AffElement *elem) aff_element_compute_color_trans (AffElement *elem)
{ {
int i, j; gdouble red_rgb[3];
gdouble green_rgb[3];
gdouble blue_rgb[3];
gdouble black_rgb[3];
gdouble target_rgb[3];
int i, j;
gegl_color_get_pixel (elem->v.red_color, babl_format ("R'G'B' double"), red_rgb);
gegl_color_get_pixel (elem->v.green_color, babl_format ("R'G'B' double"), green_rgb);
gegl_color_get_pixel (elem->v.blue_color, babl_format ("R'G'B' double"), blue_rgb);
gegl_color_get_pixel (elem->v.black_color, babl_format ("R'G'B' double"), black_rgb);
gegl_color_get_pixel (elem->v.target_color, babl_format ("R'G'B' double"), target_rgb);
if (elem->v.simple_color) if (elem->v.simple_color)
{ {
gdouble mag2; gdouble mag2;
mag2 = SQR (elem->v.target_color.r); mag2 = SQR (target_rgb[0]);
mag2 += SQR (elem->v.target_color.g); mag2 += SQR (target_rgb[1]);
mag2 += SQR (elem->v.target_color.b); mag2 += SQR (target_rgb[2]);
/* For mag2 == 0, the transformation blows up in general /* For mag2 == 0, the transformation blows up in general
but is well defined for hue_scale == value_scale, so but is well defined for hue_scale == value_scale, so
@ -426,21 +437,21 @@ aff_element_compute_color_trans (AffElement *elem)
/* red */ /* red */
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
{ {
elem->color_trans.vals[0][j] = elem->v.target_color.r elem->color_trans.vals[0][j] = target_rgb[0]
/ mag2 * (elem->v.value_scale - elem->v.hue_scale); / mag2 * (elem->v.value_scale - elem->v.hue_scale);
} }
/* green */ /* green */
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
{ {
elem->color_trans.vals[1][j] = elem->v.target_color.g elem->color_trans.vals[1][j] = target_rgb[1]
/ mag2 * (elem->v.value_scale - elem->v.hue_scale); / mag2 * (elem->v.value_scale - elem->v.hue_scale);
} }
/* blue */ /* blue */
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
{ {
elem->color_trans.vals[2][j] = elem->v.target_color.g elem->color_trans.vals[2][j] = target_rgb[2]
/ mag2 * (elem->v.value_scale - elem->v.hue_scale); / mag2 * (elem->v.value_scale - elem->v.hue_scale);
} }
@ -449,58 +460,46 @@ aff_element_compute_color_trans (AffElement *elem)
elem->color_trans.vals[2][2] += elem->v.hue_scale; elem->color_trans.vals[2][2] += elem->v.hue_scale;
elem->color_trans.vals[0][3] = elem->color_trans.vals[0][3] =
(1 - elem->v.value_scale) * elem->v.target_color.r; (1 - elem->v.value_scale) * target_rgb[0];
elem->color_trans.vals[1][3] = elem->color_trans.vals[1][3] =
(1 - elem->v.value_scale) * elem->v.target_color.g; (1 - elem->v.value_scale) * target_rgb[1];
elem->color_trans.vals[2][3] = elem->color_trans.vals[2][3] =
(1 - elem->v.value_scale) * elem->v.target_color.b; (1 - elem->v.value_scale) * target_rgb[2];
} }
aff3_apply (&elem->color_trans, 1.0, 0.0, 0.0, aff3_apply (&elem->color_trans, 1.0, 0.0, 0.0,
&elem->v.red_color.r, &red_rgb[0], &red_rgb[1], &red_rgb[2]);
&elem->v.red_color.g,
&elem->v.red_color.b);
aff3_apply (&elem->color_trans, 0.0, 1.0, 0.0, aff3_apply (&elem->color_trans, 0.0, 1.0, 0.0,
&elem->v.green_color.r, &green_rgb[0], &green_rgb[1], &green_rgb[2]);
&elem->v.green_color.g,
&elem->v.green_color.b);
aff3_apply (&elem->color_trans, 0.0, 0.0, 1.0, aff3_apply (&elem->color_trans, 0.0, 0.0, 1.0,
&elem->v.blue_color.r, &blue_rgb[0], &blue_rgb[1], &blue_rgb[2]);
&elem->v.blue_color.g,
&elem->v.blue_color.b);
aff3_apply (&elem->color_trans, 0.0, 0.0, 0.0, aff3_apply (&elem->color_trans, 0.0, 0.0, 0.0,
&elem->v.black_color.r, &black_rgb[0], &black_rgb[1], &black_rgb[2]);
&elem->v.black_color.g,
&elem->v.black_color.b); gegl_color_set_pixel (elem->v.red_color, babl_format ("R'G'B' double"), red_rgb);
gegl_color_set_pixel (elem->v.green_color, babl_format ("R'G'B' double"), green_rgb);
gegl_color_set_pixel (elem->v.blue_color, babl_format ("R'G'B' double"), blue_rgb);
gegl_color_set_pixel (elem->v.black_color, babl_format ("R'G'B' double"), black_rgb);
} }
else else
{ {
elem->color_trans.vals[0][0] = elem->color_trans.vals[0][0] = red_rgb[0] - black_rgb[0];
elem->v.red_color.r - elem->v.black_color.r; elem->color_trans.vals[1][0] = red_rgb[1] - black_rgb[1];
elem->color_trans.vals[1][0] = elem->color_trans.vals[2][0] = red_rgb[2] - black_rgb [2];
elem->v.red_color.g - elem->v.black_color.g;
elem->color_trans.vals[2][0] =
elem->v.red_color.b - elem->v.black_color.b;
elem->color_trans.vals[0][1] = elem->color_trans.vals[0][1] = green_rgb[0] - black_rgb[0];
elem->v.green_color.r - elem->v.black_color.r; elem->color_trans.vals[1][1] = green_rgb[1] - black_rgb[1];
elem->color_trans.vals[1][1] = elem->color_trans.vals[2][1] = green_rgb[2] - black_rgb[2];
elem->v.green_color.g - elem->v.black_color.g;
elem->color_trans.vals[2][1] =
elem->v.green_color.b - elem->v.black_color.b;
elem->color_trans.vals[0][2] = elem->color_trans.vals[0][2] = blue_rgb[0] - black_rgb[0];
elem->v.blue_color.r - elem->v.black_color.r; elem->color_trans.vals[1][2] = blue_rgb[1] - black_rgb[1];
elem->color_trans.vals[1][2] = elem->color_trans.vals[2][2] = blue_rgb[2] - black_rgb[2];
elem->v.blue_color.g - elem->v.black_color.g;
elem->color_trans.vals[2][2] =
elem->v.blue_color.b - elem->v.black_color.b;
elem->color_trans.vals[0][3] = elem->v.black_color.r; elem->color_trans.vals[0][3] = black_rgb[0];
elem->color_trans.vals[1][3] = elem->v.black_color.g; elem->color_trans.vals[1][3] = black_rgb[1];
elem->color_trans.vals[2][3] = elem->v.black_color.b; elem->color_trans.vals[2][3] = black_rgb[2];
} }
} }
@ -771,10 +770,10 @@ aff_element_draw (AffElement *elem,
} }
AffElement * AffElement *
aff_element_new (gdouble x, aff_element_new (gdouble x,
gdouble y, gdouble y,
GimpRGB *color, GeglColor *color,
gint count) gint count)
{ {
AffElement *elem = g_new (AffElement, 1); AffElement *elem = g_new (AffElement, 1);
gchar buffer[16]; gchar buffer[16];
@ -787,12 +786,12 @@ aff_element_new (gdouble x,
elem->v.shear = 0.0; elem->v.shear = 0.0;
elem->v.flip = 0; elem->v.flip = 0;
elem->v.red_color = *color; elem->v.red_color = gegl_color_duplicate (color);
elem->v.blue_color = *color; elem->v.blue_color = gegl_color_duplicate (color);
elem->v.green_color = *color; elem->v.green_color = gegl_color_duplicate (color);
elem->v.black_color = *color; elem->v.black_color = gegl_color_duplicate (color);
elem->v.target_color = *color; elem->v.target_color = gegl_color_duplicate (color);
elem->v.hue_scale = 0.5; elem->v.hue_scale = 0.5;
elem->v.value_scale = 0.5; elem->v.value_scale = 0.5;
@ -817,6 +816,12 @@ aff_element_free (AffElement *elem)
if (elem->click_boundary != elem->draw_boundary) if (elem->click_boundary != elem->draw_boundary)
g_free (elem->click_boundary); g_free (elem->click_boundary);
g_clear_object (&elem->v.red_color);
g_clear_object (&elem->v.blue_color);
g_clear_object (&elem->v.green_color);
g_clear_object (&elem->v.black_color);
g_clear_object (&elem->v.target_color);
g_free (elem->draw_boundary); g_free (elem->draw_boundary);
g_free (elem); g_free (elem);
} }

View file

@ -264,9 +264,10 @@ static void recompute_center_action (GSimpleAction *action,
static void ifs_compose (GimpDrawable *drawable); static void ifs_compose (GimpDrawable *drawable);
static ColorMap *color_map_create (const gchar *name, static ColorMap *color_map_create (const gchar *name,
GimpRGB *orig_color, GeglColor *orig_color,
GimpRGB *data, GeglColor *data,
gboolean fixed_point); gboolean fixed_point);
static void color_map_free (ColorMap *cmap);
static void color_map_color_changed_cb (GtkWidget *widget, static void color_map_color_changed_cb (GtkWidget *widget,
ColorMap *color_map); ColorMap *color_map);
static void color_map_update (ColorMap *color_map); static void color_map_update (ColorMap *color_map);
@ -740,7 +741,7 @@ ifs_compose_color_page (void)
GtkWidget *grid; GtkWidget *grid;
GtkWidget *label; GtkWidget *label;
GSList *group = NULL; GSList *group = NULL;
GimpRGB color; GeglColor *color;
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
@ -763,7 +764,7 @@ ifs_compose_color_page (void)
gtk_widget_show (ifsD->simple_button); gtk_widget_show (ifsD->simple_button);
ifsD->target_cmap = color_map_create (_("IFS Fractal: Target"), NULL, ifsD->target_cmap = color_map_create (_("IFS Fractal: Target"), NULL,
&ifsD->current_vals.target_color, TRUE); ifsD->current_vals.target_color, TRUE);
gtk_grid_attach (GTK_GRID (grid), ifsD->target_cmap->hbox, 1, 0, 1, 2); gtk_grid_attach (GTK_GRID (grid), ifsD->target_cmap->hbox, 1, 0, 1, 2);
// GTK_FILL, 0, 0, 0); // GTK_FILL, 0, 0, 0);
gtk_widget_show (ifsD->target_cmap->hbox); gtk_widget_show (ifsD->target_cmap->hbox);
@ -806,37 +807,37 @@ ifs_compose_color_page (void)
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (ifsD->full_button)); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (ifsD->full_button));
gtk_widget_show (ifsD->full_button); gtk_widget_show (ifsD->full_button);
gimp_rgb_parse_name (&color, "red", -1); color = gegl_color_new ("red");
gimp_rgb_set_alpha (&color, 1.0); ifsD->red_cmap = color_map_create (_("IFS Fractal: Red"), color,
ifsD->red_cmap = color_map_create (_("IFS Fractal: Red"), &color, ifsD->current_vals.red_color, FALSE);
&ifsD->current_vals.red_color, FALSE);
gtk_grid_attach (GTK_GRID (grid), ifsD->red_cmap->hbox, 1, 2, 1, 1); gtk_grid_attach (GTK_GRID (grid), ifsD->red_cmap->hbox, 1, 2, 1, 1);
// GTK_FILL, GTK_FILL, 0, 0); // GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (ifsD->red_cmap->hbox); gtk_widget_show (ifsD->red_cmap->hbox);
g_object_unref (color);
gimp_rgb_parse_name (&color, "green", -1); color = gegl_color_new ("green");
gimp_rgb_set_alpha (&color, 1.0); ifsD->green_cmap = color_map_create (_("IFS Fractal: Green"), color,
ifsD->green_cmap = color_map_create (_("IFS Fractal: Green"), &color, ifsD->current_vals.green_color, FALSE);
&ifsD->current_vals.green_color, FALSE);
gtk_grid_attach (GTK_GRID (grid), ifsD->green_cmap->hbox, 2, 2, 1, 1); gtk_grid_attach (GTK_GRID (grid), ifsD->green_cmap->hbox, 2, 2, 1, 1);
// GTK_FILL, GTK_FILL, 0, 0); // GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (ifsD->green_cmap->hbox); gtk_widget_show (ifsD->green_cmap->hbox);
g_object_unref (color);
gimp_rgb_parse_name (&color, "blue", -1); color = gegl_color_new ("blue");
gimp_rgb_set_alpha (&color, 1.0); ifsD->blue_cmap = color_map_create (_("IFS Fractal: Blue"), color,
ifsD->blue_cmap = color_map_create (_("IFS Fractal: Blue"), &color, ifsD->current_vals.blue_color, FALSE);
&ifsD->current_vals.blue_color, FALSE);
gtk_grid_attach (GTK_GRID (grid), ifsD->blue_cmap->hbox, 3, 2, 1, 1); gtk_grid_attach (GTK_GRID (grid), ifsD->blue_cmap->hbox, 3, 2, 1, 1);
// GTK_FILL, GTK_FILL, 0, 0); // GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (ifsD->blue_cmap->hbox); gtk_widget_show (ifsD->blue_cmap->hbox);
g_object_unref (color);
gimp_rgb_parse_name (&color, "black", -1); color = gegl_color_new ("black");
gimp_rgb_set_alpha (&color, 1.0); ifsD->black_cmap = color_map_create (_("IFS Fractal: Black"), color,
ifsD->black_cmap = color_map_create (_("IFS Fractal: Black"), &color, ifsD->current_vals.black_color, FALSE);
&ifsD->current_vals.black_color, FALSE);
gtk_grid_attach (GTK_GRID (grid), ifsD->black_cmap->hbox, 4, 2, 1, 1); gtk_grid_attach (GTK_GRID (grid), ifsD->black_cmap->hbox, 4, 2, 1, 1);
// GTK_FILL, GTK_FILL, 0, 0); // GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (ifsD->black_cmap->hbox); gtk_widget_show (ifsD->black_cmap->hbox);
g_object_unref (color);
return vbox; return vbox;
} }
@ -1461,8 +1462,19 @@ update_values (void)
{ {
ifsD->in_update = TRUE; ifsD->in_update = TRUE;
g_clear_object (&ifsD->current_vals.red_color);
g_clear_object (&ifsD->current_vals.green_color);
g_clear_object (&ifsD->current_vals.blue_color);
g_clear_object (&ifsD->current_vals.black_color);
g_clear_object (&ifsD->current_vals.target_color);
ifsD->current_vals = elements[ifsD->current_element]->v; ifsD->current_vals = elements[ifsD->current_element]->v;
ifsD->current_vals.theta *= 180/G_PI; ifsD->current_vals.theta *= 180/G_PI;
ifsD->current_vals.red_color = gegl_color_duplicate (ifsD->current_vals.red_color);
ifsD->current_vals.green_color = gegl_color_duplicate (ifsD->current_vals.green_color);
ifsD->current_vals.blue_color = gegl_color_duplicate (ifsD->current_vals.blue_color);
ifsD->current_vals.black_color = gegl_color_duplicate (ifsD->current_vals.black_color);
ifsD->current_vals.target_color = gegl_color_duplicate (ifsD->current_vals.target_color);
value_pair_update (ifsD->prob_pair); value_pair_update (ifsD->prob_pair);
value_pair_update (ifsD->x_pair); value_pair_update (ifsD->x_pair);
@ -1995,8 +2007,18 @@ val_changed_update (void)
undo_begin (); undo_begin ();
undo_update (ifsD->current_element); undo_update (ifsD->current_element);
g_clear_object (&cur->v.red_color);
g_clear_object (&cur->v.green_color);
g_clear_object (&cur->v.blue_color);
g_clear_object (&cur->v.black_color);
g_clear_object (&cur->v.target_color);
cur->v = ifsD->current_vals; cur->v = ifsD->current_vals;
cur->v.theta *= G_PI/180.0; cur->v.red_color = gegl_color_duplicate (cur->v.red_color);
cur->v.green_color = gegl_color_duplicate (cur->v.green_color);
cur->v.blue_color = gegl_color_duplicate (cur->v.blue_color);
cur->v.black_color = gegl_color_duplicate (cur->v.black_color);
cur->v.target_color = gegl_color_duplicate (cur->v.target_color);
cur->v.theta *= G_PI/180.0;
aff_element_compute_trans (cur, aff_element_compute_trans (cur,
allocation.width, allocation.height, allocation.width, allocation.height,
ifsvals.center_x, ifsvals.center_y); ifsvals.center_x, ifsvals.center_y);
@ -2013,18 +2035,19 @@ val_changed_update (void)
static ColorMap * static ColorMap *
color_map_create (const gchar *name, color_map_create (const gchar *name,
GimpRGB *orig_color, GeglColor *orig_color,
GimpRGB *data, GeglColor *data,
gboolean fixed_point) gboolean fixed_point)
{ {
GtkWidget *frame; GtkWidget *frame;
GtkWidget *arrow; GtkWidget *arrow;
ColorMap *color_map = g_new (ColorMap, 1); ColorMap *color_map = g_new (ColorMap, 1);
GeglColor *color;
gimp_rgb_set_alpha (data, 1.0); if (data || orig_color)
color_map->color = gegl_color_new (NULL); color_map->color = gegl_color_duplicate (data ? data : orig_color);
gegl_color_set_pixel (color_map->color, babl_format ("R'G'B'A double"), data); else
color_map->color = gegl_color_new ("black");
gimp_color_set_alpha (color_map->color, 1.0);
color_map->fixed_point = fixed_point; color_map->fixed_point = fixed_point;
color_map->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); color_map->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
@ -2033,10 +2056,8 @@ color_map_create (const gchar *name,
gtk_box_pack_start (GTK_BOX (color_map->hbox), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (color_map->hbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame); gtk_widget_show (frame);
color = gegl_color_new (NULL); color_map->orig_preview = gimp_color_area_new (fixed_point ? color_map->color : orig_color,
gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), fixed_point ? data : orig_color); GIMP_COLOR_AREA_FLAT, 0);
color_map->orig_preview = gimp_color_area_new (color, GIMP_COLOR_AREA_FLAT, 0);
g_object_unref (color);
gtk_drag_dest_unset (color_map->orig_preview); gtk_drag_dest_unset (color_map->orig_preview);
gtk_widget_set_size_request (color_map->orig_preview, gtk_widget_set_size_request (color_map->orig_preview,
COLOR_SAMPLE_SIZE, COLOR_SAMPLE_SIZE); COLOR_SAMPLE_SIZE, COLOR_SAMPLE_SIZE);
@ -2064,26 +2085,43 @@ color_map_create (const gchar *name,
return color_map; return color_map;
} }
static void
color_map_free (ColorMap *cmap)
{
g_object_unref (cmap->color);
g_free (cmap);
}
static void static void
color_map_color_changed_cb (GtkWidget *widget, color_map_color_changed_cb (GtkWidget *widget,
ColorMap *color_map) ColorMap *color_map)
{ {
g_clear_object (&color_map->color);
color_map->color = gimp_color_button_get_color (GIMP_COLOR_BUTTON (widget));
if (ifsD->in_update) if (ifsD->in_update)
return; return;
undo_begin (); undo_begin ();
undo_update (ifsD->current_element); undo_update (ifsD->current_element);
g_clear_object (&elements[ifsD->current_element]->v.red_color);
g_clear_object (&elements[ifsD->current_element]->v.green_color);
g_clear_object (&elements[ifsD->current_element]->v.blue_color);
g_clear_object (&elements[ifsD->current_element]->v.black_color);
g_clear_object (&elements[ifsD->current_element]->v.target_color);
elements[ifsD->current_element]->v = ifsD->current_vals; elements[ifsD->current_element]->v = ifsD->current_vals;
elements[ifsD->current_element]->v.theta *= G_PI/180.0; elements[ifsD->current_element]->v.theta *= G_PI/180.0;
elements[ifsD->current_element]->v.red_color = gegl_color_duplicate (elements[ifsD->current_element]->v.red_color);
elements[ifsD->current_element]->v.green_color = gegl_color_duplicate (elements[ifsD->current_element]->v.green_color);
elements[ifsD->current_element]->v.blue_color = gegl_color_duplicate (elements[ifsD->current_element]->v.blue_color);
elements[ifsD->current_element]->v.black_color = gegl_color_duplicate (elements[ifsD->current_element]->v.black_color);
elements[ifsD->current_element]->v.target_color = gegl_color_duplicate (elements[ifsD->current_element]->v.target_color);
aff_element_compute_color_trans (elements[ifsD->current_element]); aff_element_compute_color_trans (elements[ifsD->current_element]);
update_values (); update_values ();
ifs_compose_preview (); ifs_compose_preview ();
g_clear_object (&color_map->color);
color_map->color = gimp_color_button_get_color (GIMP_COLOR_BUTTON (widget));
} }
static void static void
@ -2327,12 +2365,9 @@ static void
ifs_compose_set_defaults (void) ifs_compose_set_defaults (void)
{ {
GeglColor *color; GeglColor *color;
GimpRGB rgb;
gint i; gint i;
color = gimp_context_get_foreground (); color = gimp_context_get_foreground ();
gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb);
g_object_unref (color);
ifsvals.aspect_ratio = ifsvals.aspect_ratio =
(gdouble)ifsD->drawable_height / ifsD->drawable_width; (gdouble)ifsD->drawable_height / ifsD->drawable_width;
@ -2346,13 +2381,13 @@ ifs_compose_set_defaults (void)
element_selected = g_realloc (element_selected, element_selected = g_realloc (element_selected,
ifsvals.num_elements * sizeof(gboolean)); ifsvals.num_elements * sizeof(gboolean));
elements[0] = aff_element_new (0.3, 0.37 * ifsvals.aspect_ratio, &rgb, elements[0] = aff_element_new (0.3, 0.37 * ifsvals.aspect_ratio, color,
++count_for_naming); ++count_for_naming);
element_selected[0] = FALSE; element_selected[0] = FALSE;
elements[1] = aff_element_new (0.7, 0.37 * ifsvals.aspect_ratio, &rgb, elements[1] = aff_element_new (0.7, 0.37 * ifsvals.aspect_ratio, color,
++count_for_naming); ++count_for_naming);
element_selected[1] = FALSE; element_selected[1] = FALSE;
elements[2] = aff_element_new (0.5, 0.7 * ifsvals.aspect_ratio, &rgb, elements[2] = aff_element_new (0.5, 0.7 * ifsvals.aspect_ratio, color,
++count_for_naming); ++count_for_naming);
element_selected[2] = FALSE; element_selected[2] = FALSE;
@ -2380,6 +2415,8 @@ ifs_compose_set_defaults (void)
g_free (ifsD->selected_orig); g_free (ifsD->selected_orig);
ifsD->selected_orig = g_new (AffElement, ifsvals.num_elements); ifsD->selected_orig = g_new (AffElement, ifsvals.num_elements);
g_object_unref (color);
} }
/* show a transient message dialog */ /* show a transient message dialog */
@ -2629,7 +2666,6 @@ ifs_compose_new_action (GSimpleAction *action,
{ {
GtkAllocation allocation; GtkAllocation allocation;
GeglColor *color; GeglColor *color;
GimpRGB rgb;
gint i; gint i;
AffElement *elem; AffElement *elem;
@ -2638,12 +2674,10 @@ ifs_compose_new_action (GSimpleAction *action,
undo_begin (); undo_begin ();
color = gimp_context_get_foreground (); color = gimp_context_get_foreground ();
gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb);
g_object_unref (color);
elem = aff_element_new (0.5, 0.5 * allocation.height / allocation.width, elem = aff_element_new (0.5, 0.5 * allocation.height / allocation.width,
&rgb, color, ++count_for_naming);
++count_for_naming); g_object_unref (color);
ifsvals.num_elements++; ifsvals.num_elements++;
elements = g_realloc (elements, ifsvals.num_elements * sizeof (AffElement *)); elements = g_realloc (elements, ifsvals.num_elements * sizeof (AffElement *));
@ -2870,6 +2904,11 @@ window_destroy (GtkWidget *widget,
if (ifsOptD) if (ifsOptD)
gtk_widget_destroy (ifsOptD->dialog); gtk_widget_destroy (ifsOptD->dialog);
color_map_free (ifsD->red_cmap);
color_map_free (ifsD->green_cmap);
color_map_free (ifsD->blue_cmap);
color_map_free (ifsD->black_cmap);
color_map_free (ifsD->target_cmap);
g_free (ifsD); g_free (ifsD);
gtk_application_remove_window (ifs->app, GTK_WINDOW (ifs->dialog)); gtk_application_remove_window (ifs->app, GTK_WINDOW (ifs->dialog));

View file

@ -32,24 +32,24 @@ typedef struct {
} IPolygon; } IPolygon;
typedef struct { typedef struct {
gdouble x, y; gdouble x, y;
gdouble theta; gdouble theta;
gdouble scale; gdouble scale;
gdouble asym; gdouble asym;
gdouble shear; gdouble shear;
gint flip; gint flip;
GimpRGB red_color; GeglColor *red_color;
GimpRGB green_color; GeglColor *green_color;
GimpRGB blue_color; GeglColor *blue_color;
GimpRGB black_color; GeglColor *black_color;
GimpRGB target_color; GeglColor *target_color;
gdouble hue_scale; gdouble hue_scale;
gdouble value_scale; gdouble value_scale;
gint simple_color; gint simple_color;
gdouble prob; gdouble prob;
} AffElementVals; } AffElementVals;
typedef struct typedef struct
@ -131,7 +131,7 @@ gint ipolygon_contains (IPolygon *poly,
/* manipulation of composite transforms */ /* manipulation of composite transforms */
AffElement *aff_element_new (gdouble x, AffElement *aff_element_new (gdouble x,
gdouble y, gdouble y,
GimpRGB *color, GeglColor *color,
gint count); gint count);
void aff_element_free (AffElement *elem); void aff_element_free (AffElement *elem);
void aff_element_compute_trans (AffElement *elem, void aff_element_compute_trans (AffElement *elem,