1 /*	layer.c
2 	Copyright (C) 2005-2017 Mark Tyler and Dmitry Groshev
3 
4 	This file is part of mtPaint.
5 
6 	mtPaint is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 3 of the License, or
9 	(at your option) any later version.
10 
11 	mtPaint is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with mtPaint in the file COPYING.
18 */
19 
20 #include "global.h"
21 #undef _
22 #define _(X) X
23 
24 #include "mygtk.h"
25 #include "memory.h"
26 #include "vcode.h"
27 #include "ani.h"
28 #include "png.h"
29 #include "layer.h"
30 #include "mainwindow.h"
31 #include "otherwindow.h"
32 #include "canvas.h"
33 #include "inifile.h"
34 #include "viewer.h"
35 #include "channels.h"
36 #include "icons.h"
37 
38 
39 int	layers_total,		// Layers currently being used
40 	layer_selected,		// Layer currently selected in the layers window
41 	layers_changed;		// 0=Unchanged
42 
43 char layers_filename[PATHBUF];		// Current filename for layers file
44 int	show_layers_main,		// Show all layers in main window
45 	layer_overlay;			// Toggle overlays per layer
46 
47 
48 // !!! Always follow adding/changing layer's image_info by update_undo()
49 layer_node layer_table[(MAX_LAYERS + 1) * 2];	// Table of layer info & its backup
50 layer_node *layer_table_p = layer_table;	// Unmodified layer table
51 
52 
layer_clear_slot(int l,int visible)53 static void layer_clear_slot(int l, int visible)
54 {
55 	memset(layer_table + l, 0, sizeof(layer_node));
56 	layer_table[l].opacity = 100;
57 	layer_table[l].visible = visible;
58 }
59 
layers_init()60 void layers_init()
61 {
62 	layer_clear_slot(0, TRUE);
63 	strncpy0(layer_table[0].name, __("Background"), LAYER_NAMELEN);
64 	layer_table[0].image = calloc(1, sizeof(layer_image));
65 }
66 
67 /* Allocate layer image, its channels and undo stack
68  * !!! Must be followed by update_undo() after setting up image is done */
alloc_layer(int w,int h,int bpp,int cmask,image_info * src)69 layer_image *alloc_layer(int w, int h, int bpp, int cmask, image_info *src)
70 {
71 	layer_image *lim;
72 
73 	lim = calloc(1, sizeof(layer_image));
74 	if (!lim) return (NULL);
75 	if (init_undo(&lim->image_.undo_, mem_undo_depth) &&
76 		mem_alloc_image(src ? AI_COPY : 0, &lim->image_, w, h, bpp, cmask, src))
77 		return (lim);
78 	mem_free_image(&lim->image_, FREE_UNDO);
79 	free(lim);
80 	return (NULL);
81 }
82 
83 /* Repaint layer in view/main window */
repaint_layer(int l)84 static void repaint_layer(int l)
85 {
86 	image_info *image = l == layer_selected ? &mem_image :
87 		&layer_table[l].image->image_;
88 	lr_update_area(l, 0, 0, image->width, image->height);
89 }
90 
repaint_layers()91 static void repaint_layers()
92 {
93 	update_stuff(show_layers_main ? UPD_ALLV : UPD_VIEW);
94 }
95 
96 
97 ///	LAYERS WINDOW
98 
99 typedef struct {
100 	int lock;
101 	int x, y, opacity, trans;
102 	int nlayer, lnum;
103 	int vis;
104 	char *lname;
105 	void **llist, **nmentry, **xspin, **yspin, **opslider, **trspin;
106 	void **ltb_new, **ltb_raise, **ltb_lower, **ltb_dup, **ltb_center,
107 		**ltb_del, **ltb_close;
108 } layers_dd;
109 
110 static void **layers_box_, **layers_window_;
111 
112 
layers_update_titlebar()113 static void layers_update_titlebar()		// Update filename in titlebar
114 {
115 	char txt[300], txt2[PATHTXT];
116 
117 
118 	if (!layers_window_) return;	// Don't bother if window is not showing
119 
120 	gtkuncpy(txt2, layers_filename, PATHTXT);
121 	snprintf(txt, 290, "%s %s %s", __("Layers"),
122 		layers_changed ? __("(Modified)") : "-",
123 		txt2[0] ? txt2 : __("Untitled"));
124 	cmd_setv(GET_WINDOW(layers_window_), txt, WINDOW_TITLE);
125 }
126 
layers_notify_changed()127 void layers_notify_changed()			// Layers have just changed - update vars as needed
128 {
129 	if ( layers_changed != 1 )
130 	{
131 		layers_changed = 1;
132 		layers_update_titlebar();
133 	}
134 }
135 
layers_notify_unchanged()136 static void layers_notify_unchanged()		// Layers have just been unchanged (saved) - update vars as needed
137 {
138 	if ( layers_changed != 0 )
139 	{
140 		layers_changed = 0;
141 		layers_update_titlebar();
142 	}
143 }
144 
145 
layer_copy_from_main(int l)146 void layer_copy_from_main( int l )	// Copy info from main image to layer
147 {
148 	layer_image *lp = layer_table[l].image;
149 
150 	lp->image_ = mem_image;
151 	lp->state_ = mem_state;
152 	lp->image_.undo_.size = 0; // Invalidate
153 	update_undo(&lp->image_); // Safety net
154 }
155 
layer_copy_to_main(int l)156 void layer_copy_to_main( int l )		// Copy info from layer to main image
157 {
158 	layer_image *lp = layer_table[l].image;
159 
160 	if (!layer_overlay)
161 	{
162 		lp->state_.iover = mem_state.iover;
163 		lp->state_.aover = mem_state.aover;
164 	}
165 	mem_image = lp->image_;
166 	mem_state = lp->state_;
167 }
168 
shift_layer(int val)169 void shift_layer(int val)
170 {
171 	layers_dd *dt = GET_DDATA(layers_box_);
172 	layer_node temp;
173 	int newbkg, lv = layer_selected + val;
174 
175 	if ((lv < 0) || (lv > layers_total)) return; // Cannot move
176 
177 	/* Update source layer */
178 	if ((blend_src == SRC_LAYER + layer_selected) || (blend_src == SRC_LAYER + lv))
179 		blend_src ^= (SRC_LAYER + layer_selected) ^ (SRC_LAYER + lv);
180 
181 	layer_copy_from_main(layer_selected);
182 	temp = layer_table[layer_selected];
183 	layer_table[layer_selected] = layer_table[lv];
184 	layer_table[lv] = temp;
185 	newbkg = (layer_selected == 0) || (lv == 0);
186 
187 	cmd_setv(dt->llist, (void *)layer_selected, LISTCC_RESET_ROW);
188 	cmd_setv(dt->llist, (void *)lv, LISTCC_RESET_ROW);
189 	cmd_set(dt->llist, layer_selected = lv);
190 	layers_notify_changed();
191 
192 	if (newbkg)	// Background layer changed
193 	{
194 		vw_realign();
195 		repaint_layers();
196 	}
197 	else repaint_layer(layer_selected);	// Regular layer shifted
198 }
199 
layer_show_new()200 void layer_show_new()
201 {
202 	layer_refresh_list(layers_total);
203 	layers_notify_changed();
204 }
205 
layer_add(int w,int h,int bpp,int cols,png_color * pal,int cmask)206 int layer_add(int w, int h, int bpp, int cols, png_color *pal, int cmask)
207 {
208 	layer_image *lim;
209 
210 	if (layers_total >= MAX_LAYERS) return (FALSE);
211 
212 	lim = alloc_layer(w, h, bpp, cmask, NULL);
213 	if (!lim)
214 	{
215 		memory_errors(1);
216 		return (FALSE);
217 	}
218 	lim->state_.xbm_hot_x = lim->state_.xbm_hot_y = -1;
219 	lim->state_.channel = lim->image_.img[mem_channel] ? mem_channel : CHN_IMAGE;
220 
221 	lim->image_.trans = -1;
222 	lim->image_.cols = cols;
223 	if (pal) mem_pal_copy(lim->image_.pal, pal);
224 	else mem_bw_pal(lim->image_.pal, 0, cols - 1);
225 
226 	init_istate(&lim->state_, &lim->image_);
227 	update_undo(&lim->image_);
228 
229 	layers_total++;
230 	layer_clear_slot(layers_total, TRUE);
231 	layer_table[layers_total].image = lim;
232 
233 	/* Start with fresh animation data if new */
234 	if (layers_total == 1) ani_init();
235 
236 	return (TRUE);
237 }
238 
layer_new(int w,int h,int bpp,int cols,png_color * pal,int cmask)239 void layer_new(int w, int h, int bpp, int cols, png_color *pal, int cmask)
240 {
241 	if (layer_add(w, h, bpp, cols, pal, cmask)) layer_show_new();
242 }
243 
244 /* !!! Same as above: modify structures, *then* show results - WJ */
layer_press_duplicate()245 void layer_press_duplicate()
246 {
247 	layer_image *lim, *ls;
248 
249 	if (layers_total >= MAX_LAYERS) return;
250 
251 	lim = alloc_layer(0, 0, 0, 0, &mem_image);
252 	if (!lim)
253 	{
254 		memory_errors(1);
255 		return;
256 	}
257 
258 	// Copy layer info
259 	layer_copy_from_main(layer_selected);
260 	layers_total++;
261 	layer_table[layers_total] = layer_table[layer_selected];
262 	layer_table[layers_total].image = lim;
263 	ls = layer_table[layer_selected].image;
264 
265 	lim->state_ = ls->state_;
266 	mem_pal_copy(lim->image_.pal, ls->image_.pal);
267 	lim->image_.cols = ls->image_.cols;
268 	lim->image_.trans = ls->image_.trans;
269 	update_undo(&lim->image_);
270 
271 	// Copy across position data
272 	lim->ani_ = ls->ani_;
273 
274 	layer_show_new();
275 }
276 
layer_delete(int item)277 void layer_delete(int item)
278 {
279 	layer_image *lp = layer_table[item].image;
280 	int i;
281 
282 	mem_free_image(&lp->image_, FREE_ALL);
283 	free(lp);
284 
285 	// If deleted item is not at the end shuffle rest down
286 	for (i = item; i < layers_total; i++)
287 		layer_table[i] = layer_table[i + 1];
288 	memset(layer_table + layers_total, 0, sizeof(layer_node));
289 	layers_total--;
290 }
291 
layer_refresh_list(int slot)292 void layer_refresh_list(int slot)
293 {
294 	layers_dd *dt = GET_DDATA(layers_box_);
295 
296 	dt->nlayer = slot;
297 	dt->lnum = layers_total + 1;
298 	cmd_reset(dt->llist, dt);
299 	cmd_set(dt->llist, slot); // !!! For the rest of updates
300 }
301 
layer_press_delete()302 void layer_press_delete()
303 {
304 	char txt[256];
305 	int i;
306 
307 	if (!layer_selected) return; // Deleting background is forbidden
308 	snprintf(txt, 256, __("Do you really want to delete layer %i (%s) ?"),
309 		layer_selected, layer_table[layer_selected].name );
310 
311 	i = alert_box(_("Warning"), txt, _("No"), _("Yes"), NULL);
312 	if ((i != 2) || (check_for_changes() == 1)) return;
313 
314 	if (blend_src == SRC_LAYER + layer_selected) blend_src = SRC_NORMAL;
315 	layer_copy_from_main(layer_selected);
316 	layer_copy_to_main(--layer_selected);
317 	update_main_with_new_layer();
318 	layer_delete(layer_selected + 1);
319 
320 	layer_refresh_list(layer_selected);
321 	layers_notify_changed();
322 }
323 
layer_show_position()324 static void layer_show_position()
325 {
326 	layers_dd *dt = GET_DDATA(layers_box_);
327 	layer_node *t = layer_table + layer_selected;
328 
329 	dt->lock++;
330 	cmd_set(dt->xspin, t->x);
331 	cmd_set(dt->yspin, t->y);
332 	dt->lock--;
333 }
334 
layer_show_trans()335 void layer_show_trans()
336 {
337 	layers_dd *dt = GET_DDATA(layers_box_);
338 
339 	if (dt->trans != mem_xpm_trans)
340 	{
341 		dt->lock++;
342 		cmd_set(dt->trspin, mem_xpm_trans);
343 		dt->lock--;
344 	}
345 }
346 
layer_press_centre()347 void layer_press_centre()
348 {
349 	if (!layer_selected) return; // Nothing to do
350 	layer_table[layer_selected].x = layer_table[0].x +
351 		layer_table[0].image->image_.width / 2 - mem_width / 2;
352 	layer_table[layer_selected].y = layer_table[0].y +
353 		layer_table[0].image->image_.height / 2 - mem_height / 2;
354 	layer_show_position();
355 	layers_notify_changed();
356 	repaint_layers();
357 }
358 
359 /* Return 1 if some layers are modified, 2 if some are nameless, 3 if both,
360  * 0 if neither */
layers_changed_tot()361 static int layers_changed_tot()
362 {
363 	image_info *image;
364 	int j, k;
365 
366 	for (j = k = 0; k <= layers_total; k++) // Check each layer for mem_changed
367 	{
368 		image = k == layer_selected ? &mem_image :
369 			&layer_table[k].image->image_;
370 		j |= !!image->changed + !image->filename * 2;
371 	}
372 
373 	return (j);
374 }
375 
check_layers_for_changes()376 int check_layers_for_changes()		// 1=STOP, 2=IGNORE, -10=NOT CHANGED
377 {
378 	if (!(layers_changed_tot() + layers_changed)) return (-10);
379 	return (alert_box(_("Warning"),
380 		_("One or more of the layers contains changes that have not been saved.  Do you really want to lose these changes?"),
381 		_("Cancel Operation"), _("Lose Changes"), NULL));
382 }
383 
layer_update_filename(char * name)384 static void layer_update_filename( char *name )
385 {
386 	strncpy(layers_filename, name, PATHBUF);
387 	layers_changed = 1;		// Forces update of titlebar
388 	layers_notify_unchanged();
389 }
390 
layers_free_all()391 static void layers_free_all()
392 {
393 	layer_node *t;
394 
395 	if (blend_src > SRC_LAYER + 0) blend_src = SRC_NORMAL;
396 
397 	if (layers_total && layer_selected)	// Copy over layer 0
398 	{
399 		layer_copy_from_main(layer_selected);
400 		layer_copy_to_main(0);
401 		layer_selected = 0;
402 	}
403 
404 	for (t = layer_table + layers_total; t != layer_table; t--)
405 	{
406 		mem_free_image(&t->image->image_, FREE_ALL);
407 		free(t->image);
408 	}
409 	memset(layer_table + 1, 0, sizeof(layer_node) * MAX_LAYERS);
410 	layers_total = 0;
411 	layers_filename[0] = 0;
412 	layers_changed = 0;
413 }
414 
string_chop(char * txt)415 void string_chop( char *txt )
416 {
417 	char *cp = txt + strlen(txt) - 1;
418 
419 	// Chop off unwanted non ASCII characters at end
420 	while ((cp - txt >= 0) && ((unsigned char)*cp < 32)) *cp-- = 0;
421 }
422 
read_file_num(FILE * fp,char * txt)423 int read_file_num(FILE *fp, char *txt)
424 {
425 	int i;
426 
427 	if (!fgets(txt, 32, fp)) return -987654321;
428 	sscanf(txt, "%i", &i);
429 
430 	return i;
431 }
432 
load_layers(char * file_name)433 int load_layers( char *file_name )
434 {
435 	layer_node *t;
436 	layer_image *lim2;
437 	char tin[300], load_name[PATHBUF], *c;
438 	int i, j, k, kk;
439 	int layers_to_read = -1, /*layer_file_version = -1,*/ lfail = 0, lplen = 0;
440 	FILE *fp;
441 
442 	c = strrchr(file_name, DIR_SEP);
443 	if (c) lplen = c - file_name + 1;
444 
445 		// Try to save text file, return -1 if failure
446 	if ((fp = fopen(file_name, "r")) == NULL) goto fail;
447 
448 	if (!fgets(tin, 32, fp)) goto fail2;
449 
450 	string_chop( tin );
451 	if ( strcmp( tin, LAYERS_HEADER ) != 0 ) goto fail2;		// Bad header
452 
453 	i = read_file_num(fp, tin);
454 	if ( i==-987654321 ) goto fail2;
455 //	layer_file_version = i;
456 	if ( i>LAYERS_VERSION ) goto fail2;		// Version number must be compatible
457 
458 	i = read_file_num(fp, tin);
459 	if ( i==-987654321 ) goto fail2;
460 	layers_to_read = i < MAX_LAYERS ? i : MAX_LAYERS;
461 
462 	/* !!! Can use lock field instead, but this is the original way */
463 	cmd_sensitive(GET_WINDOW(layers_box_), FALSE);
464 
465 	if (layers_total) layers_free_all();	// Remove all current layers if any
466 	for ( i=0; i<=layers_to_read; i++ )
467 	{
468 		// Read filename, strip end chars & try to load (if name length > 0)
469 		fgets(tin, 256, fp);
470 		string_chop(tin);
471 		wjstrcat(load_name, PATHBUF, file_name, lplen, tin, NULL);
472 		k = 1;
473 		j = detect_image_format(load_name);
474 		if ((j > 0) && (j != FT_NONE) && (j != FT_LAYERS1))
475 			k = load_image(load_name, FS_LAYER_LOAD, j) != 1;
476 
477 		if (k) /* Failure - skip this layer */
478 		{
479 			for ( j=0; j<7; j++ ) read_file_num(fp, tin);
480 			lfail++;
481 			continue;
482 		}
483 
484 		/* Update image variables after load */
485 		t = layer_table + layers_total;
486 		lim2 = t->image;
487 		// !!! No old name so no fuss with saving it
488 		lim2->image_.filename = strdup(load_name);
489 
490 		fgets(tin, 256, fp);
491 		string_chop(tin);
492 		strncpy0(t->name, tin, LAYER_NAMELEN);
493 
494 		k = read_file_num(fp, tin);
495 		t->visible = k > 0;
496 
497 		t->x = read_file_num(fp, tin);
498 		t->y = read_file_num(fp, tin);
499 
500 		kk = read_file_num(fp, tin);
501 		k = read_file_num(fp, tin);
502 		lim2->image_.trans = kk <= 0 ? -1 : k < 0 ? 0 : k > 255 ? 255 : k;
503 
504 		k = read_file_num(fp, tin);
505 		t->opacity = k < 1 ? 1 : k > 100 ? 100 : k;
506 
507 		init_istate(&lim2->state_, &lim2->image_);
508 		if (!layers_total++) layer_copy_to_main(0); // Update mem_state
509 	}
510 	if (layers_total) layers_total--;
511 
512 	/* Read in animation data - only if all layers loaded OK
513 	 * (to do otherwise is likely to result in SIGSEGV) */
514 	if (!lfail) ani_read_file(fp);
515 	fclose(fp);
516 
517 	layer_refresh_list(layers_total);
518 	cmd_sensitive(GET_WINDOW(layers_box_), TRUE);
519 	layer_update_filename( file_name );
520 
521 	if (lfail) /* There were failures */
522 	{
523 		snprintf(tin, 300, __("%d layers failed to load"), lfail);
524 		alert_box(_("Error"), tin, NULL);
525 	}
526 
527 	return 1;		// Success
528 fail2:
529 	fclose(fp);
530 fail:
531 	return -1;
532 }
533 
load_to_layers(char * file_name,int ftype,int ani_mode)534 int load_to_layers(char *file_name, int ftype, int ani_mode)
535 {
536 	char *buf, *tail;
537 	image_frame *frm;
538 	image_info *image;
539 	image_state *state;
540 	layer_node *t;
541 	layer_image *lim;
542 	frameset fset;
543 	int anim = ani_mode > ANM_PAGE;
544 	int i, j, l, res, res0, lname;
545 
546 
547 	/* Create buffer for name mangling */
548 	lname = strlen(file_name);
549 	buf = malloc(lname + 64);
550 	if (!buf) return (FILE_MEM_ERROR);
551 	strcpy(buf, file_name);
552 	tail = buf + lname;
553 
554 	/* !!! Can use lock field instead, but this is the original way */
555 	cmd_sensitive(GET_WINDOW(layers_box_), FALSE);
556 
557 	/* Remove old layers, load new frames */
558 	if (layers_total) layers_free_all();	// Remove all current layers
559 	res = res0 = load_frameset(&fset, ani_mode, file_name, FS_LAYER_LOAD, ftype);
560 
561 	if (!fset.cnt) /* Failure - we have no image */
562 	{
563 		if (res == FILE_LIB_ERROR) res = -1; // Failure is complete
564 	}
565 	else /* Got some frames - convert into layers */
566 	{
567 		l = 0; // Start from layer 0
568 		if (anim) /* Animation */
569 		{
570 			int x0, y0, x1, y1, x, y;
571 
572 			frm = fset.frames;
573 			/* Calculate a bounding box for the anim */
574 			x1 = (x0 = frm->x) + frm->width;
575 			y1 = (y0 = frm->y) + frm->height;
576 			for (i = 1; i < fset.cnt; i++)
577 			{
578 				frm++;
579 				x = frm->x; if (x0 > x) x0 = x;
580 				x += frm->width; if (x1 < x) x1 = x;
581 				y = frm->y; if (y0 > y) y0 = y;
582 				y += frm->height; if (y1 < y) y1 = y;
583 			}
584 			/* Create an empty indexed background of that size */
585 			do_new_one(x1 - x0, y1 - y0, 256, mem_pal_def, 1, FALSE);
586 			/* Remember the offsets */
587 			layer_table[0].x = x0;
588 			layer_table[0].y = y0;
589 			l = 1; // Frames start from layer 1
590 		}
591 
592 		for (i = 0; i < fset.cnt; i++ , l++)
593 		{
594 			frm = fset.frames + i;
595 
596 			t = layer_table + l;
597 			res = FILE_MEM_ERROR;
598 			if (!l) // Layer 0 aka current image
599 			{
600 				if (mem_new(frm->width, frm->height, frm->bpp, 0))
601 					break;
602 				layer_copy_from_main(0);
603 			}
604 			else
605 			{
606 				if (!(t->image = alloc_layer(frm->width, frm->height,
607 					frm->bpp, 0, NULL))) break;
608 			}
609 			res = res0;
610 			lim = t->image;
611 			t->visible = !anim;
612 			t->opacity = 100;
613 			image = &lim->image_; state = &lim->state_;
614 
615 			/* Move frame data to image */
616 			memcpy(image->img, frm->img, sizeof(chanlist));
617 			memset(frm->img, 0, sizeof(chanlist));
618 			image->trans = frm->trans;
619 			mem_pal_copy(image->pal, frm->pal ? frm->pal :
620 				fset.pal ? fset.pal : mem_pal_def);
621 			image->cols = frm->cols;
622 			t->x = frm->x; t->y = frm->y;
623 			update_undo(image);
624 
625 			/* Create a name for this frame */
626 			sprintf(tail, ".%03d", i);
627 			// !!! No old name so no fuss with saving it
628 			image->filename = strdup(buf);
629 
630 			init_istate(state, image);
631 			if (!l) layer_copy_to_main(0); // Update everything
632 		}
633 		layers_total = l ? l - 1 : 0;
634 
635 		if (anim)
636 		{
637 // !!! These legacy things need be replaced by a per-layer field
638 			preserved_gif_delay = ani_gif_delay = fset.frames[0].delay;
639 
640 			/* Clear stale cycles */
641 			memset(ani_cycle_table, 0, sizeof(ani_cycle_table));
642 			/* Build animation cycle for these layers */
643 			ani_frame1 = ani_cycle_table[0].frame0 = 1;
644 			ani_frame2 = ani_cycle_table[0].frame1 = l - 1;
645 			ani_cycle_table[0].len = l - 1;
646 			for (j = 1; j < l; j++)
647 			{
648 				unsigned char *cp = layer_table[j].image->ani_.cycles;
649 				cp[0] = 1; // Cycle # + 1
650 				cp[1] = j - 1; // Position
651 			}
652 
653 			/* Display 1st layer in sequence */
654 			layer_table[1].visible = TRUE;
655 			layer_copy_from_main(0);
656 			layer_copy_to_main(layer_selected = 1);
657 		}
658 		update_main_with_new_layer();
659 	}
660 	mem_free_frames(&fset);
661 
662 	layer_refresh_list(layer_selected);
663 	cmd_sensitive(GET_WINDOW(layers_box_), TRUE);
664 
665 	/* Name change so that layers file would not overwrite the source */
666 	strcpy(tail, ".txt");
667 	layer_update_filename(buf);
668 
669 	free(buf);
670 	return (res);
671 }
672 
673 /* Convert absolute filename 'file' into one relative to prefix */
parse_filename(char * dest,char * prefix,char * file,int len)674 static void parse_filename(char *dest, char *prefix, char *file, int len)
675 {
676 	int i, k;
677 
678 	/* # of chars that match at start */
679 	for (i = 0; (i < len) && (prefix[i] == file[i]); i++);
680 
681 	if (!i || (i == len)) /* Complete match, or no match at all */
682 		strncpy(dest, file + i, PATHBUF);
683 	else	/* Partial match */
684 	{
685 		dest[0] = 0;
686 		/* Count number of DIR_SEP encountered on and after point i in
687 		 * 'prefix', add a '../' for each found */
688 		for (k = i; k < len; k++)
689 		{
690 			if (prefix[k] == DIR_SEP)
691 				strnncat(dest, ".." DIR_SEP_STR, PATHBUF);
692 		}
693 		/* nip backwards on 'file' from i to previous DIR_SEP or
694 		 * beginning and ... */
695 		for (k = i; (k >= 0) && (file[k] != DIR_SEP); k--);
696 		/* ... add rest of 'file' */
697 		strnncat(dest, file + k + 1, PATHBUF);
698 	}
699 }
700 
layer_save_composite(char * fname,ls_settings * settings)701 int layer_save_composite(char *fname, ls_settings *settings)
702 {
703 	image_info *image;
704 	unsigned char *layer_rgb;
705 	int w, h, res = 0, tf = comp_need_alpha(settings->ftype);
706 
707 	image = layer_selected ? &layer_table[0].image->image_ : &mem_image;
708 	w = image->width;
709 	h = image->height;
710 	layer_rgb = calloc(1, w * h * (3 + !!tf));
711 	if (layer_rgb)
712 	{
713 		view_render_rgb(layer_rgb, 0, 0, w, h, 1);	// Render layer
714 		if (tf)
715 		{
716 			unsigned char *alpha = layer_rgb + w * h * 3;
717 			collect_alpha(alpha, w, h);
718 			mem_demultiply(layer_rgb, alpha, w * h, 3);
719 			settings->img[CHN_ALPHA] = alpha;
720 		}
721 		settings->img[CHN_IMAGE] = layer_rgb;
722 		settings->width = w;
723 		settings->height = h;
724 		settings->bpp = 3;
725 		if (layers_total) /* Remember global offset */
726 		{
727 			settings->x = layer_table[0].x;
728 			settings->y = layer_table[0].y;
729 		}
730 		/* Set up palette to go with transparency */
731 		if (settings->xpm_trans >= 0)
732 		{
733 			settings->pal = image->pal;
734 			settings->colors = image->cols;
735 		}
736 		res = save_image(fname, settings);
737 		free( layer_rgb );
738 	}
739 	else memory_errors(1);
740 
741 	return res;
742 }
743 
layer_add_composite()744 void layer_add_composite()
745 {
746 	layer_image *lim;
747 	image_info *image = layer_selected ? &layer_table[0].image->image_ :
748 		&mem_image;
749 	unsigned char **img;
750 	int w = image->width, h = image->height;
751 
752 	if (layers_total >= MAX_LAYERS) return;
753 	if (layer_add(w, h, 3, image->cols, image->pal,
754 		comp_need_alpha(FT_NONE) ? CMASK_RGBA : CMASK_IMAGE))
755 	{
756 		/* Render to an invisible layer */
757 		layer_table[layers_total].visible = FALSE;
758 		lim = layer_table[layers_total].image;
759 		img = lim->image_.img;
760 		view_render_rgb(img[CHN_IMAGE], 0, 0, w, h, 1);
761 		/* Add alpha if wanted */
762 		if (img[CHN_ALPHA])
763 		{
764 			collect_alpha(img[CHN_ALPHA], w, h);
765 			mem_demultiply(img[CHN_IMAGE], img[CHN_ALPHA], w * h, 3);
766 		}
767 		/* Copy background's transparency and position */
768 		lim->image_.trans = image->trans;
769 		layer_table[layers_total].x = layer_table[0].x;
770 		layer_table[layers_total].y = layer_table[0].y;
771 		/* Activate the result */
772 		layer_show_new();
773 	}
774 	else memory_errors(1);
775 }
776 
save_layers(char * file_name)777 int save_layers( char *file_name )
778 {
779 	layer_node *t;
780 	char comp_name[PATHBUF], *c, *msg;
781 	int i, l = 0, xpm;
782 	FILE *fp;
783 
784 
785 	layer_copy_from_main(layer_selected);
786 
787 	c = strrchr(file_name, DIR_SEP);
788 	if (c) l = c - file_name + 1;
789 
790 		// Try to save text file, return -1 if failure
791 	if ((fp = fopen(file_name, "w")) == NULL) goto fail;
792 
793 	fprintf( fp, "%s\n%i\n%i\n", LAYERS_HEADER, LAYERS_VERSION, layers_total );
794 	for ( i=0; i<=layers_total; i++ )
795 	{
796 		t = layer_table + i;
797 		parse_filename(comp_name, file_name, t->image->image_.filename, l);
798 		fprintf( fp, "%s\n", comp_name );
799 
800 		xpm = t->image->image_.trans;
801 		fprintf(fp, "%s\n%i\n%i\n%i\n%i\n%i\n%i\n", t->name,
802 			t->visible, t->x, t->y, xpm >= 0, xpm, t->opacity);
803 	}
804 
805 	ani_write_file(fp);			// Write animation data
806 
807 	fclose(fp);
808 	layer_update_filename( file_name );
809 	register_file( file_name );		// Recently used file list / last directory
810 
811 	return 1;		// Success
812 fail:
813 	c = gtkuncpy(NULL, layers_filename, 0);
814 	msg = g_strdup_printf(__("Unable to save file: %s"), c);
815 	alert_box(_("Error"), msg, NULL);
816 	g_free(msg);
817 	g_free(c);
818 
819 	return -1;
820 }
821 
822 
check_layers_all_saved()823 int check_layers_all_saved()
824 {
825 	if (layers_changed_tot() < 2) return (0);
826 	alert_box(_("Warning"), _("One or more of the image layers has not been saved.  You must save each image individually before saving the layers text file in order to load this composite image in the future."), NULL);
827 	return (1);
828 }
829 
layer_press_save()830 void layer_press_save()
831 {
832 	if (!layers_filename[0]) file_selector(FS_LAYER_SAVE);
833 	else if (!check_layers_all_saved()) save_layers(layers_filename);
834 }
835 
layer_press_remove_all()836 void layer_press_remove_all()
837 {
838 	int i = check_layers_for_changes();
839 
840 	if (i < 0) i = alert_box(_("Warning"),
841 		_("Do you really want to delete all of the layers?"),
842 		_("No"), _("Yes"), NULL);
843 	if (i != 2) return;
844 
845 	layers_free_all();
846 
847 	layer_refresh_list(0);
848 	update_main_with_new_layer();
849 }
850 
layer_tog_visible(layers_dd * dt,void ** wdata,int what,void ** where,void * xdata)851 static void layer_tog_visible(layers_dd *dt, void **wdata, int what,
852 	void **where, void *xdata)
853 {
854 	/* !!! Column is self-reading */
855 	if (dt->lock) return;
856 	layers_notify_changed();
857 	repaint_layer((int)xdata); // !!! row passed in there
858 }
859 
layer_inputs_changed(layers_dd * dt,void ** wdata,int what,void ** where)860 static void layer_inputs_changed(layers_dd *dt, void **wdata, int what,
861 	void **where)
862 {
863 	layer_node *t = layer_table + layer_selected;
864 	void *cause;
865 	int dx, dy;
866 
867 	cause = cmd_read(where, dt);
868 	if (cause == &show_layers_main)
869 	{
870 		update_stuff(UPD_RENDER);
871 		return;
872 	}
873 	if (dt->lock) return;
874 
875 	layers_notify_changed();
876 
877 	if (cause == &dt->lname) // Name entry
878 	{
879 		strncpy0(t->name, dt->lname, LAYER_NAMELEN);
880 		cmd_setv(dt->llist, (void *)layer_selected, LISTCC_RESET_ROW);
881 	}
882 	else if ((cause == &dt->x) || (cause == &dt->y)) // Position spin
883 	{
884 		dx = dt->x - t->x;
885 		dy = dt->y - t->y;
886 		if (dx | dy) move_layer_relative(layer_selected, dx, dy);
887 	}
888 	else if (cause == &dt->opacity) // Opacity slider
889 	{
890 		t->opacity = dt->opacity;
891 		repaint_layer(layer_selected);
892 	}
893 	else if (cause == &dt->vis) // Scripted visibility toggle
894 	{
895 		t->visible = dt->vis;
896 		cmd_setv(dt->llist, (void *)layer_selected, LISTCC_RESET_ROW);
897 		repaint_layer(layer_selected);
898 	}
899 	else /* if (cause == &dt->trans) */ // Transparency spin
900 	{
901 		mem_set_trans(dt->trans);
902 	}
903 }
904 
layer_choose(int l)905 void layer_choose(int l)	// Select a new layer from the list
906 {
907 	if ((l <= layers_total) && (l >= 0) && (l != layer_selected))
908 	{
909 		layers_dd *dt = GET_DDATA(layers_box_);
910 		cmd_set(dt->llist, l);
911 	}
912 }
913 
layer_select(layers_dd * dt,void ** wdata,int what,void ** where)914 static void layer_select(layers_dd *dt, void **wdata, int what, void **where)
915 {
916 	layer_node *t;
917 	int j;
918 
919 	cmd_read(where, dt);
920 	if (dt->lock) return; // Paranoia
921 
922 	j = dt->nlayer;
923 	if (j > layers_total) return; // Paranoia
924 
925 	dt->lock++;
926 	if (j != layer_selected) /* Move data before doing anything else */
927 	{
928 		layer_copy_from_main(layer_selected);
929 		layer_copy_to_main(layer_selected = j);
930 		update_main_with_new_layer();
931 	}
932 
933 	t = layer_table + j;
934 	cmd_setv(dt->nmentry, t->name, ENTRY_VALUE);
935 	cmd_sensitive(dt->ltb_raise, j < layers_total);
936 	cmd_sensitive(dt->ltb_lower, j);
937 	cmd_sensitive(dt->ltb_del, j);
938 	cmd_sensitive(dt->ltb_center, j);
939 	// Disable new/duplicate if we have max layers
940 	cmd_sensitive(dt->ltb_new, layers_total < MAX_LAYERS);
941 	cmd_sensitive(dt->ltb_dup, layers_total < MAX_LAYERS);
942 
943 	cmd_set(dt->opslider, t->opacity);
944 	layer_show_position();
945 	layer_show_trans();
946 
947 	dt->lock--;
948 }
949 
delete_layers_window()950 void delete_layers_window()
951 {
952 	void **wdata = layers_window_;
953 
954 	// No deletion if no window
955 	if (!wdata) return;
956 
957 	layers_window_ = NULL;
958 	cmd_set(menu_slots[MENU_LAYER], FALSE); // Ensure it's unchecked
959 	run_destroy(wdata);
960 }
961 
pressed_paste_layer()962 void pressed_paste_layer()
963 {
964 	layer_image *lim;
965 	unsigned char *dest;
966 	int i, j, k, chan = mem_channel, cmask = CMASK_IMAGE;
967 
968 	if (layers_total >= MAX_LAYERS)
969 	{
970 		alert_box(_("Error"), _("You cannot add any more layers."), NULL);
971 		return;
972 	}
973 
974 	/* No way to put RGB clipboard into utility channel */
975 	if (mem_clip_bpp == 3) chan = CHN_IMAGE;
976 
977 	if ((mem_clip_alpha || mem_clip_mask) && !channel_dis[CHN_ALPHA])
978 		cmask = CMASK_RGBA;
979 	cmask |= CMASK_FOR(chan);
980 
981 	if (!layer_add(mem_clip_w, mem_clip_h, mem_clip_bpp, mem_cols, mem_pal,
982 		cmask)) return; // Failed
983 
984 	layer_table[layers_total].x = layer_table[layer_selected].x + mem_clip_x;
985 	layer_table[layers_total].y = layer_table[layer_selected].y + mem_clip_y;
986 	lim = layer_table[layers_total].image;
987 
988 	lim->state_ = mem_state;
989 	lim->state_.channel = chan;
990 
991 	j = mem_clip_w * mem_clip_h;
992 	memcpy(lim->image_.img[chan], mem_clipboard, j * mem_clip_bpp);
993 
994 	/* Image channel with alpha */
995 	dest = lim->image_.img[CHN_ALPHA];
996 	if (dest && (chan == CHN_IMAGE))
997 	{
998 		/* Fill alpha channel */
999 		if (mem_clip_alpha) memcpy(dest, mem_clip_alpha, j);
1000 		else memset(dest, 255, j);
1001 	}
1002 
1003 	/* Image channel with mask */
1004 	if (mem_clip_mask && (chan == CHN_IMAGE))
1005 	{
1006 		/* Mask image - fill unselected part with color A */
1007 		dest = lim->image_.img[CHN_IMAGE];
1008 		k = mem_clip_bpp == 1 ? mem_col_A : mem_col_A24.red;
1009 		for (i = 0; i < j; i++ , dest += mem_clip_bpp)
1010 		{
1011 			if (mem_clip_mask[i]) continue;
1012 			dest[0] = k;
1013 			if (mem_clip_bpp == 1) continue;
1014 			dest[1] = mem_col_A24.green;
1015 			dest[2] = mem_col_A24.blue;
1016 		}
1017 	}
1018 
1019 	/* Utility channel with mask */
1020 	dest = lim->image_.img[CHN_ALPHA];
1021 	if (chan != CHN_IMAGE) dest = lim->image_.img[chan];
1022 	if (dest && mem_clip_mask)
1023 	{
1024 		/* Mask the channel */
1025 		for (i = 0; i < j; i++)
1026 		{
1027 			k = dest[i] * mem_clip_mask[i];
1028 			dest[i] = (k + (k >> 8) + 1) >> 8;
1029 		}
1030 	}
1031 
1032 	set_new_filename(layers_total, NULL);
1033 
1034 	layer_show_new();
1035 	view_show();
1036 }
1037 
1038 /* Move a layer & update window labels */
move_layer_relative(int l,int change_x,int change_y)1039 void move_layer_relative(int l, int change_x, int change_y)
1040 {
1041 	image_info *image = l == layer_selected ? &mem_image :
1042 		&layer_table[l].image->image_;
1043 	int upd = 0;
1044 
1045 	layer_table[l].x += change_x;
1046 	layer_table[l].y += change_y;
1047 
1048 	layers_notify_changed();
1049 	if (l == layer_selected)
1050 	{
1051 		layer_show_position();
1052 		// All layers get moved while the current one stays still
1053 		if (show_layers_main) upd |= UPD_RENDER;
1054 	}
1055 	// All layers get moved while the background stays still
1056 	if (l == 0) upd |= UPD_VIEW;
1057 
1058 	lr_update_area(l, change_x < 0 ? 0 : -change_x, change_y < 0 ? 0 : -change_y,
1059 		image->width + abs(change_x), image->height + abs(change_y));
1060 	if (upd) update_stuff(upd);
1061 }
1062 
layer_bar_click(layers_dd * dt,void ** wdata,int what,void ** where)1063 static void layer_bar_click(layers_dd *dt, void **wdata, int what, void **where)
1064 {
1065 	int act_m = TOOL_ID(where);
1066 
1067 	action_dispatch(act_m >> 16, (act_m & 0xFFFF) - 0x8000, TRUE, FALSE);
1068 }
1069 
1070 #define WBbase layers_dd
1071 static void *layers_code[] = {
1072 	TOPVBOX,
1073 	SCRIPTED, BORDER(SCROLL, 0), BORDER(LISTCC, 0),
1074 	XSCROLL(1, 1), // auto/auto
1075 	WLIST,
1076 	IDXCOLUMN(0, 1, 40, 1), // center
1077 	XTXTCOLUMNv(layer_table[0].name, sizeof(layer_table[0]), 0, 0), // left
1078 	CHKCOLUMNv(layer_table[0].visible, sizeof(layer_table[0]), 0, 0,
1079 		layer_tog_visible),
1080 	REF(llist), LISTCCHr(nlayer, lnum, MAX_LAYERS + 1, layer_select), TRIGGER,
1081 	BORDER(TOOLBAR, 0),
1082 	TOOLBAR(layer_bar_click),
1083 	REF(ltb_new), TBBUTTON(_("New Layer"), XPM_ICON(new),
1084 		ACTMOD(ACT_LR_ADD, LR_NEW)),
1085 	REF(ltb_raise), TBBUTTON(_("Raise"), XPM_ICON(up),
1086 		ACTMOD(ACT_LR_SHIFT, 1)),
1087 	REF(ltb_lower), TBBUTTON(_("Lower"), XPM_ICON(down),
1088 		ACTMOD(ACT_LR_SHIFT, -1)),
1089 	REF(ltb_dup), TBBUTTON(_("Duplicate Layer"), XPM_ICON(copy),
1090 		ACTMOD(ACT_LR_ADD, LR_DUP)),
1091 	REF(ltb_center), TBBUTTON(_("Centralise Layer"), XPM_ICON(centre),
1092 		ACTMOD(ACT_LR_CENTER, 0)),
1093 	REF(ltb_del), TBBUTTON(_("Delete Layer"), XPM_ICON(cut),
1094 		ACTMOD(ACT_LR_DEL, 0)),
1095 	REF(ltb_close), TBBUTTON(_("Close Layers Window"), XPM_ICON(close),
1096 		ACTMOD(DLG_LAYERS, 1)), UNNAME,
1097 	WDONE,
1098 	TABLEs(3, 4, 5),
1099 	BORDER(LABEL, 0), BORDER(ENTRY, 0),
1100 	BORDER(SPIN, 0), BORDER(SPINSLIDE, 0),
1101 	TLABEL(_("Layer Name")),
1102 	REF(nmentry), MINWIDTH(100), TLENTRY(lname, LAYER_NAMELEN - 1, 1, 0, 2),
1103 	EVENT(CHANGE, layer_inputs_changed),
1104 	TLABEL(_("Position")),
1105 	REF(xspin), TLSPIN(x, -MAX_WIDTH, MAX_WIDTH, 1, 1),
1106 	EVENT(CHANGE, layer_inputs_changed), OPNAME("X"),
1107 	REF(yspin), TLSPIN(y, -MAX_HEIGHT, MAX_HEIGHT, 2, 1),
1108 	EVENT(CHANGE, layer_inputs_changed), OPNAME("Y"),
1109 	TLABEL(_("Opacity")),
1110 	REF(opslider), TLSPINSLIDExl(opacity, 0, 100, 1, 2, 2),
1111 	EVENT(CHANGE, layer_inputs_changed),
1112 	TLLABELl(_("Transparent Colour"), 0, 3, 2),
1113 	REF(trspin), TLSPIN(trans, -1, 255, 2, 3),
1114 	EVENT(CHANGE, layer_inputs_changed),
1115 	uCHECK("Visible", vis), EVENT(SCRIPT, layer_inputs_changed),
1116 	WDONE,
1117 	CHECKv(_("Show all layers in main window"), show_layers_main),
1118 	EVENT(CHANGE, layer_inputs_changed), UNNAME,
1119 	WEND
1120 };
1121 #undef WBbase
1122 
create_layers_box()1123 void **create_layers_box()
1124 {
1125 	static char *noscript;
1126 	layers_dd tdata;
1127 	void **res;
1128 
1129 	memset(&tdata, 0, sizeof(tdata));
1130 	tdata.nlayer = layer_selected;
1131 	tdata.lnum = layers_total + 1;
1132 	tdata.lname = "";
1133 	layers_box_ = res = run_create_(layers_code, &tdata, sizeof(tdata),
1134 		cmd_mode ? &noscript : NULL);
1135 
1136 	return (res);
1137 }
1138 
1139 static void *layersw_code[] = {
1140 	WPWHEREVER, WINDOW(""), EVENT(CANCEL, delete_layers_window),
1141 	WXYWH("layers", 400, 400),
1142 	REMOUNTv(layers_dock),
1143 	WSHOW
1144 };
1145 
pressed_layers()1146 void pressed_layers()
1147 {
1148 	void **res;
1149 
1150 	if (cmd_mode) return;
1151 	if (layers_window_) return; // Already have it open
1152 	layers_window_ = res = run_create(layersw_code, layersw_code, 0);
1153 
1154 	layers_update_titlebar();
1155 
1156 	cmd_setv(GET_WINDOW(res),
1157 		((layers_dd *)GET_DDATA(layers_box_))->ltb_close, WINDOW_ESC_BTN);
1158 }
1159