1 /* vim:expandtab:ts=2 sw=2:
2 */
3 /* Grafx2 - The Ultimate 256-color bitmap paint program
4
5 Copyright owned by various GrafX2 authors, see COPYRIGHT.txt for details.
6
7 Grafx2 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2
10 of the License.
11
12 Grafx2 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Grafx2; if not, see <http://www.gnu.org/licenses/>
19 */
20 #include <math.h>
21 #include <string.h>
22 #include <stdlib.h>
23
24 #include "const.h"
25 #include "struct.h"
26 #include "global.h"
27 #include "misc.h"
28 #include "osdep.h"
29 #include "engine.h"
30 #include "graph.h"
31 #include "operatio.h"
32 #include "buttons.h"
33 #include "pages.h"
34 #include "errors.h"
35 #include "screen.h"
36 #include "brush.h"
37 #include "windows.h"
38 #include "input.h"
39 #include "special.h"
40 #include "tiles.h"
41 #include "keyboard.h"
42
43 // PI is NOT part of math.h according to C standards...
44 #if defined(__GP2X__) || defined(__VBCC__)
45 #define M_PI 3.14159265358979323846
46 #endif
47
48 /// Time (in SDL ticks) when the next airbrush drawing should be done. Also used
49 /// for discontinuous freehand drawing.
50 dword Airbrush_next_time;
51
52 // Panning needs its own operation storage because it may interrupt another
53 // interrupting operation
54 static enum OPERATIONS Operation_before_pan;
55
Start_operation_stack(word new_operation)56 void Start_operation_stack(word new_operation)
57 {
58 // This part handles things that must be done when exiting an operation.
59 Brush_rotation_center_is_defined=0;
60 switch(Current_operation)
61 {
62 case OPERATION_ROTATE_BRUSH:
63 End_brush_rotation();
64 break;
65
66 default:
67 break;
68 }
69
70 // On mémorise l'opération précédente si on démarre une interruption
71 switch(new_operation)
72 {
73 case OPERATION_MAGNIFY:
74 case OPERATION_COLORPICK:
75 case OPERATION_RMB_COLORPICK:
76 case OPERATION_GRAB_BRUSH:
77 case OPERATION_POLYBRUSH:
78 case OPERATION_STRETCH_BRUSH:
79 Operation_before_interrupt=Current_operation;
80 // On passe à l'operation demandée
81 Current_operation=new_operation;
82 break;
83 case OPERATION_PAN_VIEW:
84 // Use separate operation-before storage for panning
85 Operation_before_pan=Current_operation;
86 // On passe à l'operation demandée
87 Current_operation=new_operation;
88 break;
89 case OPERATION_ROTATE_BRUSH:
90 Begin_brush_rotation();
91 Operation_before_interrupt=Current_operation;
92 // On passe à l'operation demandée
93 Current_operation=new_operation;
94 break;
95 default :
96 // On passe à l'operation demandée
97 Current_operation=new_operation;
98 Operation_before_interrupt=Current_operation;
99 }
100
101 // On spécifie si l'opération autorise le changement de couleur au clavier
102 switch(new_operation)
103 {
104 case OPERATION_CONTINUOUS_DRAW:
105 case OPERATION_DISCONTINUOUS_DRAW:
106 case OPERATION_AIRBRUSH:
107 case OPERATION_CENTERED_LINES:
108 Allow_color_change_during_operation=1;
109 break;
110 default :
111 Allow_color_change_during_operation=0;
112 }
113
114 // Et on passe au curseur qui va avec
115 Cursor_shape=CURSOR_FOR_OPERATION[new_operation];
116 Operation_stack_size=0;
117 }
118
119
Init_start_operation(void)120 void Init_start_operation(void)
121 {
122 Operation_in_magnifier=(Mouse_X>=Main.X_zoom);
123 Smear_start=1;
124 }
125
126
Operation_push(short value)127 void Operation_push(short value)
128 {
129 Operation_stack[++Operation_stack_size]=value;
130 }
131
132
Operation_pop(short * value)133 void Operation_pop(short * value)
134 {
135 *value=Operation_stack[Operation_stack_size--];
136 }
137
138
139 byte Paintbrush_shape_before_operation;
140 byte Paintbrush_hidden_before_scroll;
141
142
143
Distance(short x1,short y1,short x2,short y2)144 short Distance(short x1, short y1, short x2, short y2)
145 {
146 short x2_moins_x1=x2-x1;
147 short y2_minus_y1=y2-y1;
148
149 return Round( sqrt( (x2_moins_x1*x2_moins_x1) + (y2_minus_y1*y2_minus_y1) ) );
150 }
151
152
Display_coords_rel_or_abs(short start_x,short start_y)153 void Display_coords_rel_or_abs(short start_x, short start_y)
154 {
155 char str[6];
156
157 if (Config.Coords_rel)
158 {
159 if (Menu_is_visible)
160 {
161 if (Paintbrush_X>start_x)
162 {
163 Num2str(Paintbrush_X-start_x,str,5);
164 str[0]='+';
165 }
166 else if (Paintbrush_X<start_x)
167 {
168 Num2str(start_x-Paintbrush_X,str,5);
169 str[0]='-';
170 }
171 else
172 strcpy(str,"\xb1 0");
173 Print_in_menu(str,2);
174
175 if (Paintbrush_Y>start_y)
176 {
177 Num2str(Paintbrush_Y-start_y,str,5);
178 str[0]='+';
179 }
180 else if (Paintbrush_Y<start_y)
181 {
182 Num2str(start_y-Paintbrush_Y,str,5);
183 str[0]='-';
184 }
185 else
186 strcpy(str,"\xb1 0");
187 Print_in_menu(str,12);
188 }
189 }
190 else
191 Print_coordinates();
192 }
193
194 //////////////////////////////////////////////////// OPERATION_CONTINUOUS_DRAW
195
Freehand_mode1_1_0(void)196 void Freehand_mode1_1_0(void)
197 // Opération : OPERATION_CONTINUOUS_DRAW
198 // Click Souris: 1
199 // Taille_Pile : 0
200 //
201 // Souris effacée: Oui
202 {
203 Init_start_operation();
204 Backup();
205 Shade_table=Shade_table_left;
206 // On affiche définitivement le pinceau
207 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color);
208 Operation_push(Paintbrush_X);
209 Operation_push(Paintbrush_Y);
210 }
211
212
Freehand_mode1_1_2(void)213 void Freehand_mode1_1_2(void)
214 // Opération : OPERATION_CONTINUOUS_DRAW
215 // Click Souris: 1
216 // Taille_Pile : 2
217 //
218 // Souris effacée: Non
219 {
220 short start_x;
221 short start_y;
222
223 Operation_pop(&start_y);
224 Operation_pop(&start_x);
225
226 if ( (start_y!=Paintbrush_Y) || (start_x!=Paintbrush_X) )
227 {
228 Hide_cursor();
229 Print_coordinates();
230 Draw_line_permanent(start_x,start_y,Paintbrush_X,Paintbrush_Y,Fore_color);
231 Display_cursor();
232 }
233
234 Operation_push(Paintbrush_X);
235 Operation_push(Paintbrush_Y);
236 }
237
238
Freehand_mode12_0_2(void)239 void Freehand_mode12_0_2(void)
240 // Opération : OPERATION_DESSIN_[DIS]CONTINU
241 // Click Souris: 0
242 // Taille_Pile : 2
243 //
244 // Souris effacée: Non
245 {
246 Operation_stack_size=0;
247 End_of_modification();
248 }
249
250
Freehand_mode1_2_0(void)251 void Freehand_mode1_2_0(void)
252 // Opération : OPERATION_CONTINUOUS_DRAW
253 // Click Souris: 2
254 // Taille_Pile : 0
255 //
256 // Souris effacée: Oui
257 {
258 if (Rightclick_colorpick(0))
259 return;
260
261 Init_start_operation();
262 Backup();
263 Shade_table=Shade_table_right;
264 // On affiche définitivement le pinceau
265 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color);
266 Operation_push(Paintbrush_X);
267 Operation_push(Paintbrush_Y);
268 }
269
270
Freehand_mode1_2_2(void)271 void Freehand_mode1_2_2(void)
272 // Opération : OPERATION_CONTINUOUS_DRAW
273 // Click Souris: 2
274 // Taille_Pile : 2
275 //
276 // Souris effacée: Non
277 {
278 short start_x;
279 short start_y;
280
281 Operation_pop(&start_y);
282 Operation_pop(&start_x);
283
284 if ( (start_y!=Paintbrush_Y) || (start_x!=Paintbrush_X) )
285 {
286 Print_coordinates();
287 Hide_cursor();
288 Draw_line_permanent(start_x,start_y,Paintbrush_X,Paintbrush_Y,Back_color);
289 Display_cursor();
290 }
291
292 Operation_push(Paintbrush_X);
293 Operation_push(Paintbrush_Y);
294 }
295
296
297 ///////////////////////////////////////////////// OPERATION_DISCONTINUOUS_DRAW
298
Freehand_mode2_1_0(void)299 void Freehand_mode2_1_0(void)
300 // Opération : OPERATION_DISCONTINUOUS_DRAW
301 // Click Souris: 1
302 // Taille_Pile : 0
303 //
304 // Souris effacée: Oui
305 {
306 Init_start_operation();
307 Backup();
308 Shade_table=Shade_table_left;
309 // On affiche définitivement le pinceau
310 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color);
311 Operation_push(Paintbrush_X);
312 Operation_push(Paintbrush_Y);
313 Print_coordinates();
314 Airbrush_next_time = GFX2_GetTicks() + Airbrush_delay*10;
315 }
316
317
Freehand_mode2_1_2(void)318 void Freehand_mode2_1_2(void)
319 // Opération : OPERATION_DISCONTINUOUS_DRAW
320 // Click Souris: 1
321 // Taille_Pile : 2
322 //
323 // Souris effacée: Non
324 {
325 short start_x;
326 short start_y;
327
328 Operation_pop(&start_y);
329 Operation_pop(&start_x);
330
331 if ( (start_x!=Paintbrush_X) || (start_y!=Paintbrush_Y) )
332 {
333 Print_coordinates();
334 if (GFX2_GetTicks()>Airbrush_next_time)
335 {
336 Airbrush_next_time+=Airbrush_delay*10;
337 Hide_cursor();
338 // On affiche définitivement le pinceau
339 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color);
340 Display_cursor();
341 }
342 }
343
344 Operation_push(Paintbrush_X);
345 Operation_push(Paintbrush_Y);
346 }
347
348 // ----------
349
Freehand_mode2_2_0(void)350 void Freehand_mode2_2_0(void)
351 // Opération : OPERATION_DISCONTINUOUS_DRAW
352 // Click Souris: 2
353 // Taille_Pile : 0
354 //
355 // Souris effacée: Oui
356 {
357 if (Rightclick_colorpick(0))
358 return;
359
360 Init_start_operation();
361 Backup();
362 Shade_table=Shade_table_right;
363 Operation_push(Paintbrush_X);
364 Operation_push(Paintbrush_Y);
365 Print_coordinates();
366 Airbrush_next_time = GFX2_GetTicks() + Airbrush_delay*10;
367 // On affiche définitivement le pinceau
368 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color);
369 }
370
371
Freehand_mode2_2_2(void)372 void Freehand_mode2_2_2(void)
373 // Opération : OPERATION_DISCONTINUOUS_DRAW
374 // Click Souris: 2
375 // Taille_Pile : 2
376 //
377 // Souris effacée: Non
378 {
379 short start_x;
380 short start_y;
381
382 Operation_pop(&start_y);
383 Operation_pop(&start_x);
384
385 if ( (start_x!=Paintbrush_X) || (start_y!=Paintbrush_Y) )
386 {
387 Print_coordinates();
388 if (GFX2_GetTicks()>Airbrush_next_time)
389 {
390 Airbrush_next_time+=Airbrush_delay*10;
391 Hide_cursor();
392 // On affiche définitivement le pinceau
393 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color);
394 Display_cursor();
395 }
396 }
397
398 Operation_push(Paintbrush_X);
399 Operation_push(Paintbrush_Y);
400 }
401
402
403 ////////////////////////////////////////////////////// OPERATION_POINT_DRAW
404
Freehand_mode3_1_0(void)405 void Freehand_mode3_1_0(void)
406 // Opération : OPERATION_POINT_DRAW
407 // Click Souris: 1
408 // Taille_Pile : 0
409 //
410 // Souris effacée: Oui
411 {
412 Init_start_operation();
413 Backup();
414 Shade_table=Shade_table_left;
415 // On affiche définitivement le pinceau
416 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color);
417 Operation_push(0); // On change simplement l'état de la pile...
418 }
419
420
Freehand_Mode3_2_0(void)421 void Freehand_Mode3_2_0(void)
422 // Opération : OPERATION_POINT_DRAW
423 // Click Souris: 2
424 // Taille_Pile : 0
425 //
426 // Souris effacée: Oui
427 {
428 if (Rightclick_colorpick(0))
429 return;
430
431 Init_start_operation();
432 Backup();
433 Shade_table=Shade_table_right;
434 // On affiche définitivement le pinceau
435 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color);
436 Operation_push(0); // On change simplement l'état de la pile...
437 }
438
439
Freehand_mode3_0_1(void)440 void Freehand_mode3_0_1(void)
441 // Opération : OPERATION_POINT_DRAW
442 // Click Souris: 0
443 // Taille_Pile : 1
444 //
445 // Souris effacée: Non
446 {
447 End_of_modification();
448 Operation_stack_size--;
449 }
450
451
452 ///////////////////////////////////////////////////////////// OPERATION_LINE
453
Line_12_0(void)454 void Line_12_0(void)
455 // Opération : OPERATION_LINE
456 // Click Souris: 1 ou 2
457 // Taille_Pile : 0
458 //
459 // Souris effacée: Oui
460
461 // Début du tracé d'une ligne (premier clic)
462 {
463 if (Rightclick_colorpick(0))
464 return;
465
466 Init_start_operation();
467 Backup();
468 Paintbrush_shape_before_operation=Paintbrush_shape;
469 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
470
471 if (Mouse_K==LEFT_SIDE)
472 {
473 Shade_table=Shade_table_left;
474 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Fore_color);
475 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
476 Operation_push(Fore_color);
477 }
478 else
479 {
480 Shade_table=Shade_table_right;
481 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Back_color);
482 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
483 Operation_push(Back_color);
484 }
485
486 if ((Config.Coords_rel) && (Menu_is_visible))
487 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
488
489 Operation_push(Paintbrush_X);
490 Operation_push(Paintbrush_Y);
491 Operation_push(Paintbrush_X);
492 Operation_push(Paintbrush_Y);
493 }
494
495
Line_12_5(void)496 void Line_12_5(void)
497 // Opération : OPERATION_LINE
498 // Click Souris: 1
499 // Taille_Pile : 5
500 //
501 // Souris effacée: Non
502
503 // Poursuite du tracé d'une ligne (déplacement de la souris en gardant le
504 // curseur appuyé)
505 {
506 short start_x;
507 short start_y;
508 short end_x;
509 short end_y;
510
511 short cursor_x;
512 short cursor_y;
513
514 Operation_pop(&end_y);
515 Operation_pop(&end_x);
516 Operation_pop(&start_y);
517 Operation_pop(&start_x);
518
519 cursor_x = Paintbrush_X;
520 cursor_y = Paintbrush_Y;
521
522 // On corrige les coordonnées de la ligne si la touche shift est appuyée...
523 if(Get_Key_modifiers() & GFX2_MOD_SHIFT)
524 Clamp_coordinates_regular_angle(start_x,start_y,&cursor_x,&cursor_y);
525
526 // On vient de bouger
527 if ((cursor_x!=end_x) || (cursor_y!=end_y))
528 {
529 Hide_cursor();
530
531 Display_coords_rel_or_abs(start_x,start_y);
532
533 Hide_line_preview(start_x,start_y,end_x,end_y);
534 if (Mouse_K==LEFT_SIDE)
535 {
536 Pixel_figure_preview (start_x,start_y,Fore_color);
537 Draw_line_preview (start_x,start_y,cursor_x,cursor_y,Fore_color);
538 }
539 else
540 {
541 Pixel_figure_preview (start_x,start_y,Back_color);
542 Draw_line_preview (start_x,start_y,cursor_x,cursor_y,Back_color);
543 }
544
545 Operation_push(start_x);
546 Operation_push(start_y);
547 Operation_push(cursor_x);
548 Operation_push(cursor_y);
549
550 Display_cursor();
551 }
552 else
553 {
554 Operation_push(start_x);
555 Operation_push(start_y);
556 Operation_push(end_x);
557 Operation_push(end_y);
558 }
559 }
560
561
Line_0_5(void)562 void Line_0_5(void)
563 // Opération : OPERATION_LINE
564 // Click Souris: 0
565 // Taille_Pile : 5
566 //
567 // Souris effacée: Oui
568
569 // End du tracé d'une ligne (relachage du bouton)
570 {
571 short start_x;
572 short start_y;
573 short end_x;
574 short end_y;
575 short color;
576
577 Operation_pop(&end_y);
578 Operation_pop(&end_x);
579 Operation_pop(&start_y);
580 Operation_pop(&start_x);
581 Operation_pop(&color);
582
583 Paintbrush_shape=Paintbrush_shape_before_operation;
584
585 Pixel_figure_preview_auto (start_x,start_y);
586 Hide_line_preview (start_x,start_y,end_x,end_y);
587 Draw_paintbrush (start_x,start_y,color);
588 Draw_line_permanent(start_x,start_y,end_x,end_y,color);
589
590 End_of_modification();
591 if ( (Config.Coords_rel) && (Menu_is_visible) )
592 {
593 Print_in_menu("X: Y: ",0);
594 Print_coordinates();
595 }
596 }
597
598
599 /////////////////////////////////////////////////////////// OPERATION_K_LINE
600
601
K_line_12_0(void)602 void K_line_12_0(void)
603 // Opération : OPERATION_K_LINE
604 // Click Souris: 1 ou 2
605 // Taille_Pile : 0
606 //
607 // Souris effacée: Oui
608 {
609 byte color;
610
611 if (Rightclick_colorpick(0))
612 return;
613
614 Init_start_operation();
615 Backup();
616 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
617 Paintbrush_shape_before_operation=Paintbrush_shape;
618 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
619
620 color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
621
622 // On place temporairement le début de la ligne qui ne s'afficherait pas sinon
623 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
624
625 if ((Config.Coords_rel) && (Menu_is_visible))
626 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
627
628 Operation_push(Mouse_K | 0x80);
629 Operation_push(color);
630 Operation_push(Paintbrush_X);
631 Operation_push(Paintbrush_Y);
632 Operation_push(Paintbrush_X);
633 Operation_push(Paintbrush_Y);
634 // Taille de pile 6 : phase d'appui, non interruptible
635 }
636
637
K_line_12_6(void)638 void K_line_12_6(void)
639 // Opération : OPERATION_K_LINE
640 // Click Souris: 1 ou 2 | 0
641 // Taille_Pile : 6 | 7
642 //
643 // Souris effacée: Non
644 {
645 short start_x;
646 short start_y;
647 short end_x;
648 short end_y;
649 short color;
650
651 Operation_pop(&end_y);
652 Operation_pop(&end_x);
653
654 if ((Paintbrush_X!=end_x) || (Paintbrush_Y!=end_y))
655 {
656 Hide_cursor();
657 Operation_pop(&start_y);
658 Operation_pop(&start_x);
659 Operation_pop(&color);
660
661 Display_coords_rel_or_abs(start_x,start_y);
662
663 Hide_line_preview(start_x,start_y,end_x,end_y);
664 Pixel_figure_preview (start_x,start_y,color);
665 Draw_line_preview (start_x,start_y,Paintbrush_X,Paintbrush_Y,color);
666
667 Operation_push(color);
668 Operation_push(start_x);
669 Operation_push(start_y);
670 Display_cursor();
671 }
672
673 Operation_push(Paintbrush_X);
674 Operation_push(Paintbrush_Y);
675 }
676
677
K_line_0_6(void)678 void K_line_0_6(void)
679 // Opération : OPERATION_K_LINE
680 // Click Souris: 0
681 // Taille_Pile : 6
682 //
683 // Souris effacée: Oui
684 {
685 short start_x;
686 short start_y;
687 short end_x;
688 short end_y;
689 short color;
690 short direction;
691
692 Operation_pop(&end_y);
693 Operation_pop(&end_x);
694 Operation_pop(&start_y);
695 Operation_pop(&start_x);
696 Operation_pop(&color);
697 Operation_pop(&direction);
698
699 if ((Config.Coords_rel) && (Menu_is_visible))
700 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
701
702 Pixel_figure_preview_auto (start_x,start_y);
703 Hide_line_preview (start_x,start_y,end_x,end_y);
704 /* Doesn't work if fast moving
705 Pixel_figure_preview_xor (start_x,start_y, 0);
706 Draw_line_preview_xor (start_x,start_y,end_x,end_y,0);
707 */
708 Paintbrush_shape=Paintbrush_shape_before_operation;
709 if (direction & 0x80)
710 {
711 Draw_paintbrush(start_x,start_y,color);
712 direction=(direction & 0x7F);
713 }
714 Draw_line_permanent(start_x,start_y,Paintbrush_X,Paintbrush_Y,color);
715 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
716
717 Operation_push(direction);
718 Operation_push(direction); // Valeur bidon servant de nouvel état de pile
719 Operation_push(color);
720 Operation_push(Paintbrush_X);
721 Operation_push(Paintbrush_Y);
722 Operation_push(Paintbrush_X);
723 Operation_push(Paintbrush_Y);
724 // Taille de pile 7 : phase de "repos", interruptible (comme Elliot Ness :))
725 }
726
727
K_line_12_7(void)728 void K_line_12_7(void)
729 // Opération : OPERATION_K_LINE
730 // Click Souris: 1 ou 2
731 // Taille_Pile : 7
732 //
733 // Souris effacée: Oui
734 {
735 short start_x;
736 short start_y;
737 short end_x;
738 short end_y;
739 short color;
740 short direction;
741
742 Operation_pop(&end_y);
743 Operation_pop(&end_x);
744 Operation_pop(&start_y);
745 Operation_pop(&start_x);
746 Operation_pop(&color);
747 Operation_pop(&direction);
748 Operation_pop(&direction);
749
750 if (direction==Mouse_K)
751 {
752 Operation_push(direction);
753 Operation_push(color);
754 Operation_push(start_x);
755 Operation_push(start_y);
756 Operation_push(end_x);
757 Operation_push(end_y);
758 // Taille de pile 6 : phase d'appui, non interruptible
759 }
760 else
761 {
762 // La série de ligne est terminée, il faut donc effacer la dernière
763 // preview de ligne
764 Pixel_figure_preview_auto (start_x,start_y);
765 Hide_line_preview (start_x,start_y,end_x,end_y);
766
767 Display_cursor();
768 Wait_end_of_click();
769 Hide_cursor();
770 Paintbrush_shape=Paintbrush_shape_before_operation;
771
772 End_of_modification();
773 if ( (Config.Coords_rel) && (Menu_is_visible) )
774 {
775 Print_in_menu("X: Y: ",0);
776 Print_coordinates();
777 }
778 }
779 }
780
781 /////////////////////////////////////////////////// OPERATION_RECTANGLE_?????
782
Rectangle_12_0(void)783 void Rectangle_12_0(void)
784 // Opération : OPERATION_EMPTY_RECTANGLE / OPERATION_FILLED_RECTANGLE
785 // Click Souris: 1 ou 2
786 // Taille_Pile : 0
787 //
788 // Souris effacée: Oui
789 {
790 if (Rightclick_colorpick(0))
791 return;
792
793 Init_start_operation();
794
795 if ((Config.Coords_rel) && (Menu_is_visible))
796 Print_in_menu("\035: 1 \022: 1",0);
797 // On laisse une trace du curseur à l'écran
798 Display_cursor();
799
800 if (Mouse_K==LEFT_SIDE)
801 {
802 Shade_table=Shade_table_left;
803 Operation_push(Fore_color);
804 }
805 else
806 {
807 Shade_table=Shade_table_right;
808 Operation_push(Back_color);
809 }
810
811 Operation_push(Paintbrush_X);
812 Operation_push(Paintbrush_Y);
813 Operation_push(Paintbrush_X);
814 Operation_push(Paintbrush_Y);
815 }
816
817
Rectangle_12_5(void)818 void Rectangle_12_5(void)
819 // Opération : OPERATION_EMPTY_RECTANGLE / OPERATION_FILLED_RECTANGLE
820 // Click Souris: 1 ou 2
821 // Taille_Pile : 5
822 //
823 // Souris effacée: Non
824 {
825 short start_x;
826 short start_y;
827 short old_x;
828 short old_y;
829 char str[5];
830
831 Operation_pop(&old_y);
832 Operation_pop(&old_x);
833
834 if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y))
835 {
836 Operation_pop(&start_y);
837 Operation_pop(&start_x);
838
839 if ((Config.Coords_rel) && (Menu_is_visible))
840 {
841 Num2str(((start_x<Paintbrush_X)?Paintbrush_X-start_x:start_x-Paintbrush_X)+1,str,4);
842 Print_in_menu(str,2);
843 Num2str(((start_y<Paintbrush_Y)?Paintbrush_Y-start_y:start_y-Paintbrush_Y)+1,str,4);
844 Print_in_menu(str,11);
845 }
846 else
847 Print_coordinates();
848
849 Operation_push(start_x);
850 Operation_push(start_y);
851 }
852
853 Operation_push(Paintbrush_X);
854 Operation_push(Paintbrush_Y);
855 }
856
857
Empty_rectangle_0_5(void)858 void Empty_rectangle_0_5(void)
859 // Opération : OPERATION_EMPTY_RECTANGLE
860 // Click Souris: 0
861 // Taille_Pile : 5
862 //
863 // Souris effacée: Oui
864 {
865 short old_paintbrush_x;
866 short old_paintbrush_y;
867 short color;
868
869 // On mémorise la position courante du pinceau:
870
871 old_paintbrush_x=Paintbrush_X;
872 old_paintbrush_y=Paintbrush_Y;
873
874 // On lit l'ancienne position du pinceau:
875
876 Operation_pop(&Paintbrush_Y);
877 Operation_pop(&Paintbrush_X);
878 Operation_pop(&Paintbrush_Y);
879 Operation_pop(&Paintbrush_X);
880
881 // On va devoir effacer l'ancien curseur qu'on a laissé trainer:
882 Hide_cursor();
883
884 // On lit la couleur du rectangle:
885 Operation_pop(&color);
886
887 // On fait un petit backup de l'image:
888 Backup();
889
890 // Et on trace le rectangle:
891 Draw_empty_rectangle(Paintbrush_X,Paintbrush_Y,old_paintbrush_x,old_paintbrush_y,color);
892
893 // Enfin, on rétablit la position du pinceau:
894 Paintbrush_X=old_paintbrush_x;
895 Paintbrush_Y=old_paintbrush_y;
896
897 End_of_modification();
898
899 if ((Config.Coords_rel) && (Menu_is_visible))
900 Print_in_menu("X: Y:",0);
901 Print_coordinates();
902 }
903
904
Filled_rectangle_0_5(void)905 void Filled_rectangle_0_5(void)
906 // Opération : OPERATION_FILLED_RECTANGLE
907 // Click Souris: 0
908 // Taille_Pile : 5
909 //
910 // Souris effacée: Oui
911 {
912 short old_paintbrush_x;
913 short old_paintbrush_y;
914 short color;
915
916 // On mémorise la position courante du pinceau:
917
918 old_paintbrush_x=Paintbrush_X;
919 old_paintbrush_y=Paintbrush_Y;
920
921 // On lit l'ancienne position du pinceau:
922
923 Operation_pop(&Paintbrush_Y);
924 Operation_pop(&Paintbrush_X);
925 Operation_pop(&Paintbrush_Y);
926 Operation_pop(&Paintbrush_X);
927
928 // On va devoir effacer l'ancien curseur qu'on a laissé trainer:
929 Hide_cursor();
930
931 // On lit la couleur du rectangle:
932 Operation_pop(&color);
933
934 // On fait un petit backup de l'image:
935 Backup();
936
937 // Et on trace le rectangle:
938 Draw_filled_rectangle(Paintbrush_X,Paintbrush_Y,old_paintbrush_x,old_paintbrush_y,color);
939
940 // Enfin, on rétablit la position du pinceau:
941 Paintbrush_X=old_paintbrush_x;
942 Paintbrush_Y=old_paintbrush_y;
943
944 End_of_modification();
945 if ( (Config.Coords_rel) && (Menu_is_visible) )
946 {
947 Print_in_menu("X: Y:",0);
948 Print_coordinates();
949 }
950 }
951
952
953 ////////////////////////////////////////////////////// OPERATION_CERCLE_?????
954
955
Circle_12_0(void)956 void Circle_12_0(void)
957 //
958 // Opération : OPERATION_EMPTY_CIRCLE / OPERATION_FILLED_CIRCLE
959 // Click Souris: 1 ou 2
960 // Taille_Pile : 0
961 //
962 // Souris effacée: Oui
963 {
964 if (Rightclick_colorpick(0))
965 return;
966
967 Init_start_operation();
968 Backup();
969
970 Paintbrush_shape_before_operation=Paintbrush_shape;
971 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
972
973 if (Mouse_K==LEFT_SIDE)
974 {
975 Shade_table=Shade_table_left;
976 Operation_push(Fore_color);
977 }
978 else
979 {
980 Shade_table=Shade_table_right;
981 Operation_push(Back_color);
982 }
983
984 if ((Config.Coords_rel) && (Menu_is_visible))
985 Print_in_menu("Radius: 0 ",0);
986
987 Operation_push(Paintbrush_X);
988 Operation_push(Paintbrush_Y);
989 Operation_push(Paintbrush_X);
990 Operation_push(Paintbrush_Y);
991 }
992
993
Circle_12_5(void)994 void Circle_12_5(void)
995 //
996 // Opération : OPERATION_EMPTY_CIRCLE / OPERATION_FILLED_CIRCLE
997 // Click Souris: 1 ou 2
998 // Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
999 //
1000 // Souris effacée: Non
1001 //
1002 {
1003 short tangent_x;
1004 short tangent_y;
1005 short center_x;
1006 short center_y;
1007 short color;
1008 long limit;
1009 char str[5];
1010
1011 Operation_pop(&tangent_y);
1012 Operation_pop(&tangent_x);
1013 Operation_pop(¢er_y);
1014 Operation_pop(¢er_x);
1015 Operation_pop(&color);
1016
1017 if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) )
1018 {
1019 Hide_cursor();
1020 Cursor_shape=CURSOR_SHAPE_TARGET;
1021 if ((Config.Coords_rel) && (Menu_is_visible))
1022 {
1023 Num2str(Distance(center_x,center_y,Paintbrush_X,Paintbrush_Y),str,4);
1024 Print_in_menu(str,7);
1025 }
1026 else
1027 Print_coordinates();
1028
1029 limit=((tangent_x-center_x)*(tangent_x-center_x))+
1030 ((tangent_y-center_y)*(tangent_y-center_y));
1031 Hide_empty_circle_preview(center_x,center_y,limit);
1032
1033 limit=((Paintbrush_X-center_x)*(Paintbrush_X-center_x))+
1034 ((Paintbrush_Y-center_y)*(Paintbrush_Y-center_y));
1035 Draw_empty_circle_preview(center_x,center_y,limit,color);
1036
1037 Display_cursor();
1038 }
1039
1040 Operation_push(color);
1041 Operation_push(center_x);
1042 Operation_push(center_y);
1043 Operation_push(Paintbrush_X);
1044 Operation_push(Paintbrush_Y);
1045 }
1046
1047
Empty_circle_0_5(void)1048 void Empty_circle_0_5(void)
1049 //
1050 // Opération : OPERATION_EMPTY_CIRCLE
1051 // Click Souris: 0
1052 // Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
1053 //
1054 // Souris effacée: Oui
1055 //
1056 {
1057 short tangent_x;
1058 short tangent_y;
1059 short center_x;
1060 short center_y;
1061 short color;
1062 long limit;
1063
1064 Operation_pop(&tangent_y);
1065 Operation_pop(&tangent_x);
1066 Operation_pop(¢er_y);
1067 Operation_pop(¢er_x);
1068 Operation_pop(&color);
1069
1070 limit=((tangent_x-center_x)*(tangent_x-center_x))+
1071 ((tangent_y-center_y)*(tangent_y-center_y));
1072 Hide_empty_circle_preview(center_x,center_y,limit);
1073
1074 Paintbrush_shape=Paintbrush_shape_before_operation;
1075
1076 Draw_empty_circle_permanent(center_x,center_y,limit,color);
1077
1078 End_of_modification();
1079
1080 if ( (Config.Coords_rel) && (Menu_is_visible) )
1081 {
1082 Print_in_menu("X: Y:",0);
1083 Print_coordinates();
1084 }
1085 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
1086 }
1087
1088
Filled_circle_0_5(void)1089 void Filled_circle_0_5(void)
1090 //
1091 // Opération : OPERATION_FILLED_CIRCLE
1092 // Click Souris: 0
1093 // Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
1094 //
1095 // Souris effacée: Oui
1096 //
1097 {
1098 short tangent_x;
1099 short tangent_y;
1100 short center_x;
1101 short center_y;
1102 short color;
1103 long limit;
1104
1105 Operation_pop(&tangent_y);
1106 Operation_pop(&tangent_x);
1107 Operation_pop(¢er_y);
1108 Operation_pop(¢er_x);
1109 Operation_pop(&color);
1110
1111 limit=((tangent_x-center_x)*(tangent_x-center_x))+
1112 ((tangent_y-center_y)*(tangent_y-center_y));
1113 Hide_empty_circle_preview(center_x,center_y,limit);
1114
1115 Paintbrush_shape=Paintbrush_shape_before_operation;
1116
1117 Draw_filled_circle(center_x,center_y,limit,color);
1118
1119 End_of_modification();
1120 if ( (Config.Coords_rel) && (Menu_is_visible) )
1121 {
1122 Print_in_menu("X: Y:",0);
1123 Print_coordinates();
1124 }
1125 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
1126 }
1127
1128
1129 ///////////////////////////////////////////////////// OPERATION_ELLIPSE_?????
1130
1131
Ellipse_12_0(void)1132 void Ellipse_12_0(void)
1133 //
1134 // Opération : OPERATION_EMPTY_ELLIPSE / OPERATION_FILLED_ELLIPSE
1135 // Click Souris: 1 ou 2
1136 // Taille_Pile : 0
1137 //
1138 // Souris effacée: Oui
1139 {
1140 if (Rightclick_colorpick(0))
1141 return;
1142
1143 Init_start_operation();
1144 Backup();
1145
1146 Paintbrush_shape_before_operation=Paintbrush_shape;
1147 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
1148
1149 if (Mouse_K==LEFT_SIDE)
1150 {
1151 Shade_table=Shade_table_left;
1152 Operation_push(Fore_color);
1153 }
1154 else
1155 {
1156 Shade_table=Shade_table_right;
1157 Operation_push(Back_color);
1158 }
1159
1160 if ((Config.Coords_rel) && (Menu_is_visible))
1161 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
1162
1163 Operation_push(Paintbrush_X);
1164 Operation_push(Paintbrush_Y);
1165 Operation_push(Paintbrush_X);
1166 Operation_push(Paintbrush_Y);
1167 }
1168
1169
Ellipse_12_5(void)1170 void Ellipse_12_5(void)
1171 //
1172 // Opération : OPERATION_EMPTY_ELLIPSE / OPERATION_FILLED_ELLIPSE
1173 // Click Souris: 1 ou 2
1174 // Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
1175 //
1176 // Souris effacée: Non
1177 //
1178 {
1179 short tangent_x;
1180 short tangent_y;
1181 short center_x;
1182 short center_y;
1183 short color;
1184 short horizontal_radius;
1185 short vertical_radius;
1186
1187 Operation_pop(&tangent_y);
1188 Operation_pop(&tangent_x);
1189 Operation_pop(¢er_y);
1190 Operation_pop(¢er_x);
1191 Operation_pop(&color);
1192
1193
1194 if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) )
1195 {
1196 Hide_cursor();
1197 Display_coords_rel_or_abs(center_x,center_y);
1198
1199 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
1200 {
1201 Cursor_shape=CURSOR_SHAPE_TARGET;
1202 horizontal_radius=(tangent_x>center_x)?tangent_x-center_x
1203 :center_x-tangent_x;
1204 vertical_radius =(tangent_y>center_y)?tangent_y-center_y
1205 :center_y-tangent_y;
1206 Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius);
1207
1208 horizontal_radius=(Paintbrush_X>center_x)?Paintbrush_X-center_x
1209 :center_x-Paintbrush_X;
1210 vertical_radius =(Paintbrush_Y>center_y)?Paintbrush_Y-center_y
1211 :center_y-Paintbrush_Y;
1212 Draw_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius,color);
1213 }
1214 else
1215 {
1216 Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y);
1217 Draw_empty_inscribed_ellipse_preview(center_x,center_y,Paintbrush_X,Paintbrush_Y,color);
1218 }
1219
1220 Display_cursor();
1221 }
1222
1223 Operation_push(color);
1224 Operation_push(center_x);
1225 Operation_push(center_y);
1226 Operation_push(Paintbrush_X);
1227 Operation_push(Paintbrush_Y);
1228 }
1229
1230
Empty_ellipse_0_5(void)1231 void Empty_ellipse_0_5(void)
1232 //
1233 // Opération : OPERATION_EMPTY_ELLIPSE
1234 // Click Souris: 0
1235 // Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
1236 //
1237 // Souris effacée: Oui
1238 //
1239 {
1240 short tangent_x;
1241 short tangent_y;
1242 short center_x;
1243 short center_y;
1244 short color;
1245 short horizontal_radius;
1246 short vertical_radius;
1247
1248 Operation_pop(&tangent_y);
1249 Operation_pop(&tangent_x);
1250 Operation_pop(¢er_y);
1251 Operation_pop(¢er_x);
1252 Operation_pop(&color);
1253
1254 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
1255 {
1256 horizontal_radius=(tangent_x>center_x)?tangent_x-center_x
1257 :center_x-tangent_x;
1258 vertical_radius =(tangent_y>center_y)?tangent_y-center_y
1259 :center_y-tangent_y;
1260 Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius);
1261 Paintbrush_shape=Paintbrush_shape_before_operation;
1262 Draw_empty_ellipse_permanent(center_x,center_y,horizontal_radius,vertical_radius,color);
1263 }
1264 else
1265 {
1266 Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y);
1267 Paintbrush_shape=Paintbrush_shape_before_operation;
1268 Draw_empty_inscribed_ellipse_permanent(center_x,center_y,tangent_x,tangent_y,color);
1269 }
1270
1271 End_of_modification();
1272
1273 if ( (Config.Coords_rel) && (Menu_is_visible) )
1274 {
1275 Print_in_menu("X: Y: ",0);
1276 Print_coordinates();
1277 }
1278 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
1279 }
1280
1281
Filled_ellipse_0_5(void)1282 void Filled_ellipse_0_5(void)
1283 //
1284 // Opération : OPERATION_FILLED_ELLIPSE
1285 // Click Souris: 0
1286 // Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
1287 //
1288 // Souris effacée: Oui
1289 //
1290 {
1291 short tangent_x;
1292 short tangent_y;
1293 short center_x;
1294 short center_y;
1295 short color;
1296 short horizontal_radius;
1297 short vertical_radius;
1298
1299 Operation_pop(&tangent_y);
1300 Operation_pop(&tangent_x);
1301 Operation_pop(¢er_y);
1302 Operation_pop(¢er_x);
1303 Operation_pop(&color);
1304
1305 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
1306 {
1307 horizontal_radius=(tangent_x>center_x)?tangent_x-center_x
1308 :center_x-tangent_x;
1309 vertical_radius =(tangent_y>center_y)?tangent_y-center_y
1310 :center_y-tangent_y;
1311 Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius);
1312 Paintbrush_shape=Paintbrush_shape_before_operation;
1313 Draw_filled_ellipse(center_x,center_y,horizontal_radius,vertical_radius,color);
1314 }
1315 else
1316 {
1317 Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y);
1318 Paintbrush_shape=Paintbrush_shape_before_operation;
1319 Draw_filled_inscribed_ellipse(center_x,center_y,tangent_x,tangent_y,color);
1320 }
1321
1322 End_of_modification();
1323 if ( (Config.Coords_rel) && (Menu_is_visible) )
1324 {
1325 Print_in_menu("X: Y: ",0);
1326 Print_coordinates();
1327 }
1328 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
1329 }
1330
1331
1332 ////////////////////////////////////////////////////////////// OPERATION_FILL
1333
1334
Fill_1_0(void)1335 void Fill_1_0(void)
1336 //
1337 // Opération : OPERATION_FILL
1338 // Click Souris: 1
1339 // Taille_Pile : 0
1340 //
1341 // Souris effacée: Oui
1342 //
1343 {
1344 Hide_cursor();
1345 // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas
1346 // le Fill, et on se fout de savoir si on est dans la partie gauche ou
1347 // droite de la loupe.
1348 // On ne s'occupe pas de faire un Backup: c'est "Fill_general" qui s'en charge.
1349 Shade_table=Shade_table_left;
1350 Fill_general(Fore_color);
1351 Display_cursor();
1352 End_of_modification();
1353 Wait_end_of_click();
1354 }
1355
1356
Fill_2_0(void)1357 void Fill_2_0(void)
1358 //
1359 // Opération : OPERATION_FILL
1360 // Click Souris: 2
1361 // Taille_Pile : 0
1362 //
1363 // Souris effacée: Non
1364 //
1365 {
1366 if (Rightclick_colorpick(1))
1367 return;
1368
1369 Hide_cursor();
1370 // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas
1371 // le Fill, et on se fout de savoir si on est dans la partie gauche ou
1372 // droite de la loupe.
1373 // On ne s'occupe pas de faire un Backup: c'est "Fill_general" qui s'en charge.
1374 Shade_table=Shade_table_right;
1375 Fill_general(Back_color);
1376 Display_cursor();
1377 End_of_modification();
1378 Wait_end_of_click();
1379 }
1380
1381
1382 ///////////////////////////////////////////////////////// OPERATION_REPLACE
1383
1384
Replace_1_0(void)1385 void Replace_1_0(void)
1386 //
1387 // Opération : OPERATION_REPLACE
1388 // Click Souris: 1
1389 // Taille_Pile : 0
1390 //
1391 // Souris effacée: Non
1392 //
1393 {
1394 Hide_cursor();
1395 Init_start_operation();
1396 Backup();
1397 // Shade_table=Shade_table_left;
1398 Replace(Fore_color);
1399 End_of_modification();
1400 Display_all_screen();
1401 Display_cursor();
1402 Wait_end_of_click();
1403 }
1404
1405
Replace_2_0(void)1406 void Replace_2_0(void)
1407 //
1408 // Opération : OPERATION_REPLACE
1409 // Click Souris: 2
1410 // Taille_Pile : 0
1411 //
1412 // Souris effacée: Non
1413 //
1414 {
1415 if (Rightclick_colorpick(1))
1416 return;
1417
1418 Hide_cursor();
1419 Init_start_operation();
1420 Backup();
1421 // Shade_table=Shade_table_right;
1422 Replace(Back_color);
1423 End_of_modification();
1424 Display_all_screen();
1425 Display_cursor();
1426 Wait_end_of_click();
1427 }
1428
1429
1430 /////////////////////////////////////////////////// OPERATION_4_POINTS_CURVE
1431
1432
Draw_curve_cross(short x_pos,short y_pos)1433 void Draw_curve_cross(short x_pos, short y_pos)
1434 {
1435 short start_x,end_x;
1436 short start_y,end_y;
1437 short i,temp;
1438 //byte temp2;
1439
1440 if (x_pos>=Limit_left+3)
1441 start_x=0;
1442 else
1443 start_x=3-(x_pos-Limit_left);
1444
1445 if (y_pos>=Limit_top+3)
1446 start_y=0;
1447 else
1448 start_y=3-(y_pos-Limit_top);
1449
1450 if (x_pos<=Limit_visible_right-3)
1451 end_x=6;
1452 else
1453 end_x=3+(Limit_visible_right-x_pos);
1454
1455 if (y_pos<=Limit_visible_bottom-3)
1456 end_y=6;
1457 else
1458 end_y=3+(Limit_visible_bottom-y_pos);
1459
1460 if (start_x<=end_x && start_y<=end_y)
1461 {
1462 for (i=start_x; i<=end_x; i++)
1463 {
1464 temp=x_pos+i-3;
1465 Pixel_preview(temp,y_pos,xor_lut[Read_pixel(temp -Main.offset_X,
1466 y_pos-Main.offset_Y)]);
1467 }
1468 for (i=start_y; i<=end_y; i++)
1469 {
1470 temp=y_pos+i-3;
1471 Pixel_preview(x_pos,temp,xor_lut[Read_pixel(x_pos-Main.offset_X,
1472 temp -Main.offset_Y)]);
1473 }
1474 Update_part_of_screen(x_pos+start_x-3,y_pos+start_y-3,end_x-start_x+1,end_y-start_y+1);
1475 }
1476 }
1477
1478
Curve_34_points_1_0(void)1479 void Curve_34_points_1_0(void)
1480 //
1481 // Opération : OPERATION_COURBE_?_POINTS
1482 // Click Souris: 1
1483 // Taille_Pile : 0
1484 //
1485 // Souris effacée: Oui
1486 //
1487 {
1488 Init_start_operation();
1489 Backup();
1490 Shade_table=Shade_table_left;
1491
1492 Paintbrush_hidden=1;
1493
1494 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Fore_color);
1495 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
1496
1497 if ((Config.Coords_rel) && (Menu_is_visible))
1498 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
1499
1500 Operation_push(Fore_color);
1501 Operation_push(Paintbrush_X);
1502 Operation_push(Paintbrush_Y);
1503 Operation_push(Paintbrush_X);
1504 Operation_push(Paintbrush_Y);
1505 }
1506
Curve_34_points_2_0(void)1507 void Curve_34_points_2_0(void)
1508 //
1509 // Opération : OPERATION_COURBE_?_POINTS
1510 // Click Souris: 2
1511 // Taille_Pile : 0
1512 //
1513 // Souris effacée: Oui
1514 //
1515 {
1516 if (Rightclick_colorpick(0))
1517 return;
1518
1519 Init_start_operation();
1520 Backup();
1521 Shade_table=Shade_table_right;
1522
1523 Paintbrush_hidden=1;
1524
1525 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Back_color);
1526 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
1527
1528 if ((Config.Coords_rel) && (Menu_is_visible))
1529 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
1530
1531 Operation_push(Back_color);
1532 Operation_push(Paintbrush_X);
1533 Operation_push(Paintbrush_Y);
1534 Operation_push(Paintbrush_X);
1535 Operation_push(Paintbrush_Y);
1536 }
1537
1538
Curve_34_points_1_5(void)1539 void Curve_34_points_1_5(void)
1540 //
1541 // Opération : OPERATION_COURBE_?_POINTS
1542 // Click Souris: 1
1543 // Taille_Pile : 5
1544 //
1545 // Souris effacée: Non
1546 //
1547 {
1548 short x1,x2,y1,y2;
1549
1550 Operation_pop(&y2);
1551 Operation_pop(&x2);
1552 Operation_pop(&y1);
1553 Operation_pop(&x1);
1554
1555 if ( (y2!=Paintbrush_Y) || (x2!=Paintbrush_X) )
1556 {
1557 Hide_cursor();
1558 Display_coords_rel_or_abs(x1,y1);
1559
1560 Hide_line_preview(x1,y1,x2,y2);
1561 Pixel_figure_preview (x1,y1,Fore_color);
1562 Draw_line_preview (x1,y1,Paintbrush_X,Paintbrush_Y,Fore_color);
1563
1564 Display_cursor();
1565 }
1566
1567 Operation_push(x1);
1568 Operation_push(y1);
1569 Operation_push(Paintbrush_X);
1570 Operation_push(Paintbrush_Y);
1571 }
1572
Curve_34_points_2_5(void)1573 void Curve_34_points_2_5(void)
1574 //
1575 // Opération : OPERATION_COURBE_?_POINTS
1576 // Click Souris: 2
1577 // Taille_Pile : 5
1578 //
1579 // Souris effacée: Non
1580 //
1581 {
1582 short x1,x2,y1,y2;
1583
1584 Operation_pop(&y2);
1585 Operation_pop(&x2);
1586 Operation_pop(&y1);
1587 Operation_pop(&x1);
1588
1589 if ( (y2!=Paintbrush_Y) || (x2!=Paintbrush_X) )
1590 {
1591 Hide_cursor();
1592 Display_coords_rel_or_abs(x1,y1);
1593
1594 Hide_line_preview(x1,y1,x2,y2);
1595 Pixel_figure_preview (x1,y1,Back_color);
1596 Draw_line_preview (x1,y1,Paintbrush_X,Paintbrush_Y,Back_color);
1597
1598 Display_cursor();
1599 }
1600
1601 Operation_push(x1);
1602 Operation_push(y1);
1603 Operation_push(Paintbrush_X);
1604 Operation_push(Paintbrush_Y);
1605 }
1606
1607
1608 byte Cursor_hidden_before_curve;
1609
Curve_4_points_0_5(void)1610 void Curve_4_points_0_5(void)
1611 //
1612 // Opération : OPERATION_4_POINTS_CURVE
1613 // Click Souris: 0
1614 // Taille_Pile : 5
1615 //
1616 // Souris effacée: Oui
1617 //
1618 {
1619 short x1,y1,x2,y2,x3,y3,x4,y4;
1620 short third_x,third_y;
1621 short color;
1622
1623 Operation_pop(&y4);
1624 Operation_pop(&x4);
1625 Operation_pop(&y1);
1626 Operation_pop(&x1);
1627 Operation_pop(&color);
1628
1629 third_x=Round_div(abs(x4-x1),3);
1630 third_y=Round_div(abs(y4-y1),3);
1631
1632 if (x1<x4)
1633 {
1634 x2=x1+third_x;
1635 x3=x4-third_x;
1636 }
1637 else
1638 {
1639 x3=x4+third_x;
1640 x2=x1-third_x;
1641 }
1642
1643 if (y1<y4)
1644 {
1645 y2=y1+third_y;
1646 y3=y4-third_y;
1647 }
1648 else
1649 {
1650 y3=y4+third_y;
1651 y2=y1-third_y;
1652 }
1653
1654 Hide_line_preview(x1,y1,x4,y4);
1655 Draw_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
1656
1657 // On trace les petites croix montrant les 2 points intermédiares
1658 Draw_curve_cross(x2,y2);
1659 Draw_curve_cross(x3,y3);
1660
1661 Cursor_hidden_before_curve=Cursor_hidden;
1662 Cursor_hidden=0;
1663
1664 Operation_push(color);
1665 Operation_push(x1);
1666 Operation_push(y1);
1667 Operation_push(x2);
1668 Operation_push(y2);
1669 Operation_push(x3);
1670 Operation_push(y3);
1671 Operation_push(x4);
1672 Operation_push(y4);
1673
1674 if ( (Config.Coords_rel) && (Menu_is_visible) )
1675 {
1676 Print_in_menu("X: Y: ",0);
1677 Print_coordinates();
1678 }
1679 }
1680
1681
Curve_4_points_1_9(void)1682 void Curve_4_points_1_9(void)
1683 //
1684 // Opération : OPERATION_4_POINTS_CURVE
1685 // Click Souris: 1
1686 // Taille_Pile : 9
1687 //
1688 // Souris effacée: Non
1689 //
1690 {
1691 short x1,y1,x2,y2,x3,y3,x4,y4;
1692 short color;
1693 byte it_is_x2;
1694
1695 Operation_pop(&y4);
1696 Operation_pop(&x4);
1697 Operation_pop(&y3);
1698 Operation_pop(&x3);
1699 Operation_pop(&y2);
1700 Operation_pop(&x2);
1701 Operation_pop(&y1);
1702 Operation_pop(&x1);
1703 Operation_pop(&color);
1704
1705 it_is_x2=(Distance(Paintbrush_X,Paintbrush_Y,x2,y2) < Distance(Paintbrush_X,Paintbrush_Y,x3,y3));
1706
1707 if ( ( it_is_x2 && ( (Paintbrush_X!=x2) || (Paintbrush_Y!=y2) ) )
1708 || ( (!it_is_x2) && ( (Paintbrush_X!=x3) || (Paintbrush_Y!=y3) ) ) )
1709 {
1710 Hide_cursor();
1711 Print_coordinates();
1712
1713 Draw_curve_cross(x2,y2);
1714 Draw_curve_cross(x3,y3);
1715
1716 Hide_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
1717
1718 if (it_is_x2)
1719 {
1720 x2=Paintbrush_X;
1721 y2=Paintbrush_Y;
1722 }
1723 else
1724 {
1725 x3=Paintbrush_X;
1726 y3=Paintbrush_Y;
1727 }
1728
1729 Draw_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
1730
1731 Draw_curve_cross(x2,y2);
1732 Draw_curve_cross(x3,y3);
1733
1734 Display_cursor();
1735 }
1736
1737 Operation_push(color);
1738 Operation_push(x1);
1739 Operation_push(y1);
1740 Operation_push(x2);
1741 Operation_push(y2);
1742 Operation_push(x3);
1743 Operation_push(y3);
1744 Operation_push(x4);
1745 Operation_push(y4);
1746 }
1747
1748
Curve_4_points_2_9(void)1749 void Curve_4_points_2_9(void)
1750 //
1751 // Opération : OPERATION_4_POINTS_CURVE
1752 // Click Souris: 2
1753 // Taille_Pile : 9
1754 //
1755 // Souris effacée: Oui
1756 //
1757 {
1758 short x1,y1,x2,y2,x3,y3,x4,y4;
1759 short color;
1760
1761 Operation_pop(&y4);
1762 Operation_pop(&x4);
1763 Operation_pop(&y3);
1764 Operation_pop(&x3);
1765 Operation_pop(&y2);
1766 Operation_pop(&x2);
1767 Operation_pop(&y1);
1768 Operation_pop(&x1);
1769 Operation_pop(&color);
1770
1771 Hide_cursor();
1772
1773 Draw_curve_cross(x2,y2);
1774 Draw_curve_cross(x3,y3);
1775
1776 Paintbrush_hidden=0;
1777 Cursor_hidden=Cursor_hidden_before_curve;
1778
1779 Hide_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
1780 Draw_curve_permanent(x1,y1,x2,y2,x3,y3,x4,y4,color);
1781
1782 Display_cursor();
1783 End_of_modification();
1784 Wait_end_of_click();
1785 }
1786
1787
1788 /////////////////////////////////////////////////// OPERATION_3_POINTS_CURVE
1789
1790
Compute_3_point_curve(short x1,short y1,short x4,short y4,short * x2,short * y2,short * x3,short * y3)1791 void Compute_3_point_curve(short x1, short y1, short x4, short y4,
1792 short * x2, short * y2, short * x3, short * y3)
1793 {
1794 float cx,cy; // Centre de (x1,y1) et (x4,y4)
1795 float bx,by; // Intersect. des dtes ((x1,y1),(x2,y2)) et ((x3,y3),(x4,y4))
1796
1797 cx=(float)(x1+x4)/2.0; // P1*--_ Legend:
1798 cy=(float)(y1+y4)/2.0; // · \·· P2 -_\|/ : curve
1799 // · \ ·*· * : important point
1800 bx=cx+((8.0/3.0)*(Paintbrush_X-cx));// · | ·· · : dotted line
1801 by=cy+((8.0/3.0)*(Paintbrush_Y-cy));// · |P ·· B
1802 // C *·····*·········* P=Pencil position
1803 *x2=Round((bx+x1)/2.0); // · | ·· C=middle of [P1,P4]
1804 *y2=Round((by+y1)/2.0); // · | ·· B=point computed as
1805 // · / ·*· C->B=(8/3) * C->P
1806 *x3=Round((bx+x4)/2.0); // · _/·· P3 P2=middle of [P1,B]
1807 *y3=Round((by+y4)/2.0); // P4*-- P3=middle of [P4,B]
1808 }
1809
1810
Curve_3_points_0_5(void)1811 void Curve_3_points_0_5(void)
1812 //
1813 // Opération : OPERATION_3_POINTS_CURVE
1814 // Click Souris: 0
1815 // Taille_Pile : 5
1816 //
1817 // Souris effacée: Oui
1818 //
1819 {
1820 short x1,y1,x2,y2,x3,y3,x4,y4;
1821 short color;
1822
1823 Operation_pop(&y4);
1824 Operation_pop(&x4);
1825 Operation_pop(&y1);
1826 Operation_pop(&x1);
1827 Operation_pop(&color);
1828
1829 Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3);
1830
1831 if (!Config.Stylus_mode)
1832 {
1833 Hide_line_preview(x1,y1,x4,y4);
1834 Draw_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
1835 }
1836
1837 if ( (Config.Coords_rel) && (Menu_is_visible) )
1838 {
1839 Print_in_menu("X: Y: ",0);
1840 Print_coordinates();
1841 }
1842
1843 Operation_push(color);
1844 Operation_push(x1);
1845 Operation_push(y1);
1846 Operation_push(x2);
1847 Operation_push(y2);
1848 Operation_push(x3);
1849 Operation_push(y3);
1850 Operation_push(x4);
1851 Operation_push(y4);
1852 Operation_push(Paintbrush_X);
1853 Operation_push(Paintbrush_Y);
1854
1855 if (Config.Stylus_mode)
1856 {
1857 Display_cursor();
1858 while(!Mouse_K)
1859 Get_input(20);
1860 Hide_cursor();
1861
1862 Hide_line_preview(x1,y1,x4,y4);
1863 }
1864 }
1865
Curve_drag(void)1866 void Curve_drag(void)
1867 {
1868 short x1,y1,x2,y2,x3,y3,x4,y4;
1869 short old_x,old_y;
1870 short color;
1871
1872 Operation_pop(&old_y);
1873 Operation_pop(&old_x);
1874
1875 if ( (Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) )
1876 {
1877 Operation_pop(&y4);
1878 Operation_pop(&x4);
1879 Operation_pop(&y3);
1880 Operation_pop(&x3);
1881 Operation_pop(&y2);
1882 Operation_pop(&x2);
1883 Operation_pop(&y1);
1884 Operation_pop(&x1);
1885 Operation_pop(&color);
1886
1887 Hide_cursor();
1888 Print_coordinates();
1889
1890 Hide_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
1891 Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3);
1892 Draw_curve_preview (x1,y1,x2,y2,x3,y3,x4,y4,color);
1893 Display_cursor();
1894
1895 Operation_push(color);
1896 Operation_push(x1);
1897 Operation_push(y1);
1898 Operation_push(x2);
1899 Operation_push(y2);
1900 Operation_push(x3);
1901 Operation_push(y3);
1902 Operation_push(x4);
1903 Operation_push(y4);
1904 }
1905 Operation_push(Paintbrush_X);
1906 Operation_push(Paintbrush_Y);
1907 }
Curve_finalize(void)1908 void Curve_finalize(void)
1909 {
1910 short x1,y1,x2,y2,x3,y3,x4,y4;
1911 short old_x,old_y;
1912 short color;
1913
1914 Operation_pop(&old_y);
1915 Operation_pop(&old_x);
1916 Operation_pop(&y4);
1917 Operation_pop(&x4);
1918 Operation_pop(&y3);
1919 Operation_pop(&x3);
1920 Operation_pop(&y2);
1921 Operation_pop(&x2);
1922 Operation_pop(&y1);
1923 Operation_pop(&x1);
1924 Operation_pop(&color);
1925
1926 Paintbrush_hidden=0;
1927
1928 Hide_cursor();
1929
1930 Hide_curve_preview (x1,y1,x2,y2,x3,y3,x4,y4,color);
1931 Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3);
1932 Draw_curve_permanent(x1,y1,x2,y2,x3,y3,x4,y4,color);
1933
1934 End_of_modification();
1935 Display_cursor();
1936 Wait_end_of_click();
1937 }
1938
Curve_3_points_0_11(void)1939 void Curve_3_points_0_11(void)
1940 //
1941 // Opération : OPERATION_3_POINTS_CURVE
1942 // Click Souris: 0
1943 // Taille_Pile : 11
1944 //
1945 // Souris effacée: Non
1946 //
1947 {
1948 if (!Config.Stylus_mode)
1949 Curve_drag();
1950 else
1951 Curve_finalize();
1952 }
1953
1954
Curve_3_points_12_11(void)1955 void Curve_3_points_12_11(void)
1956 //
1957 // Opération : OPERATION_3_POINTS_CURVE
1958 // Click Souris: 1 ou 2
1959 // Taille_Pile : 11
1960 //
1961 // Souris effacée: Oui
1962 //
1963 {
1964 if (!Config.Stylus_mode)
1965 Curve_finalize();
1966 else
1967 Curve_drag();
1968 }
1969
1970
1971 ///////////////////////////////////////////////////////////// OPERATION_AIRBRUSH
1972
Airbrush_1_0(void)1973 void Airbrush_1_0(void)
1974 //
1975 // Opération : OPERATION_AIRBRUSH
1976 // Click Souris: 1
1977 // Taille_Pile : 0
1978 //
1979 // Souris effacée: Non
1980 //
1981 {
1982 Init_start_operation();
1983 Backup();
1984 Shade_table=Shade_table_left;
1985
1986 if (GFX2_GetTicks()>Airbrush_next_time)
1987 {
1988 Airbrush(LEFT_SIDE);
1989 Airbrush_next_time = GFX2_GetTicks()+Airbrush_delay*10;
1990 }
1991
1992 Operation_push(Paintbrush_X);
1993 Operation_push(Paintbrush_Y);
1994 }
1995
Airbrush_2_0(void)1996 void Airbrush_2_0(void)
1997 //
1998 // Opération : OPERATION_AIRBRUSH
1999 // Click Souris: 2
2000 // Taille_Pile : 0
2001 //
2002 // Souris effacée: Non
2003 //
2004 {
2005 if (Rightclick_colorpick(1))
2006 return;
2007
2008 Init_start_operation();
2009 Backup();
2010 Shade_table=Shade_table_right;
2011 if (GFX2_GetTicks()>Airbrush_next_time)
2012 {
2013 Airbrush(RIGHT_SIDE);
2014 Airbrush_next_time = GFX2_GetTicks()+Airbrush_delay*10;
2015 }
2016
2017 Operation_push(Paintbrush_X);
2018 Operation_push(Paintbrush_Y);
2019 }
2020
Airbrush_12_2(void)2021 void Airbrush_12_2(void)
2022 //
2023 // Opération : OPERATION_AIRBRUSH
2024 // Click Souris: 1 ou 2
2025 // Taille_Pile : 2
2026 //
2027 // Souris effacée: Non
2028 //
2029 {
2030 short old_x,old_y;
2031 dword now;
2032
2033 Operation_pop(&old_y);
2034 Operation_pop(&old_x);
2035
2036 if ( (Menu_is_visible) && ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) )
2037 {
2038 Hide_cursor();
2039 Print_coordinates();
2040 Display_cursor();
2041 }
2042
2043 now=GFX2_GetTicks();
2044 if (now>Airbrush_next_time)
2045 {
2046 //Airbrush_next_time+=Airbrush_delay*10;
2047 // Time is now reset, because the += was death spiral
2048 // if drawing took more time than the frequency.
2049 Airbrush_next_time=now+Airbrush_delay*10;
2050 Airbrush(Mouse_K_unique);
2051 }
2052
2053 Operation_push(Paintbrush_X);
2054 Operation_push(Paintbrush_Y);
2055 }
2056
Airbrush_0_2(void)2057 void Airbrush_0_2(void)
2058 //
2059 // Opération : OPERATION_AIRBRUSH
2060 // Click Souris: 0
2061 // Taille_Pile : 2
2062 //
2063 // Souris effacée: Non
2064 //
2065 {
2066 Operation_stack_size-=2;
2067 End_of_modification();
2068 }
2069
2070
2071 ////////////////////////////////////////////////////////// OPERATION_POLYGON
2072
2073
Polygon_12_0(void)2074 void Polygon_12_0(void)
2075 // Opération : OPERATION_POLYGON
2076 // Click Souris: 1 ou 2
2077 // Taille_Pile : 0
2078 //
2079 // Souris effacée: Oui
2080 {
2081 byte color;
2082
2083 if (Rightclick_colorpick(0))
2084 return;
2085
2086 Init_start_operation();
2087 Backup();
2088 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
2089 Paintbrush_shape_before_operation=Paintbrush_shape;
2090 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
2091
2092 color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
2093
2094 // On place temporairement le début de la ligne qui ne s'afficherait pas sinon
2095 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
2096 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
2097
2098 if ((Config.Coords_rel) && (Menu_is_visible))
2099 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
2100
2101 Operation_push(Paintbrush_X);
2102 Operation_push(Paintbrush_Y);
2103 Operation_push(Mouse_K | 0x80);
2104 Operation_push(color);
2105 Operation_push(Paintbrush_X);
2106 Operation_push(Paintbrush_Y);
2107 Operation_push(Paintbrush_X);
2108 Operation_push(Paintbrush_Y);
2109 // Taille de pile 8 : phase d'appui, non interruptible
2110 }
2111
2112
2113
Polygon_12_9(void)2114 void Polygon_12_9(void)
2115 // Opération : OPERATION_POLYGON
2116 // Click Souris: 1 ou 2
2117 // Taille_Pile : 9
2118 //
2119 // Souris effacée: Oui
2120 {
2121 short start_x;
2122 short start_y;
2123 short end_x;
2124 short end_y;
2125 short color;
2126 short direction;
2127
2128 Operation_pop(&end_y);
2129 Operation_pop(&end_x);
2130 Operation_pop(&start_y);
2131 Operation_pop(&start_x);
2132 Operation_pop(&color);
2133 Operation_pop(&direction);
2134 Operation_pop(&direction);
2135
2136 if (direction==Mouse_K)
2137 {
2138 Operation_push(direction);
2139 Operation_push(color);
2140 Operation_push(start_x);
2141 Operation_push(start_y);
2142 Operation_push(end_x);
2143 Operation_push(end_y);
2144 // Taille de pile 8 : phase d'appui, non interruptible
2145 }
2146 else
2147 {
2148 // La série de ligne est terminée, il faut donc effacer la dernière
2149 // preview de ligne et relier le dernier point avec le premier
2150 Pixel_figure_preview_auto (start_x,start_y);
2151 Hide_line_preview (start_x,start_y,end_x,end_y);
2152 Operation_pop(&end_y);
2153 Operation_pop(&end_x);
2154 Paintbrush_shape=Paintbrush_shape_before_operation;
2155 // Le pied aurait été de ne pas repasser sur le 1er point de la 1ère ligne
2156 // mais c'est pas possible :(
2157 Draw_line_permanent(start_x,start_y,end_x,end_y,color);
2158 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
2159
2160 Display_cursor();
2161 End_of_modification();
2162 Wait_end_of_click();
2163 Hide_cursor();
2164
2165 if ( (Config.Coords_rel) && (Menu_is_visible) )
2166 {
2167 Print_in_menu("X: Y: ",0);
2168 Print_coordinates();
2169 }
2170
2171 Paintbrush_shape=Paintbrush_shape_before_operation;
2172 }
2173 }
2174
2175
2176 ////////////////////////////////////////////////////////// OPERATION_POLYFILL
2177
Polyfill_12_0(void)2178 void Polyfill_12_0(void)
2179 // Opération : OPERATION_POLYFILL
2180 // Click Souris: 1 ou 2
2181 // Taille_Pile : 0
2182 //
2183 // Souris effacée: Oui
2184 {
2185 byte color;
2186
2187 if (Rightclick_colorpick(0))
2188 return;
2189
2190 Init_start_operation();
2191 Backup();
2192 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
2193 Paintbrush_hidden=1;
2194
2195 color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
2196
2197 Polyfill_table_of_points=(short *) malloc((Config.Nb_max_vertices_per_polygon<<1)*sizeof(short));
2198 Polyfill_table_of_points[0]=Paintbrush_X;
2199 Polyfill_table_of_points[1]=Paintbrush_Y;
2200 Polyfill_number_of_points=1;
2201
2202 // On place temporairement le début de la ligne qui ne s'afficherait pas sinon
2203 Pixel_figure_preview_xor(Paintbrush_X,Paintbrush_Y,0);
2204 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
2205
2206 if ((Config.Coords_rel) && (Menu_is_visible))
2207 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
2208
2209 Operation_push(Paintbrush_X);
2210 Operation_push(Paintbrush_Y);
2211 Operation_push(Mouse_K | 0x80);
2212 Operation_push(color);
2213 Operation_push(Paintbrush_X);
2214 Operation_push(Paintbrush_Y);
2215 Operation_push(Paintbrush_X);
2216 Operation_push(Paintbrush_Y);
2217 // Taille de pile 8 : phase d'appui, non interruptible
2218 }
2219
2220
Polyfill_0_8(void)2221 void Polyfill_0_8(void)
2222 // Opération : OPERATION_POLYFILL
2223 // Click Souris: 0
2224 // Taille_Pile : 8
2225 //
2226 // Souris effacée: Oui
2227 {
2228 short start_x;
2229 short start_y;
2230 short end_x;
2231 short end_y;
2232 short color;
2233 short direction;
2234
2235 Operation_pop(&end_y);
2236 Operation_pop(&end_x);
2237 Operation_pop(&start_y);
2238 Operation_pop(&start_x);
2239 Operation_pop(&color);
2240 Operation_pop(&direction);
2241
2242 if ((Config.Coords_rel) && (Menu_is_visible))
2243 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
2244
2245 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
2246
2247 if (direction & 0x80)
2248 direction=(direction & 0x7F);
2249
2250 Operation_push(direction); // Valeur bidon servant de nouvel état de pile
2251 Operation_push(direction);
2252 Operation_push(color);
2253
2254 Draw_line_preview_xor(start_x,start_y,Paintbrush_X,Paintbrush_Y,0);
2255
2256 if (Polyfill_number_of_points<Config.Nb_max_vertices_per_polygon)
2257 {
2258 Polyfill_table_of_points[Polyfill_number_of_points<<1] =Paintbrush_X;
2259 Polyfill_table_of_points[(Polyfill_number_of_points<<1)+1]=Paintbrush_Y;
2260 Polyfill_number_of_points++;
2261
2262 Operation_push(Paintbrush_X);
2263 Operation_push(Paintbrush_Y);
2264 Operation_push(Paintbrush_X);
2265 Operation_push(Paintbrush_Y);
2266 }
2267 else
2268 {
2269 Operation_push(start_x);
2270 Operation_push(start_y);
2271 Operation_push(Paintbrush_X);
2272 Operation_push(Paintbrush_Y);
2273 }
2274 // Taille de pile 9 : phase de "repos", interruptible (comme Elliot Ness :))
2275 }
2276
2277
Polyfill_12_8(void)2278 void Polyfill_12_8(void)
2279 // Opération : OPERATION_POLYFILL
2280 // Click Souris: 1 ou 2 | 0
2281 // Taille_Pile : 8 | 9
2282 //
2283 // Souris effacée: Non
2284 {
2285 short start_x;
2286 short start_y;
2287 short end_x;
2288 short end_y;
2289
2290 Operation_pop(&end_y);
2291 Operation_pop(&end_x);
2292
2293 if ((Paintbrush_X!=end_x) || (Paintbrush_Y!=end_y))
2294 {
2295 Hide_cursor();
2296 Operation_pop(&start_y);
2297 Operation_pop(&start_x);
2298
2299 Display_coords_rel_or_abs(start_x,start_y);
2300
2301 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
2302 Draw_line_preview_xor(start_x,start_y,Paintbrush_X,Paintbrush_Y,0);
2303
2304 Operation_push(start_x);
2305 Operation_push(start_y);
2306 Display_cursor();
2307 }
2308
2309 Operation_push(Paintbrush_X);
2310 Operation_push(Paintbrush_Y);
2311 }
2312
2313
Polyfill_12_9(void)2314 void Polyfill_12_9(void)
2315 // Opération : OPERATION_POLYFILL
2316 // Click Souris: 1 ou 2
2317 // Taille_Pile : 9
2318 //
2319 // Souris effacée: Oui
2320 {
2321 short start_x;
2322 short start_y;
2323 short end_x;
2324 short end_y;
2325 short color;
2326 short direction;
2327
2328 Operation_pop(&end_y);
2329 Operation_pop(&end_x);
2330 Operation_pop(&start_y);
2331 Operation_pop(&start_x);
2332 Operation_pop(&color);
2333 Operation_pop(&direction);
2334 Operation_pop(&direction);
2335
2336 if (direction==Mouse_K)
2337 {
2338 Operation_push(direction);
2339 Operation_push(color);
2340 Operation_push(start_x);
2341 Operation_push(start_y);
2342 Operation_push(end_x);
2343 Operation_push(end_y);
2344 // Taille de pile 8 : phase d'appui, non interruptible
2345 }
2346 else
2347 {
2348 // La série de lignes est terminée, il faut donc effacer la dernière
2349 // preview de ligne et relier le dernier point avec le premier
2350 Hide_cursor();
2351 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
2352 Operation_pop(&end_y);
2353 Operation_pop(&end_x);
2354 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
2355
2356 Display_all_screen();
2357 Polyfill(Polyfill_number_of_points,Polyfill_table_of_points,color);
2358 free(Polyfill_table_of_points);
2359 Polyfill_table_of_points = NULL;
2360
2361 End_of_modification();
2362 if ( (Config.Coords_rel) && (Menu_is_visible) )
2363 {
2364 Print_in_menu("X: Y: ",0);
2365 Print_coordinates();
2366 }
2367
2368 Paintbrush_hidden=0;
2369
2370 Display_cursor();
2371 Wait_end_of_click();
2372 }
2373 }
2374
2375
2376 ////////////////////////////////////////////////////////// OPERATION_POLYFORM
2377
2378
Polyform_12_0(void)2379 void Polyform_12_0(void)
2380 // Opération : OPERATION_POLYFORM
2381 // Click Souris: 1 ou 2
2382 // Taille_Pile : 0
2383 //
2384 // Souris effacée: Oui
2385 {
2386 short color;
2387
2388 if (Rightclick_colorpick(0))
2389 return;
2390
2391 Init_start_operation();
2392 Backup();
2393 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
2394
2395 color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
2396
2397 // On place un premier pinceau en (Paintbrush_X,Paintbrush_Y):
2398 Draw_paintbrush(Paintbrush_X,Paintbrush_Y,color);
2399 // Et on affiche un pixel de preview en (Paintbrush_X,Paintbrush_Y):
2400 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
2401
2402 Operation_push(Paintbrush_X); // X Initial
2403 Operation_push(Paintbrush_Y); // X Initial
2404 Operation_push(color); // color de remplissage
2405 Operation_push(Paintbrush_X); // Start X
2406 Operation_push(Paintbrush_Y); // Start Y
2407 Operation_push(Paintbrush_X); // End X
2408 Operation_push(Paintbrush_Y); // End Y
2409 Operation_push(Mouse_K); // click
2410 }
2411
2412
Polyform_12_8(void)2413 void Polyform_12_8(void)
2414 // Opération : OPERATION_POLYFORM
2415 // Click Souris: 1 ou 2
2416 // Taille_Pile : 8
2417 //
2418 // Souris effacée: Non
2419 {
2420 short click;
2421 short end_y;
2422 short end_x;
2423 short start_y;
2424 short start_x;
2425 short color;
2426 short initial_y;
2427 short initial_x;
2428
2429 Operation_pop(&click);
2430 Operation_pop(&end_y);
2431 Operation_pop(&end_x);
2432 Operation_pop(&start_y);
2433 Operation_pop(&start_x);
2434
2435 if (click==Mouse_K)
2436 {
2437 // L'utilisateur clic toujours avec le bon bouton de souris
2438
2439 if ((start_x!=Paintbrush_X) || (start_y!=Paintbrush_Y))
2440 {
2441 // Il existe un segment définit par (start_x,start_y)-(Paintbrush_X,Paintbrush_Y)
2442
2443 Hide_cursor();
2444 Print_coordinates();
2445
2446 Operation_pop(&color);
2447
2448 // On efface la preview du segment validé:
2449 Pixel_figure_preview_auto (start_x,start_y);
2450 Hide_line_preview(start_x,start_y,end_x,end_y);
2451
2452 // On l'affiche de façon définitive:
2453 Draw_line_permanent(start_x,start_y,Paintbrush_X,Paintbrush_Y,color);
2454
2455 // Et on affiche un pixel de preview en (Paintbrush_X,Paintbrush_Y):
2456 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
2457
2458 Operation_push(color);
2459
2460 Display_cursor();
2461 }
2462
2463 Operation_push(Paintbrush_X); // Nouveau start_x
2464 Operation_push(Paintbrush_Y); // Nouveau start_y
2465 Operation_push(Paintbrush_X); // Nouveau end_x
2466 Operation_push(Paintbrush_Y); // Nouveau end_y
2467 Operation_push(click);
2468 }
2469 else
2470 {
2471 // L'utilisateur souhaite arrêter l'opération et refermer le polygone
2472
2473 Operation_pop(&color);
2474 Operation_pop(&initial_y);
2475 Operation_pop(&initial_x);
2476
2477 Hide_cursor();
2478 Print_coordinates();
2479
2480 // On efface la preview du segment annulé:
2481 Hide_line_preview(start_x,start_y,end_x,end_y);
2482
2483 // On affiche de façon définitive le bouclage du polygone:
2484 Draw_line_permanent(start_x,start_y,initial_x,initial_y,color);
2485
2486 Display_cursor();
2487 End_of_modification();
2488 Wait_end_of_click();
2489 }
2490 }
2491
2492
Polyform_0_8(void)2493 void Polyform_0_8(void)
2494 // Opération : OPERATION_POLYFORM
2495 // Click Souris: 0
2496 // Taille_Pile : 8
2497 //
2498 // Souris effacée: Non
2499 {
2500 short click;
2501 short end_y;
2502 short end_x;
2503 short start_y;
2504 short start_x;
2505 short color;
2506
2507 Operation_pop(&click);
2508 Operation_pop(&end_y);
2509 Operation_pop(&end_x);
2510
2511 if ((end_x!=Paintbrush_X) || (end_y!=Paintbrush_Y))
2512 {
2513 Hide_cursor();
2514 Print_coordinates();
2515
2516 Operation_pop(&start_y);
2517 Operation_pop(&start_x);
2518 Operation_pop(&color);
2519
2520 // On met à jour l'affichage de la preview du prochain segment:
2521 Hide_line_preview(start_x,start_y,end_x,end_y);
2522 Draw_line_preview (start_x,start_y,Paintbrush_X,Paintbrush_Y,color);
2523
2524 Operation_push(color);
2525 Operation_push(start_x);
2526 Operation_push(start_y);
2527
2528 Display_cursor();
2529 }
2530
2531 Operation_push(Paintbrush_X);
2532 Operation_push(Paintbrush_Y);
2533 Operation_push(click);
2534 }
2535
2536
2537 /////////////////////////////////////////////////// OPERATION_FILLED_POLYFORM
2538
2539
Filled_polyform_12_0(void)2540 void Filled_polyform_12_0(void)
2541 // Opération : OPERATION_FILLED_POLYFORM
2542 // Click Souris: 1 ou 2
2543 // Taille_Pile : 0
2544 //
2545 // Souris effacée: Oui
2546 {
2547 short color;
2548
2549 if (Rightclick_colorpick(0))
2550 return;
2551
2552 Init_start_operation();
2553
2554 // Cette opération étant également utilisée pour le lasso, on ne fait pas de
2555 // backup si on prend une brosse au lasso avec le bouton gauche.
2556 if ((Current_operation==OPERATION_FILLED_POLYFORM) || (Current_operation==OPERATION_FILLED_CONTOUR) || (Mouse_K==RIGHT_SIDE))
2557 Backup();
2558
2559 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
2560 Paintbrush_hidden=1;
2561
2562 color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
2563
2564 Polyfill_table_of_points=(short *) malloc((Config.Nb_max_vertices_per_polygon<<1)*sizeof(short));
2565 Polyfill_table_of_points[0]=Paintbrush_X;
2566 Polyfill_table_of_points[1]=Paintbrush_Y;
2567 Polyfill_number_of_points=1;
2568
2569 // On place temporairement le début de la ligne qui ne s'afficherait pas sinon
2570 Pixel_figure_preview_xor(Paintbrush_X,Paintbrush_Y,0);
2571 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
2572
2573 Operation_push(Paintbrush_X); // X Initial
2574 Operation_push(Paintbrush_Y); // X Initial
2575 Operation_push(color); // color de remplissage
2576 Operation_push(Paintbrush_X); // Start X
2577 Operation_push(Paintbrush_Y); // Start Y
2578 Operation_push(Paintbrush_X); // End X
2579 Operation_push(Paintbrush_Y); // End Y
2580 Operation_push(Mouse_K); // click
2581 }
2582
2583
Filled_polyform_12_8(void)2584 void Filled_polyform_12_8(void)
2585 // Opération : OPERATION_FILLED_POLYFORM
2586 // Click Souris: 1 ou 2
2587 // Taille_Pile : 8
2588 //
2589 // Souris effacée: Non
2590 {
2591 short click;
2592 short end_y;
2593 short end_x;
2594 short start_y;
2595 short start_x;
2596 short color;
2597 short initial_y;
2598 short initial_x;
2599
2600 Operation_pop(&click);
2601 Operation_pop(&end_y);
2602 Operation_pop(&end_x);
2603 Operation_pop(&start_y);
2604 Operation_pop(&start_x);
2605
2606 if (click==Mouse_K)
2607 {
2608 // L'utilisateur clique toujours avec le bon bouton de souris
2609
2610 if (((start_x!=Paintbrush_X) || (start_y!=Paintbrush_Y)) &&
2611 (Polyfill_number_of_points<Config.Nb_max_vertices_per_polygon))
2612 {
2613 // Il existe un nouveau segment défini par
2614 // (start_x,start_y)-(Paintbrush_X,Paintbrush_Y)
2615
2616 Hide_cursor();
2617 Print_coordinates();
2618
2619 // On le place à l'écran
2620 if (Current_operation==OPERATION_FILLED_CONTOUR)
2621 {
2622 Draw_line_preview_xorback(start_x,start_y,end_x,end_y,0);
2623 Draw_line_preview_xorback(start_x,start_y,Paintbrush_X,Paintbrush_Y,0);
2624 }
2625 else
2626 {
2627 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
2628 Draw_line_preview_xor(start_x,start_y,Paintbrush_X,Paintbrush_Y,0);
2629 }
2630
2631 // On peut le rajouter au polygone
2632
2633 Polyfill_table_of_points[Polyfill_number_of_points<<1] =Paintbrush_X;
2634 Polyfill_table_of_points[(Polyfill_number_of_points<<1)+1]=Paintbrush_Y;
2635 Polyfill_number_of_points++;
2636
2637 Operation_push(Paintbrush_X); // Nouveau start_x
2638 Operation_push(Paintbrush_Y); // Nouveau start_y
2639 Operation_push(Paintbrush_X); // Nouveau end_x
2640 Operation_push(Paintbrush_Y); // Nouveau end_y
2641 Operation_push(click);
2642
2643 Display_cursor();
2644 }
2645 else
2646 {
2647 if (Polyfill_number_of_points==Config.Nb_max_vertices_per_polygon)
2648 {
2649 // Le curseur bouge alors qu'on ne peut plus stocker de segments ?
2650
2651 if ((end_x!=Paintbrush_X) || (end_y!=Paintbrush_Y))
2652 {
2653 Hide_cursor();
2654 Print_coordinates();
2655
2656 // On le place à l'écran
2657 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
2658 Draw_line_preview_xor(start_x,start_y,Paintbrush_X,Paintbrush_Y,0);
2659 Display_cursor();
2660 }
2661
2662 // On remet les mêmes valeurs (comme si on n'avait pas cliqué):
2663 Operation_push(start_x);
2664 Operation_push(start_y);
2665 Operation_push(Paintbrush_X);
2666 Operation_push(Paintbrush_Y);
2667 Operation_push(click);
2668 }
2669 else
2670 {
2671 Operation_push(Paintbrush_X); // Nouveau start_x
2672 Operation_push(Paintbrush_Y); // Nouveau start_y
2673 Operation_push(Paintbrush_X); // Nouveau end_x
2674 Operation_push(Paintbrush_Y); // Nouveau end_y
2675 Operation_push(click);
2676 }
2677 }
2678 }
2679 else
2680 {
2681 // L'utilisateur souhaite arrêter l'opération et refermer le polygone
2682
2683 Operation_pop(&color);
2684 Operation_pop(&initial_y);
2685 Operation_pop(&initial_x);
2686
2687 Hide_cursor();
2688 Print_coordinates();
2689
2690 // Pas besoin d'effacer la ligne (start_x,start_y)-(end_x,end_y)
2691 // puisque on les effaces toutes d'un coup.
2692
2693 Display_all_screen();
2694 Polyfill(Polyfill_number_of_points,Polyfill_table_of_points,color);
2695 free(Polyfill_table_of_points);
2696 Polyfill_table_of_points = NULL;
2697
2698 Paintbrush_hidden=0;
2699
2700 Display_cursor();
2701 End_of_modification();
2702 Wait_end_of_click();
2703 }
2704 }
2705
2706
Filled_polyform_0_8(void)2707 void Filled_polyform_0_8(void)
2708 // Opération : OPERATION_FILLED_POLYFORM
2709 // Click Souris: 0
2710 // Taille_Pile : 8
2711 //
2712 // Souris effacée: Non
2713 {
2714 short click;
2715 short end_y;
2716 short end_x;
2717 short start_y;
2718 short start_x;
2719
2720 Operation_pop(&click);
2721 Operation_pop(&end_y);
2722 Operation_pop(&end_x);
2723
2724 if ((end_x!=Paintbrush_X) || (end_y!=Paintbrush_Y))
2725 {
2726 Hide_cursor();
2727 Print_coordinates();
2728
2729 Operation_pop(&start_y);
2730 Operation_pop(&start_x);
2731
2732 // On met à jour l'affichage de la preview du prochain segment:
2733 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
2734 Draw_line_preview_xor(start_x,start_y,Paintbrush_X,Paintbrush_Y,0);
2735
2736 Operation_push(start_x);
2737 Operation_push(start_y);
2738
2739 Display_cursor();
2740 }
2741
2742 Operation_push(Paintbrush_X);
2743 Operation_push(Paintbrush_Y);
2744 Operation_push(click);
2745 }
2746
Filled_contour_0_8(void)2747 void Filled_contour_0_8(void)
2748 // Opération : OPERATION_FILLED_CONTOUR
2749 // Click Souris: 0
2750 // Taille_Pile : 8
2751 //
2752 // Souris effacée: Non
2753 {
2754 short click;
2755 short end_y;
2756 short end_x;
2757 short start_y;
2758 short start_x;
2759 short color;
2760 short initial_y;
2761 short initial_x;
2762
2763 Operation_pop(&click);
2764 Operation_pop(&end_y);
2765 Operation_pop(&end_x);
2766 Operation_pop(&start_y);
2767 Operation_pop(&start_x);
2768 Operation_pop(&color);
2769 Operation_pop(&initial_y);
2770 Operation_pop(&initial_x);
2771
2772 Hide_cursor();
2773 Print_coordinates();
2774
2775 // Pas besoin d'effacer la ligne (start_x,start_y)-(end_x,end_y)
2776 // puisque on les effaces toutes d'un coup.
2777
2778 Display_all_screen();
2779 Polyfill(Polyfill_number_of_points,Polyfill_table_of_points,color);
2780 free(Polyfill_table_of_points);
2781 Polyfill_table_of_points = NULL;
2782
2783 Paintbrush_hidden=0;
2784
2785 Display_cursor();
2786 End_of_modification();
2787 }
2788
2789
2790 //////////////////////////////////////////////////////////// OPERATION_SCROLL
2791
2792
2793 byte Cursor_hidden_before_scroll;
2794
Scroll_12_0(void)2795 void Scroll_12_0(void)
2796 //
2797 // Opération : OPERATION_SCROLL
2798 // Click Souris: 1 ou 2
2799 // Taille_Pile : 0
2800 //
2801 // Souris effacée: Oui
2802 //
2803 {
2804 Init_start_operation();
2805 Operation_push(Paintbrush_X);
2806 Operation_push(Paintbrush_Y);
2807 Operation_push(Paintbrush_X);
2808 Operation_push(Paintbrush_Y);
2809 Operation_push(Mouse_K); // LEFT_SIDE or RIGHT_SIDE
2810 if (Mouse_K == LEFT_SIDE)
2811 Backup();
2812 else
2813 {
2814 Backup_layers(LAYER_ALL); // Main.layers_visible
2815 if (Main.backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
2816 {
2817 // Ensure the backup visible image is up-to-date
2818 // (after swapping some layers on/off, it gets outdated)
2819 memcpy(Main_visible_image_backup.Image,
2820 Main.visible_image.Image,
2821 Main.image_width*Main.image_height);
2822 }
2823 }
2824 Update_screen_targets();
2825
2826 Cursor_hidden_before_scroll=Cursor_hidden;
2827 Cursor_hidden=1;
2828 if ((Config.Coords_rel) && (Menu_is_visible))
2829 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
2830 }
2831
2832
Scroll_12_5(void)2833 void Scroll_12_5(void)
2834 //
2835 // Opération : OPERATION_SCROLL
2836 // Click Souris: 1 ou 2
2837 // Taille_Pile : 5
2838 //
2839 // Souris effacée: Non
2840 //
2841 {
2842 short center_x;
2843 short center_y;
2844 short x_pos;
2845 short y_pos;
2846 short x_offset;
2847 short y_offset;
2848 short side;
2849 //char str[5];
2850
2851 Operation_pop(&side);
2852 Operation_pop(&y_pos);
2853 Operation_pop(&x_pos);
2854 Operation_pop(¢er_y);
2855 Operation_pop(¢er_x);
2856
2857 if ( (Paintbrush_X!=x_pos) || (Paintbrush_Y!=y_pos) )
2858 {
2859 // L'utilisateur a bougé, il faut scroller l'image
2860
2861 if (Paintbrush_X>=center_x)
2862 x_offset=(Paintbrush_X-center_x)%Main.image_width;
2863 else
2864 x_offset=Main.image_width-((center_x-Paintbrush_X)%Main.image_width);
2865
2866 if (Paintbrush_Y>=center_y)
2867 y_offset=(Paintbrush_Y-center_y)%Main.image_height;
2868 else
2869 y_offset=Main.image_height-((center_y-Paintbrush_Y)%Main.image_height);
2870
2871 Display_coords_rel_or_abs(center_x,center_y);
2872
2873 if (side == RIGHT_SIDE)
2874 {
2875 // All layers at once
2876 Scroll_picture(Screen_backup, Main_screen, x_offset,y_offset);
2877 }
2878 else
2879 {
2880 // One layer at once
2881 Scroll_picture(Main.backups->Pages->Next->Image[Main.current_layer].Pixels, Main.backups->Pages->Image[Main.current_layer].Pixels, x_offset, y_offset);
2882 Redraw_current_layer();
2883 }
2884
2885 Display_all_screen();
2886 }
2887
2888 Operation_push(center_x);
2889 Operation_push(center_y);
2890 Operation_push(Paintbrush_X);
2891 Operation_push(Paintbrush_Y);
2892 Operation_push(side);
2893 }
2894
Scroll_0_5(void)2895 void Scroll_0_5(void)
2896 //
2897 // Opération : OPERATION_SCROLL
2898 // Click Souris: 0
2899 // Taille_Pile : 5
2900 //
2901 // Souris effacée: Oui
2902 //
2903 {
2904 // All layers at once
2905 short center_x;
2906 short center_y;
2907 short x_pos;
2908 short y_pos;
2909 short x_offset;
2910 short y_offset;
2911 short side;
2912 int i;
2913
2914
2915 Operation_pop(&side);
2916 Operation_pop(&y_pos);
2917 Operation_pop(&x_pos);
2918 Operation_pop(¢er_y);
2919 Operation_pop(¢er_x);
2920
2921 if (side == RIGHT_SIDE)
2922 {
2923 // All layers at once
2924 if (x_pos>=center_x)
2925 x_offset=(x_pos-center_x)%Main.image_width;
2926 else
2927 x_offset=Main.image_width-((center_x-x_pos)%Main.image_width);
2928
2929 if (y_pos>=center_y)
2930 y_offset=(y_pos-center_y)%Main.image_height;
2931 else
2932 y_offset=Main.image_height-((center_y-y_pos)%Main.image_height);
2933
2934 // Do the actual scroll operation on all layers.
2935 for (i=0; i<Main.backups->Pages->Nb_layers; i++)
2936 //if ((1<<i) & Main.layers_visible)
2937 Scroll_picture(Main.backups->Pages->Next->Image[i].Pixels, Main.backups->Pages->Image[i].Pixels, x_offset, y_offset);
2938 // Update the depth buffer too ...
2939 // It would be faster to scroll it, but we don't have method
2940 // for in-place scrolling.
2941 Update_depth_buffer();
2942 }
2943 else
2944 {
2945 // One layer : everything was done while dragging the mouse
2946 }
2947 if (Main.tilemap_mode)
2948 Tilemap_update();
2949
2950 Cursor_hidden=Cursor_hidden_before_scroll;
2951
2952 End_of_modification();
2953 if ((Config.Coords_rel) && (Menu_is_visible))
2954 {
2955 Print_in_menu("X: Y: ",0);
2956 Print_coordinates();
2957 }
2958 }
2959
2960
2961 //////////////////////////////////////////////////// OPERATION_GRAD_CIRCLE
2962
2963
Grad_circle_12_0(void)2964 void Grad_circle_12_0(void)
2965 //
2966 // Opération : OPERATION_GRAD_CIRCLE
2967 // Click Souris: 1 ou 2
2968 // Taille_Pile : 0
2969 //
2970 // Souris effacée: Oui
2971 {
2972 byte color;
2973
2974 Init_start_operation();
2975 Backup();
2976 Load_gradient_data(Current_gradient);
2977
2978 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
2979 color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
2980
2981 Paintbrush_hidden_before_scroll=Paintbrush_hidden;
2982 Paintbrush_hidden=1;
2983
2984 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
2985 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
2986
2987 if ((Config.Coords_rel) && (Menu_is_visible))
2988 Print_in_menu("Radius: 0 ",0);
2989
2990 Operation_push(Mouse_K);
2991 Operation_push(color);
2992 Operation_push(Paintbrush_X);
2993 Operation_push(Paintbrush_Y);
2994 Operation_push(Paintbrush_X);
2995 Operation_push(Paintbrush_Y);
2996 }
2997
2998
Grad_circle_12_6(void)2999 void Grad_circle_12_6(void)
3000 //
3001 // Opération : OPERATION_GRAD_CIRCLE
3002 // Click Souris: 1 ou 2
3003 // Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
3004 //
3005 // Souris effacée: Non
3006 //
3007 {
3008 short tangent_x;
3009 short tangent_y;
3010 short center_x;
3011 short center_y;
3012 short color;
3013 long limit;
3014 char str[5];
3015
3016 Operation_pop(&tangent_y);
3017 Operation_pop(&tangent_x);
3018 Operation_pop(¢er_y);
3019 Operation_pop(¢er_x);
3020 Operation_pop(&color);
3021
3022
3023 if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) )
3024 {
3025 Hide_cursor();
3026 Cursor_shape=CURSOR_SHAPE_TARGET;
3027 if ((Config.Coords_rel) && (Menu_is_visible))
3028 {
3029 Num2str(Distance(center_x,center_y,Paintbrush_X,Paintbrush_Y),str,4);
3030 Print_in_menu(str,7);
3031 }
3032 else
3033 Print_coordinates();
3034
3035 limit=((tangent_x-center_x)*(tangent_x-center_x))+
3036 ((tangent_y-center_y)*(tangent_y-center_y));
3037 Hide_empty_circle_preview(center_x,center_y,limit);
3038
3039 limit=((Paintbrush_X-center_x)*(Paintbrush_X-center_x))+
3040 ((Paintbrush_Y-center_y)*(Paintbrush_Y-center_y));
3041 Draw_empty_circle_preview(center_x,center_y,limit,color);
3042
3043 Display_cursor();
3044 }
3045
3046 Operation_push(color);
3047 Operation_push(center_x);
3048 Operation_push(center_y);
3049 Operation_push(Paintbrush_X);
3050 Operation_push(Paintbrush_Y);
3051 }
3052
3053
Grad_circle_0_6(void)3054 void Grad_circle_0_6(void)
3055 //
3056 // Opération : OPERATION_GRAD_CIRCLE
3057 // Click Souris: 0
3058 // Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
3059 //
3060 // Souris effacée: Oui
3061 //
3062 {
3063 short tangent_x;
3064 short tangent_y;
3065 short center_x;
3066 short center_y;
3067 short color;
3068 short click;
3069
3070 Operation_pop(&tangent_y);
3071 Operation_pop(&tangent_x);
3072 Operation_pop(¢er_y);
3073 Operation_pop(¢er_x);
3074
3075 Operation_pop(&color);
3076 Operation_pop(&click);
3077
3078 if (click==LEFT_SIDE)
3079 {
3080 Operation_push(click);
3081 Operation_push(color);
3082
3083 Operation_push(center_x);
3084 Operation_push(center_y);
3085 Operation_push(tangent_x);
3086 Operation_push(tangent_y);
3087
3088 Operation_push(Paintbrush_X);
3089 Operation_push(Paintbrush_Y);
3090
3091 // On change la forme du curseur
3092 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
3093
3094 // On affiche une croix XOR au centre du cercle
3095 Draw_curve_cross(center_x,center_y);
3096
3097 if (Menu_is_visible)
3098 {
3099 if (Config.Coords_rel)
3100 Print_in_menu("X: Y:",0);
3101 else
3102 Print_in_menu("X: Y: ",0);
3103 Display_coords_rel_or_abs(center_x,center_y);
3104 }
3105 }
3106 else
3107 {
3108 long limit;
3109 limit=((tangent_x-center_x)*(tangent_x-center_x))+
3110 ((tangent_y-center_y)*(tangent_y-center_y));
3111 Hide_empty_circle_preview(center_x,center_y,limit);
3112
3113 Paintbrush_hidden=Paintbrush_hidden_before_scroll;
3114 Cursor_shape=CURSOR_SHAPE_TARGET;
3115
3116 Draw_filled_circle(center_x,center_y,limit,Back_color);
3117
3118 End_of_modification();
3119 if ((Config.Coords_rel) && (Menu_is_visible))
3120 {
3121 Print_in_menu("X: Y: ",0);
3122 Print_coordinates();
3123 }
3124 }
3125 }
3126
3127
Grad_circle_12_8(void)3128 void Grad_circle_12_8(void)
3129 //
3130 // Opération : OPERATION_GRAD_CIRCLE
3131 // Click Souris: 0
3132 // Taille_Pile : 8 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente, old_x, old_y)
3133 //
3134 // Souris effacée: Oui
3135 //
3136 {
3137 short tangent_x;
3138 short tangent_y;
3139 short center_x;
3140 short center_y;
3141 short color;
3142 short old_mouse_k;
3143 long limit;
3144
3145 Operation_stack_size-=2; // On fait sauter les 2 derniers élts de la pile
3146 Operation_pop(&tangent_y);
3147 Operation_pop(&tangent_x);
3148 Operation_pop(¢er_y);
3149 Operation_pop(¢er_x);
3150 Operation_pop(&color);
3151 Operation_pop(&old_mouse_k);
3152
3153 Hide_cursor();
3154 // On efface la croix XOR au centre du cercle
3155 Draw_curve_cross(center_x,center_y);
3156
3157 limit=((tangent_x-center_x)*(tangent_x-center_x))+
3158 ((tangent_y-center_y)*(tangent_y-center_y));
3159 Hide_empty_circle_preview(center_x,center_y,limit);
3160
3161 Paintbrush_hidden=Paintbrush_hidden_before_scroll;
3162 Cursor_shape=CURSOR_SHAPE_TARGET;
3163
3164 if (Mouse_K==old_mouse_k)
3165 Draw_grad_circle(center_x,center_y,limit,Paintbrush_X,Paintbrush_Y);
3166 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
3167
3168 Display_cursor();
3169 End_of_modification();
3170 Wait_end_of_click();
3171
3172 if ((Config.Coords_rel) && (Menu_is_visible))
3173 {
3174 Print_in_menu("X: Y: ",0);
3175 Print_coordinates();
3176 }
3177 }
3178
3179
Grad_circle_or_ellipse_0_8(void)3180 void Grad_circle_or_ellipse_0_8(void)
3181 //
3182 // Opération : OPERATION_{CERCLE|ELLIPSE}_DEGRADE
3183 // Click Souris: 0
3184 // Taille_Pile : 8
3185 //
3186 // Souris effacée: Non
3187 //
3188 {
3189 short start_x;
3190 short start_y;
3191 short tangent_x;
3192 short tangent_y;
3193 short old_x;
3194 short old_y;
3195
3196 Operation_pop(&old_y);
3197 Operation_pop(&old_x);
3198
3199 if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y))
3200 {
3201 Operation_pop(&tangent_y);
3202 Operation_pop(&tangent_x);
3203 Operation_pop(&start_y);
3204 Operation_pop(&start_x);
3205 Display_coords_rel_or_abs(start_x,start_y);
3206 Operation_push(start_x);
3207 Operation_push(start_y);
3208 Operation_push(tangent_x);
3209 Operation_push(tangent_y);
3210 }
3211
3212 Operation_push(Paintbrush_X);
3213 Operation_push(Paintbrush_Y);
3214 }
3215
3216
3217 ////////////////////////////////////////////////// OPERATION_GRAD_ELLIPSE
3218
3219
Grad_ellipse_12_0(void)3220 void Grad_ellipse_12_0(void)
3221 //
3222 // Opération : OPERATION_GRAD_ELLIPSE
3223 // Click Souris: 1 ou 2
3224 // Taille_Pile : 0
3225 //
3226 // Souris effacée: Oui
3227 {
3228 byte color;
3229
3230 Init_start_operation();
3231 Backup();
3232 Load_gradient_data(Current_gradient);
3233
3234
3235 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
3236 color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
3237
3238 Paintbrush_hidden_before_scroll=Paintbrush_hidden;
3239 Paintbrush_hidden=1;
3240
3241 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
3242 Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1);
3243
3244 if ((Config.Coords_rel) && (Menu_is_visible))
3245 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
3246
3247 Operation_push(Mouse_K);
3248 Operation_push(color);
3249 Operation_push(Paintbrush_X);
3250 Operation_push(Paintbrush_Y);
3251 Operation_push(Paintbrush_X);
3252 Operation_push(Paintbrush_Y);
3253 }
3254
3255
Grad_ellipse_12_6(void)3256 void Grad_ellipse_12_6(void)
3257 //
3258 // Opération : OPERATION_GRAD_ELLIPSE
3259 // Click Souris: 1 ou 2
3260 // Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
3261 //
3262 // Souris effacée: Non
3263 //
3264 {
3265 short tangent_x;
3266 short tangent_y;
3267 short center_x;
3268 short center_y;
3269 short color;
3270 short horizontal_radius;
3271 short vertical_radius;
3272
3273 Operation_pop(&tangent_y);
3274 Operation_pop(&tangent_x);
3275 Operation_pop(¢er_y);
3276 Operation_pop(¢er_x);
3277 Operation_pop(&color);
3278
3279 if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) )
3280 {
3281 Hide_cursor();
3282 Display_coords_rel_or_abs(center_x,center_y);
3283
3284 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
3285 {
3286 Cursor_shape=CURSOR_SHAPE_TARGET;
3287 horizontal_radius=(tangent_x>center_x)?tangent_x-center_x
3288 :center_x-tangent_x;
3289 vertical_radius =(tangent_y>center_y)?tangent_y-center_y
3290 :center_y-tangent_y;
3291 Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius);
3292
3293 horizontal_radius=(Paintbrush_X>center_x)?Paintbrush_X-center_x
3294 :center_x-Paintbrush_X;
3295 vertical_radius =(Paintbrush_Y>center_y)?Paintbrush_Y-center_y
3296 :center_y-Paintbrush_Y;
3297 Draw_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius,color);
3298 }
3299 else
3300 {
3301 Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y);
3302 Draw_empty_inscribed_ellipse_preview(center_x,center_y,Paintbrush_X,Paintbrush_Y,color);
3303 }
3304
3305 Display_cursor();
3306 }
3307
3308 Operation_push(color);
3309 Operation_push(center_x);
3310 Operation_push(center_y);
3311 Operation_push(Paintbrush_X);
3312 Operation_push(Paintbrush_Y);
3313 }
3314
3315
Grad_ellipse_0_6(void)3316 void Grad_ellipse_0_6(void)
3317 //
3318 // Opération : OPERATION_GRAD_ELLIPSE
3319 // Click Souris: 0
3320 // Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente)
3321 //
3322 // Souris effacée: Oui
3323 //
3324 {
3325 short tangent_x;
3326 short tangent_y;
3327 short center_x;
3328 short center_y;
3329 short color;
3330 short click;
3331 //short radius;
3332 short horizontal_radius;
3333 short vertical_radius;
3334
3335 Operation_pop(&tangent_y);
3336 Operation_pop(&tangent_x);
3337 Operation_pop(¢er_y);
3338 Operation_pop(¢er_x);
3339
3340 Operation_pop(&color);
3341 Operation_pop(&click);
3342
3343 if (click==LEFT_SIDE)
3344 {
3345 Operation_push(click);
3346 Operation_push(color);
3347
3348 Operation_push(center_x);
3349 Operation_push(center_y);
3350 Operation_push(tangent_x);
3351 Operation_push(tangent_y);
3352
3353 Operation_push(Paintbrush_X);
3354 Operation_push(Paintbrush_Y);
3355
3356 // On change la forme du curseur
3357 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
3358
3359 // On affiche une croix XOR au centre du cercle
3360 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
3361 Draw_curve_cross(center_x,center_y);
3362 else
3363 Draw_curve_cross((center_x+tangent_x)/2, (center_y+tangent_y)/2);
3364
3365 if (Menu_is_visible)
3366 {
3367 if (Config.Coords_rel)
3368 Print_in_menu("X: Y:",0);
3369 else
3370 Print_in_menu("X: Y: ",0);
3371 Display_coords_rel_or_abs(center_x,center_y);
3372 }
3373 }
3374 else
3375 {
3376 Paintbrush_hidden=Paintbrush_hidden_before_scroll;
3377 Cursor_shape=CURSOR_SHAPE_TARGET;
3378
3379 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
3380 {
3381 horizontal_radius=(tangent_x>center_x)?tangent_x-center_x
3382 :center_x-tangent_x;
3383 vertical_radius =(tangent_y>center_y)?tangent_y-center_y
3384 :center_y-tangent_y;
3385 Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius);
3386 Draw_filled_ellipse(center_x,center_y,horizontal_radius,vertical_radius,Back_color);
3387 }
3388 else
3389 {
3390 Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y);
3391 Draw_filled_inscribed_ellipse(center_x,center_y,tangent_x,tangent_y,Back_color);
3392 }
3393
3394 End_of_modification();
3395 if ((Config.Coords_rel) && (Menu_is_visible))
3396 {
3397 Print_in_menu("X: Y: ",0);
3398 Print_coordinates();
3399 }
3400 }
3401 }
3402
3403
Grad_ellipse_12_8(void)3404 void Grad_ellipse_12_8(void)
3405 //
3406 // Opération : OPERATION_GRAD_ELLIPSE
3407 // Click Souris: 0
3408 // Taille_Pile : 8 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente, old_x, old_y)
3409 //
3410 // Souris effacée: Oui
3411 //
3412 {
3413 short tangent_x;
3414 short tangent_y;
3415 short center_x;
3416 short center_y;
3417 short color;
3418 short horizontal_radius=0;
3419 short vertical_radius=0;
3420 short old_mouse_k;
3421
3422 Operation_stack_size-=2; // On fait sauter les 2 derniers élts de la pile
3423 Operation_pop(&tangent_y);
3424 Operation_pop(&tangent_x);
3425 Operation_pop(¢er_y);
3426 Operation_pop(¢er_x);
3427 Operation_pop(&color);
3428 Operation_pop(&old_mouse_k);
3429
3430 Hide_cursor();
3431 // On efface la croix XOR au centre de l'ellipse
3432 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
3433 {
3434 Draw_curve_cross(center_x,center_y);
3435 horizontal_radius=(tangent_x>center_x)?tangent_x-center_x
3436 :center_x-tangent_x;
3437 vertical_radius =(tangent_y>center_y)?tangent_y-center_y
3438 :center_y-tangent_y;
3439 Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius);
3440 }
3441 else
3442 {
3443 Draw_curve_cross((center_x+tangent_x)/2, (center_y+tangent_y)/2);
3444 Hide_empty_inscribed_ellipse_preview(center_x,center_y,tangent_x,tangent_y);
3445 }
3446
3447 Paintbrush_hidden=Paintbrush_hidden_before_scroll;
3448 Cursor_shape=CURSOR_SHAPE_XOR_TARGET;
3449
3450 if (Mouse_K==old_mouse_k)
3451 {
3452 if ((Selected_circle_ellipse_mode & MASK_CENTER_CORNERS) == MODE_CENTER)
3453 Draw_grad_ellipse(center_x,center_y,horizontal_radius,vertical_radius,Paintbrush_X,Paintbrush_Y);
3454 else
3455 Draw_grad_inscribed_ellipse(center_x,center_y,tangent_x,tangent_y,Paintbrush_X,Paintbrush_Y);
3456 }
3457
3458 Display_cursor();
3459 End_of_modification();
3460 Wait_end_of_click();
3461
3462 if ((Config.Coords_rel) && (Menu_is_visible))
3463 {
3464 Print_in_menu("X: Y: ",0);
3465 Print_coordinates();
3466 }
3467 }
3468
3469 /******************************
3470 * Operation_Rectangle_Degrade *
3471 ******************************/
3472
3473 // 1) tracé d'un rectangle classique avec les lignes XOR
3474 // 2) tracé d'une ligne vecteur de dégradé, comme une ligne normale
3475 // 3) dessin du dégradé
3476
3477
Grad_rectangle_12_0(void)3478 void Grad_rectangle_12_0(void)
3479 // Opération : OPERATION_GRAD_RECTANGLE
3480 // Click Souris: 1 ou 2
3481 // Taille_Pile : 0
3482 //
3483 // Souris effacée: Oui
3484
3485 // Initialisation de l'étape 1, on commence à dessiner le rectangle
3486 {
3487 Init_start_operation();
3488 Backup();
3489 Load_gradient_data(Current_gradient);
3490
3491 if ((Config.Coords_rel) && (Menu_is_visible))
3492 Print_in_menu("\035: 1 \022: 1",0);
3493 // On laisse une trace du curseur à l'écran
3494 Display_cursor();
3495
3496 if (Mouse_K==LEFT_SIDE)
3497 {
3498 Shade_table=Shade_table_left;
3499 Operation_push(Mouse_K);
3500 }
3501 else
3502 {
3503 Shade_table=Shade_table_right;
3504 Operation_push(Mouse_K);
3505 }
3506
3507 Operation_push(Paintbrush_X);
3508 Operation_push(Paintbrush_Y);
3509 Operation_push(Paintbrush_X);
3510 Operation_push(Paintbrush_Y);
3511 }
3512
3513
Grad_rectangle_12_5(void)3514 void Grad_rectangle_12_5(void)
3515 // Opération : OPERATION_GRAD_RECTANGLE
3516 // Click Souris: 1 ou 2
3517 // Taille_Pile : 5
3518 //
3519 // Souris effacée: Non
3520
3521 // Modification de la taille du rectangle
3522 {
3523 short start_x;
3524 short start_y;
3525 short old_x;
3526 short old_y;
3527 char str[5];
3528
3529 Operation_pop(&old_y);
3530 Operation_pop(&old_x);
3531
3532 if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y))
3533 {
3534 Operation_pop(&start_y);
3535 Operation_pop(&start_x);
3536
3537 if ((Config.Coords_rel) && (Menu_is_visible))
3538 {
3539 Num2str(((start_x<Paintbrush_X)?Paintbrush_X-start_x:start_x-Paintbrush_X)+1,str,4);
3540 Print_in_menu(str,2);
3541 Num2str(((start_y<Paintbrush_Y)?Paintbrush_Y-start_y:start_y-Paintbrush_Y)+1,str,4);
3542 Print_in_menu(str,11);
3543 }
3544 else
3545 Print_coordinates();
3546
3547 Operation_push(start_x);
3548 Operation_push(start_y);
3549 }
3550
3551 Operation_push(Paintbrush_X);
3552 Operation_push(Paintbrush_Y);
3553 }
3554
3555 // Start and End coordinates must be sorted
Draw_xor_rect(short start_x,short start_y,short end_x,short end_y)3556 void Draw_xor_rect(short start_x, short start_y, short end_x, short end_y)
3557 {
3558 short offset_width = 0;
3559 short offset_height = 0;
3560 short offset_left = 0;
3561 short offset_top = 0;
3562 short width = end_x-start_x;
3563 short height = end_y-start_y;
3564
3565 // Handle clipping
3566 if (end_x-Main.offset_X > Min(Main.image_width,
3567 Main.magnifier_mode?Main.separator_position:Screen_width))
3568 {
3569 offset_width = end_x - Min(Main.image_width,
3570 Main.magnifier_mode?Main.separator_position:Screen_width);
3571 }
3572
3573 if (end_y-Main.offset_Y > Min(Main.image_height, Menu_Y))
3574 offset_height = end_y - Min(Main.image_height, Menu_Y);
3575
3576 if (width == 0)
3577 {
3578 // Single line
3579 Vertical_XOR_line(start_x-Main.offset_X, start_y
3580 - Main.offset_Y, height - offset_height + 1);
3581 }
3582 else if (height == 0)
3583 {
3584 // Single line
3585 Horizontal_XOR_line(start_x-Main.offset_X,
3586 start_y - Main.offset_Y, width - offset_width + 1);
3587 }
3588 else
3589 {
3590 // Dessin dans la zone de dessin normale
3591 Horizontal_XOR_line(start_x-Main.offset_X,
3592 start_y - Main.offset_Y, width - offset_width + 1);
3593
3594 // If not, this line is out of the picture so there is no need to draw it
3595 if (offset_height == 0 || end_y - 1 > Menu_Y + Main.offset_Y)
3596 {
3597 Horizontal_XOR_line(start_x - Main.offset_X, end_y
3598 - Main.offset_Y, width - offset_width + 1);
3599 }
3600
3601 if (height > offset_height + 2)
3602 {
3603 Vertical_XOR_line(start_x-Main.offset_X, start_y
3604 - Main.offset_Y + 1, height - offset_height - 1);
3605
3606 if (offset_width == 0)
3607 {
3608 Vertical_XOR_line(end_x - Main.offset_X, start_y
3609 - Main.offset_Y + 1, height - offset_height - 1);
3610 }
3611 }
3612 }
3613
3614 Update_rect(start_x - Main.offset_X, start_y - Main.offset_Y,
3615 width + 1 - offset_width, height + 1 - offset_height);
3616
3617 // Dessin dans la zone zoomée
3618 if (Main.magnifier_mode && start_x <= Limit_right_zoom
3619 && end_x > Limit_left_zoom
3620 && start_y <= Limit_bottom_zoom
3621 && end_y > Limit_top_zoom )
3622 {
3623 offset_width = 0;
3624 offset_height = 0;
3625
3626 if (start_x<Limit_left_zoom) // On dépasse du zoom à gauche
3627 {
3628 offset_width += Limit_left_zoom - start_x;
3629 offset_left = Limit_left_zoom;
3630 }
3631
3632 if(end_x>Limit_right_zoom) // On dépasse du zoom à droite
3633 offset_width += end_x - Limit_right_zoom;
3634
3635 if(start_y<Limit_top_zoom) // On dépasse du zoom en haut
3636 {
3637 offset_height += Limit_top_zoom - start_y;
3638 offset_top = Limit_top_zoom;
3639 }
3640
3641 if(end_y>Limit_bottom_zoom) // On dépasse du zoom en bas
3642 offset_height += end_y - Limit_bottom_zoom;
3643
3644 if(width > offset_width)
3645 {
3646 if(offset_top==0) // La ligne du haut est visible
3647 Horizontal_XOR_line_zoom(offset_left>0?offset_left:start_x,start_y,width-offset_width+1);
3648
3649 if(height!=0 && end_y<=Limit_bottom_zoom) // La ligne du bas est visible
3650 Horizontal_XOR_line_zoom(offset_left>0?offset_left:start_x,end_y,width-offset_width+1);
3651 }
3652 if (width==0 && height!=0 && height > offset_height && offset_left==0)
3653 {
3654 // Single vertical line
3655 Vertical_XOR_line_zoom(start_x,offset_top!=0?offset_top:start_y,height-offset_height);
3656 }
3657 else
3658 {
3659 if(height > offset_height + 2)
3660 {
3661 if(offset_left==0) // La ligne de gauche est visible
3662 Vertical_XOR_line_zoom(start_x,offset_top!=0?offset_top:(start_y+1),height-offset_height-(offset_top==0)+(end_y>Limit_bottom_zoom));
3663
3664 if(end_x<=Limit_right_zoom) // La ligne de droite est visible
3665 Vertical_XOR_line_zoom(end_x,offset_top!=0?offset_top:(start_y+1),height-offset_height-(offset_top==0)+(end_y>Limit_bottom_zoom));
3666 }
3667 }
3668 }
3669 }
Grad_rectangle_0_5(void)3670 void Grad_rectangle_0_5(void)
3671 // OPERATION_GRAD_RECTANGLE
3672 // click souris 0
3673 // Taile pile : 5
3674 //
3675 // Souris effacée : non
3676
3677 // Le rectangle est en place, maintenant il faut tracer le vecteur de dégradé,
3678 // on doit donc attendre que l'utilisateur clique quelque part
3679 // On stocke tout de suite les coordonnées du pinceau comme ça on change d'état et on passe à la suite
3680 {
3681 // !!! Cette fonction remet start_x start_y end_x end_y dans la pile à la fin donc il ne faut pas les modifier ! (sauf éventuellement un tri)
3682 short start_x;
3683 short start_y;
3684 short end_x;
3685 short end_y;
3686
3687 // Tracé propre du rectangle
3688 Operation_pop(&end_y);
3689 Operation_pop(&end_x);
3690 Operation_pop(&start_y);
3691 Operation_pop(&start_x);
3692
3693 // This trick will erase the large crosshair at original position,
3694 // in normal and zoomed views.
3695 Paintbrush_X = start_x;
3696 Paintbrush_Y = start_y;
3697
3698 if (start_x>end_x)
3699 SWAP_SHORTS(start_x, end_x)
3700
3701 if (start_y>end_y)
3702 SWAP_SHORTS(start_y, end_y)
3703
3704 Hide_cursor();
3705
3706 // Check if the rectangle is not fully outside the picture
3707 if (start_x > Main.image_width // Rectangle at right of picture
3708 || start_y > Main.image_height // Rectangle below picture
3709 || start_y - 1 - Main.offset_Y > Menu_Y ) // Rectangle below viewport
3710 {
3711 Operation_pop(&end_y); // reset the stack
3712 return; // cancel the operation
3713 }
3714 Draw_xor_rect(start_x, start_y, end_x, end_y);
3715
3716 Operation_push(start_x);
3717 Operation_push(start_y);
3718 Operation_push(end_x);
3719 Operation_push(end_y);
3720
3721 // On ajoute des trucs dans la pile pour forcer le passage à l'étape suivante
3722 Operation_push(end_x);
3723 Operation_push(end_y);
3724 }
3725
Grad_rectangle_0_7(void)3726 void Grad_rectangle_0_7(void)
3727 // OPERATION_GRAD_RECTANGLE
3728 // click souris 0
3729 // Taile pile : 5
3730 //
3731 // Souris effacée : non
3732
3733 // On continue à attendre que l'utilisateur clique en gardant les coords à jour
3734 {
3735 Operation_stack_size -= 2;
3736 Print_coordinates();
3737 Operation_push(Paintbrush_X);
3738 Operation_push(Paintbrush_Y);
3739 }
3740
Grad_rectangle_12_7(void)3741 void Grad_rectangle_12_7(void)
3742 // Opération : OPERATION_GRAD_RECTANGLE
3743 // Click Souris: 1 ou 2
3744 // Taille_Pile : 7
3745 //
3746 // Souris effacée: Oui
3747
3748 // Début du tracé du vecteur (premier clic)
3749 // On garde les anciennes coordonnées dans la pile, et on ajoute les nouvelles par dessus
3750
3751 // Si l'utilisateur utilise le mauvais bouton, on annule le tracé. Mais ça nous oblige à vider toute la pile pour vérifier :(
3752 {
3753 short start_x,end_x,start_y,end_y,vax,vay,click;
3754
3755 Operation_pop(&vay);
3756 Operation_pop(&vax);
3757 Operation_pop(&end_y);
3758 Operation_pop(&end_x);
3759 Operation_pop(&start_y);
3760 Operation_pop(&start_x);
3761 Operation_pop(&click);
3762
3763
3764 if(click==Mouse_K)
3765 {
3766 Operation_push(click);
3767 Operation_push(start_x);
3768 Operation_push(start_y);
3769 Operation_push(end_x);
3770 Operation_push(end_y);
3771 Operation_push(vax);
3772 Operation_push(vay);
3773 Operation_push(Paintbrush_X);
3774 Operation_push(Paintbrush_Y);
3775
3776 }
3777 else
3778 {
3779 // Mauvais bouton > anulation de l'opération.
3780 // On a déjà vidé la pile, il reste à effacer le rectangle XOR
3781 Draw_xor_rect(start_x, start_y, end_x, end_y);
3782 }
3783 }
3784
Grad_rectangle_12_9(void)3785 void Grad_rectangle_12_9(void)
3786 // Opération : OPERATION_GRAD_RECTANGLE
3787 // Click Souris: 1
3788 // Taille_Pile : 9
3789 //
3790 // Souris effacée: Oui
3791
3792 // Poursuite du tracé du vecteur (déplacement de la souris en gardant le curseur appuyé)
3793 {
3794 short start_x;
3795 short start_y;
3796 short end_x;
3797 short end_y;
3798 short cursor_x;
3799 short cursor_y;
3800
3801 Operation_pop(&end_y);
3802 Operation_pop(&end_x);
3803 Operation_pop(&start_y);
3804 Operation_pop(&start_x);
3805
3806 cursor_x = Paintbrush_X;
3807 cursor_y = Paintbrush_Y;
3808 // On corrige les coordonnées de la ligne si la touche shift est appuyée...
3809 if(Get_Key_modifiers() & GFX2_MOD_SHIFT)
3810 Clamp_coordinates_regular_angle(start_x,start_y,&cursor_x,&cursor_y);
3811
3812 if ((cursor_x!=end_x) || (cursor_y!=end_y))
3813 {
3814 Display_coords_rel_or_abs(start_x,start_y);
3815
3816 Draw_line_preview_xor(start_x,start_y,end_x,end_y,0);
3817 Draw_line_preview_xor(start_x,start_y,cursor_x,cursor_y,0);
3818
3819 }
3820
3821
3822 Operation_push(start_x);
3823 Operation_push(start_y);
3824 Operation_push(cursor_x);
3825 Operation_push(cursor_y);
3826 }
3827
Grad_rectangle_0_9(void)3828 void Grad_rectangle_0_9(void)
3829 // Opération : OPERATION_GRAD_RECTANGLE
3830 // Click Souris: 0
3831 // Taille_Pile : 9
3832 //
3833 // Souris effacée: Oui
3834
3835 // Ouf, fini ! on dessine enfin le rectangle avec son dégradé
3836 {
3837 short rect_start_x;
3838 short rect_start_y;
3839 short rect_end_x;
3840 short rect_end_y;
3841
3842 short vector_start_x;
3843 short vector_start_y;
3844 short vector_end_x;
3845 short vector_end_y;
3846
3847 Operation_pop(&vector_end_y);
3848 Operation_pop(&vector_end_x);
3849 Operation_pop(&vector_start_y);
3850 Operation_pop(&vector_start_x);
3851 Operation_pop(&rect_end_y);
3852 Operation_pop(&rect_end_x);
3853 Operation_pop(&rect_start_y);
3854 Operation_pop(&rect_start_x);
3855 Operation_stack_size--;
3856
3857 Hide_cursor();
3858 // Maintenant on efface tout le bazar temporaire : rectangle et ligne XOR
3859 Draw_xor_rect(rect_start_x, rect_start_y, rect_end_x, rect_end_y);
3860 Hide_line_preview(vector_start_x,vector_start_y,vector_end_x,vector_end_y);
3861
3862 // Et enfin on trace le rectangle avec le dégradé dedans !
3863 if (vector_end_x==vector_start_x && vector_end_y==vector_start_y)
3864 {
3865 // Vecteur nul > pas de rectangle tracé
3866 }
3867 else
3868 {
3869 Draw_grad_rectangle(rect_start_x,rect_start_y,rect_end_x,rect_end_y,vector_start_x,vector_start_y,vector_end_x,vector_end_y);
3870 }
3871 Display_cursor();
3872 End_of_modification();
3873 Wait_end_of_click();
3874
3875 if ((Config.Coords_rel) && (Menu_is_visible))
3876 {
3877 Print_in_menu("X: Y: ",0);
3878 Print_coordinates();
3879 }
3880 }
3881 /////////////////////////////////////////////////// OPERATION_CENTERED_LINES
3882
3883
Centered_lines_12_0(void)3884 void Centered_lines_12_0(void)
3885 // Opération : OPERATION_CENTERED_LINES
3886 // Click Souris: 1 ou 2
3887 // Taille_Pile : 0
3888 //
3889 // Souris effacée: Oui
3890 {
3891 if (Rightclick_colorpick(0))
3892 return;
3893
3894 Init_start_operation();
3895 Backup();
3896 Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
3897
3898 if ((Config.Coords_rel) && (Menu_is_visible))
3899 Print_in_menu("X:\xb1 0 Y:\xb1 0",0);
3900
3901 Operation_push(Mouse_K);
3902 Operation_push(Paintbrush_X);
3903 Operation_push(Paintbrush_Y);
3904 }
3905
3906
Centered_lines_12_3(void)3907 void Centered_lines_12_3(void)
3908 // Opération : OPERATION_CENTERED_LINES
3909 // Click Souris: 1 ou 2
3910 // Taille_Pile : 3
3911 //
3912 // Souris effacée: Non
3913 {
3914 short start_x;
3915 short start_y;
3916
3917 Operation_pop(&start_y);
3918 Operation_pop(&start_x);
3919 Operation_push(Paintbrush_X);
3920 Operation_push(Paintbrush_Y);
3921 }
3922
3923
Centered_lines_0_3(void)3924 void Centered_lines_0_3(void)
3925 // Opération : OPERATION_CENTERED_LINES
3926 // Click Souris: 0
3927 // Taille_Pile : 3
3928 //
3929 // Souris effacée: Oui
3930 {
3931 short start_x;
3932 short start_y;
3933 short Button;
3934 short color;
3935
3936 Operation_pop(&start_y);
3937 Operation_pop(&start_x);
3938 Operation_pop(&Button);
3939
3940 color=(Button==LEFT_SIDE)?Fore_color:Back_color;
3941
3942 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
3943 Paintbrush_shape_before_operation=Paintbrush_shape;
3944 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
3945
3946 Operation_push(Button);
3947 Operation_push(Paintbrush_X); // Nouveau début X
3948 Operation_push(Paintbrush_Y); // Nouveau début Y
3949 Operation_push(Paintbrush_X); // Nouvelle dernière fin X
3950 Operation_push(Paintbrush_Y); // Nouvelle dernière fin Y
3951 Operation_push(Paintbrush_X); // Nouvelle dernière position X
3952 Operation_push(Paintbrush_Y); // Nouvelle dernière position Y
3953 }
3954
3955
Centered_lines_12_7(void)3956 void Centered_lines_12_7(void)
3957 // Opération : OPERATION_CENTERED_LINES
3958 // Click Souris: 1 ou 2
3959 // Taille_Pile : 7
3960 //
3961 // Souris effacée: Non
3962 {
3963 short Button;
3964 short start_x;
3965 short start_y;
3966 short end_x;
3967 short end_y;
3968 short last_x;
3969 short last_y;
3970 short color;
3971
3972 Operation_pop(&last_y);
3973 Operation_pop(&last_x);
3974 Operation_pop(&end_y);
3975 Operation_pop(&end_x);
3976 Operation_pop(&start_y);
3977 Operation_pop(&start_x);
3978 Operation_pop(&Button);
3979
3980 if (Mouse_K==Button)
3981 {
3982 if ( (end_x!=Paintbrush_X) || (end_y!=Paintbrush_Y) ||
3983 (last_x!=Paintbrush_X) || (last_y!=Paintbrush_Y) )
3984 {
3985 Hide_cursor();
3986
3987 color=(Button==LEFT_SIDE)?Fore_color:Back_color;
3988
3989 Paintbrush_shape=Paintbrush_shape_before_operation;
3990
3991 Pixel_figure_preview_auto (start_x,start_y);
3992 Hide_line_preview (start_x,start_y,last_x,last_y);
3993
3994 Smear_start=1;
3995 Draw_paintbrush (start_x,start_y,color);
3996 Draw_line_permanent(start_x,start_y,Paintbrush_X,Paintbrush_Y,color);
3997
3998 Paintbrush_shape=PAINTBRUSH_SHAPE_POINT;
3999 Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color);
4000 Draw_line_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y,color);
4001
4002 Display_cursor();
4003 }
4004
4005 Operation_push(Button);
4006 Operation_push(start_x);
4007 Operation_push(start_y);
4008 Operation_push(Paintbrush_X);
4009 Operation_push(Paintbrush_Y);
4010 Operation_push(Paintbrush_X);
4011 Operation_push(Paintbrush_Y);
4012 }
4013 else
4014 {
4015 Hide_cursor();
4016
4017 Paintbrush_shape=Paintbrush_shape_before_operation;
4018
4019 Pixel_figure_preview_auto (start_x,start_y);
4020 Hide_line_preview (start_x,start_y,last_x,last_y);
4021
4022 if ( (Config.Coords_rel) && (Menu_is_visible) )
4023 {
4024 Print_in_menu("X: Y: ",0);
4025 Print_coordinates();
4026 }
4027
4028 Display_cursor();
4029 End_of_modification();
4030 Wait_end_of_click();
4031 }
4032 }
4033
4034
Centered_lines_0_7(void)4035 void Centered_lines_0_7(void)
4036 // Opération : OPERATION_CENTERED_LINES
4037 // Click Souris: 0
4038 // Taille_Pile : 7
4039 //
4040 // Souris effacée: Non
4041 {
4042 short Button;
4043 short start_x;
4044 short start_y;
4045 short end_x;
4046 short end_y;
4047 short last_x;
4048 short last_y;
4049 short color;
4050
4051 Operation_pop(&last_y);
4052 Operation_pop(&last_x);
4053 Operation_pop(&end_y);
4054 Operation_pop(&end_x);
4055
4056 if ((Paintbrush_X!=last_x) || (Paintbrush_Y!=last_y))
4057 {
4058 Hide_cursor();
4059 Operation_pop(&start_y);
4060 Operation_pop(&start_x);
4061 Operation_pop(&Button);
4062
4063 color=(Button==LEFT_SIDE)?Fore_color:Back_color;
4064
4065 Display_coords_rel_or_abs(start_x,start_y);
4066
4067 Hide_line_preview(start_x,start_y,last_x,last_y);
4068
4069 Pixel_figure_preview(start_x,start_y,color);
4070 Draw_line_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y,color);
4071
4072 Operation_push(Button);
4073 Operation_push(start_x);
4074 Operation_push(start_y);
4075 Display_cursor();
4076 }
4077
4078 Operation_push(end_x);
4079 Operation_push(end_y);
4080 Operation_push(Paintbrush_X);
4081 Operation_push(Paintbrush_Y);
4082 }
4083
4084 ///////////////////////////////////////////////////////////// OPERATION_PAN_VIEW
4085
Pan_view_0_0(void)4086 void Pan_view_0_0(void)
4087 // Opération : OPERATION_PAN_VIEW
4088 // Click Souris: 0
4089 // Taille_Pile : 0
4090 //
4091 // Souris effacée: Non
4092 {
4093 if (Pan_shortcut_pressed)
4094 {
4095 Print_coordinates();
4096 }
4097 else
4098 {
4099 // End of operation, return to previous
4100 Hide_cursor();
4101 Start_operation_stack(Operation_before_pan);
4102 Display_cursor();
4103 }
4104 }
4105
Pan_view_12_0(void)4106 void Pan_view_12_0(void)
4107 // Opération : OPERATION_PAN_VIEW
4108 // Click Souris: 1 ou 2
4109 // Taille_Pile : 0
4110 //
4111 // Souris effacée: Non
4112
4113 // First time the user clicks
4114 {
4115 Init_start_operation();
4116
4117 Operation_push(Paintbrush_X);
4118 Operation_push(Paintbrush_Y);
4119 }
4120
Pan_view_12_2(void)4121 void Pan_view_12_2(void)
4122 // Opération : OPERATION_PAN_VIEW
4123 // Click Souris: 1 ou 2
4124 // Taille_Pile : 2
4125 //
4126 // Souris effacée: Non
4127
4128 // While dragging view
4129 {
4130 short start_x;
4131 short start_y;
4132
4133 Operation_pop(&start_y);
4134 Operation_pop(&start_x);
4135
4136 if (Paintbrush_X!=start_x || Paintbrush_Y!=start_y)
4137 {
4138 // User moved
4139 if (Main.magnifier_mode)
4140 Scroll_magnifier(start_x-Paintbrush_X,start_y-Paintbrush_Y);
4141 else
4142 Scroll_screen(start_x-Paintbrush_X,start_y-Paintbrush_Y);
4143 }
4144 // The "scroll" functions have actualized the Paintbrush_X and Y
4145 if (Paintbrush_X!=start_x || Paintbrush_Y!=start_y)
4146 {
4147 Print_coordinates();
4148 }
4149 Operation_push(Paintbrush_X);
4150 Operation_push(Paintbrush_Y);
4151 }
4152
Pan_view_0_2(void)4153 void Pan_view_0_2(void)
4154 // Opération : OPERATION_PAN_VIEW
4155 // Click Souris: 0
4156 // Taille_Pile : 2
4157 //
4158 // Souris effacée: Non
4159
4160 // When releasing after dragging
4161 {
4162 short start_x;
4163 short start_y;
4164
4165 Operation_pop(&start_y);
4166 Operation_pop(&start_x);
4167
4168 if (!Pan_shortcut_pressed)
4169 {
4170 // End of operation, return to previous
4171 Hide_cursor();
4172 Start_operation_stack(Operation_before_pan);
4173 Display_cursor();
4174 }
4175 }
4176