/* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Franck Charlet Copyright 2007-2008 Adrien Destugues Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Grafx2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. Grafx2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Grafx2; if not, see ******************************************************************************** Graphical interface management functions (windows, menu, cursor) */ #include #include // strncpy() strlen() #include "windows.h" #include "global.h" #include "graph.h" #include "engine.h" #include "misc.h" #include "sdlscreen.h" #include "errors.h" // L'encapsulation tente une percée...ou un dernier combat. // Nombre de cellules réel dans la palette du menu word Menu_cells_X; word Palette_cells_X() { return Menu_cells_X; } word Menu_cells_Y; word Palette_cells_Y() { return Menu_cells_Y; } // Affichage d'un pixel dans le menu (le menu doit être visible) void Pixel_in_toolbar(word x,word y,byte color) { Block(x*Menu_factor_X,(y*Menu_factor_Y)+Menu_Y,Menu_factor_X,Menu_factor_Y,color); } // Affichage d'un pixel dans la fenêtre (la fenêtre doit être visible) void Pixel_in_window(word x,word y,byte color) { Block((x*Menu_factor_X)+Window_pos_X,(y*Menu_factor_Y)+Window_pos_Y,Menu_factor_X,Menu_factor_Y,color); } // Affichage d'un rectangle dans la fenêtre (la fenêtre doit être visible) void Window_rectangle(word x_pos,word y_pos,word width,word height,byte color) { Block((x_pos*Menu_factor_X)+Window_pos_X,(y_pos*Menu_factor_Y)+Window_pos_Y,width*Menu_factor_X,height*Menu_factor_Y,color); } // -- Affichages de différents cadres dans une fenêtre ----------------------- // -- Frame général avec couleurs paramètrables -- void Window_display_frame_generic(word x_pos,word y_pos,word width,word height, byte color_tl,byte color_br,byte color_s,byte color_tlc,byte color_brc) // Paramètres de couleurs: // color_tl =Bords Haut et Gauche // color_br =Bords Bas et Droite // color_s =Coins Haut-Droite et Bas-Gauche // color_tlc=Coin Haut-Gauche // color_brc=Coin Bas-Droite { // Bord haut (sans les extrémités) Block(Window_pos_X+((x_pos+1)*Menu_factor_X), Window_pos_Y+(y_pos*Menu_factor_Y), (width-2)*Menu_factor_X,Menu_factor_Y,color_tl); // Bord bas (sans les extrémités) Block(Window_pos_X+((x_pos+1)*Menu_factor_X), Window_pos_Y+((y_pos+height-1)*Menu_factor_Y), (width-2)*Menu_factor_X,Menu_factor_Y,color_br); // Bord gauche (sans les extrémités) Block(Window_pos_X+(x_pos*Menu_factor_X), Window_pos_Y+((y_pos+1)*Menu_factor_Y), Menu_factor_X,(height-2)*Menu_factor_Y,color_tl); // Bord droite (sans les extrémités) Block(Window_pos_X+((x_pos+width-1)*Menu_factor_X), Window_pos_Y+((y_pos+1)*Menu_factor_Y), Menu_factor_X,(height-2)*Menu_factor_Y,color_br); // Coin haut gauche Pixel_in_window(x_pos,y_pos,color_tlc); // Coin haut droite Pixel_in_window(x_pos+width-1,y_pos,color_s); // Coin bas droite Pixel_in_window(x_pos+width-1,y_pos+height-1,color_brc); // Coin bas gauche Pixel_in_window(x_pos,y_pos+height-1,color_s); } // -- Frame dont tout le contour est d'une seule couleur -- void Window_display_frame_mono(word x_pos,word y_pos,word width,word height,byte color) { Window_display_frame_generic(x_pos,y_pos,width,height,color,color,color,color,color); } // -- Frame creux: foncé en haut-gauche et clair en bas-droite -- void Window_display_frame_in(word x_pos,word y_pos,word width,word height) { Window_display_frame_generic(x_pos,y_pos,width,height,MC_Dark,MC_White,MC_Light,MC_Dark,MC_White); } // -- Frame bombé: clair en haut-gauche et foncé en bas-droite -- void Window_display_frame_out(word x_pos,word y_pos,word width,word height) { Window_display_frame_generic(x_pos,y_pos,width,height,MC_White,MC_Dark,MC_Light,MC_White,MC_Dark); } // -- Frame de séparation: un cadre bombé dans un cadre creux (3D!!!) -- void Window_display_frame(word x_pos,word y_pos,word width,word height) { Window_display_frame_in(x_pos,y_pos,width,height); Window_display_frame_out(x_pos+1,y_pos+1,width-2,height-2); } //-- Affichages relatifs à la palette dans le menu --------------------------- // -- Affichage des couleurs courante (fore/back) de pinceau dans le menu -- void Display_foreback(void) { if (Menu_is_visible) { Block((MENU_WIDTH-17)*Menu_factor_X,Menu_Y+Menu_factor_Y,Menu_factor_X<<4,Menu_factor_Y*7,Back_color); Block((MENU_WIDTH-13)*Menu_factor_X,Menu_Y+(Menu_factor_Y<<1),Menu_factor_X<<3,Menu_factor_Y*5,Fore_color); Update_rect((MENU_WIDTH-17)*Menu_factor_X,Menu_Y+Menu_factor_Y,Menu_factor_X<<4,Menu_factor_Y*7); } } /*! Get the top left corner for the palette cell of a color @param index Index of the color, starting at 0 for the top left one. Limited to Menu_cells_X/Menu_cells_Y. */ word Palette_cell_X(byte index) { if (Config.Palette_vertical) { return (MENU_WIDTH+1+((index-First_color_in_palette)%Menu_cells_X)*Menu_palette_cell_width)*Menu_factor_X; } else { return (MENU_WIDTH+1+((index-First_color_in_palette)/Menu_cells_Y)*Menu_palette_cell_width)*Menu_factor_X; } } /*! Get the top left corner for the palette cell of a color @param index Index of the color, starting at 0 for the top left one. Limited to Menu_cells_X/Menu_cells_Y. */ word Palette_cell_Y(byte index) { if (Config.Palette_vertical) { return Menu_Y+((2+(((index-First_color_in_palette)/Menu_cells_X)*(32/Menu_cells_Y)))*Menu_factor_Y); } else { return Menu_Y+((2+(((index-First_color_in_palette)%Menu_cells_Y)*(32/Menu_cells_Y)))*Menu_factor_Y); } } /// /// Redraw the cell in the menu palette for ::Fore_color. /// This function checks bounds, it won't draw anything if Fore_color is not visible. /// @param color: Pass MC_White to mark the color with a frame, MC_Black to unmark it. /// @param id:Color number to frame void Frame_menu_color(byte id, byte color) { word start_x,start_y,end_x,end_y; word index; word cell_height=32/Menu_cells_Y; if ((id>=First_color_in_palette) && (id=First_color_in_palette+Menu_cells_X*Menu_cells_Y) First_color_in_palette+=cells; } if (old_color!=First_color_in_palette) Display_menu_palette(); } void Change_palette_cells() { // On initialise avec la configuration de l'utilisateur Menu_cells_X=Config.Palette_cells_X; Menu_cells_Y=Config.Palette_cells_Y; // Mais on sait jamais if (Menu_cells_X<1) Menu_cells_X=1; if (Menu_cells_Y<1) Menu_cells_Y=1; while (1) { Menu_palette_cell_width = ((Screen_width/Menu_factor_X)-(MENU_WIDTH+2)) / Menu_cells_X; // Si ça tient, c'est bon. Sinon, on retente avec une colonne de moins if (Menu_palette_cell_width>2) break; Menu_cells_X--; } // Cale First_color_in_palette sur un multiple du nombre de cellules (arrondi inférieur) if (Config.Palette_vertical) First_color_in_palette=First_color_in_palette/Menu_cells_X*Menu_cells_X; else First_color_in_palette=First_color_in_palette/Menu_cells_Y*Menu_cells_Y; // Si le nombre de cellules a beaucoup augmenté et qu'on était près de // la fin, il faut reculer First_color_in_palette pour montrer plein // de couleurs. if ((int)First_color_in_palette+(Menu_cells_Y)*Menu_cells_X*2>=256) First_color_in_palette=255/Menu_cells_Y*Menu_cells_Y-(Menu_cells_X-1)*Menu_cells_Y; // Mise à jour de la taille du bouton dans le menu. C'est pour pas que // la bordure noire soit active. Buttons_Pool[BUTTON_CHOOSE_COL].Width=(Menu_palette_cell_width*Menu_cells_X)-1; Buttons_Pool[BUTTON_CHOOSE_COL].Height=32/Menu_cells_Y*Menu_cells_Y-1; } // Retrouve la couleur sur laquelle pointe le curseur souris. // Cette fonction suppose qu'on a déja vérifié que le curseur est dans // la zone rectangulaire du BUTTON_CHOOSE_COL // La fonction renvoie -1 si on est "trop à gauche" (pas possible) // ou après la couleur 255 (Ce qui peut arriver si la palette est affichée // avec un nombre de lignes qui n'est pas une puissance de deux.) int Pick_color_in_palette() { int color; int line; int column; line=(((Mouse_Y-Menu_Y)/Menu_factor_Y)-2)/(32/Menu_cells_Y); column=(((Mouse_X/Menu_factor_X)-(MENU_WIDTH+1))/Menu_palette_cell_width); if (Config.Palette_vertical) { color=First_color_in_palette+line*Menu_cells_X+column; } else { color=First_color_in_palette+line+column*Menu_cells_Y; } if (color<0 || color>255) return -1; return color; } // -- Afficher tout le menu -- void Display_menu(void) { word x_pos; word y_pos; char str[4]; if (Menu_is_visible) { // Affichage du sprite du menu for (y_pos=0;y_pos=Main_X_zoom) )) { // Dans ces deux cas, on met dans la barre les XY courant, même s'il y a des chances que ça soit recouvert si la souris est sur un bouton (trop chiant à vérifier) if ( (Current_operation!=OPERATION_COLORPICK) && (Current_operation!=OPERATION_REPLACE) ) Print_in_menu("X: Y: ",0); else { Print_in_menu("X: Y: ( )",0); Num2str(Colorpicker_color,str,3); Print_in_menu(str,20); Print_general(170*Menu_factor_X,Menu_status_Y," ",0,Colorpicker_color); } Print_coordinates(); } Print_filename(); } Update_rect(0,Menu_Y,Screen_width,MENU_HEIGHT*Menu_factor_Y); // on met toute la largur à jour, ça inclut la palette et la zone d'état avec le nom du fichier } } // -- Affichage de texte ----------------------------------------------------- // -- Afficher une chaîne n'importe où à l'écran -- void Print_general(short x,short y,const char * str,byte text_color,byte background_color) { word index; int x_pos; int y_pos; byte *font_pixel; short real_x; short real_y; byte repeat_menu_x_factor; byte repeat_menu_y_factor; real_y=y; for (y_pos=0;y_pos<8<<3;y_pos+=1<<3) { real_x=0; // Position dans le buffer for (index=0;str[index]!='\0';index++) { // Pointeur sur le premier pixel du caractère font_pixel=Menu_font+(((unsigned char)str[index])<<6); for (x_pos=0;x_pos<8;x_pos+=1) for (repeat_menu_x_factor=0;repeat_menu_x_factor size) { display_string[size-1]=ELLIPSIS_CHARACTER; } Print_in_window(x, y, display_string, text_color, background_color); } // -- Afficher une chaîne dans une fenêtre -- void Print_in_window(short x,short y,const char * str,byte text_color,byte background_color) { Print_general((x*Menu_factor_X)+Window_pos_X, (y*Menu_factor_Y)+Window_pos_Y, str,text_color,background_color); Update_rect(x*Menu_factor_X+Window_pos_X,y*Menu_factor_Y+Window_pos_Y,8*Menu_factor_X*strlen(str),8*Menu_factor_Y); } // -- Afficher une chaîne dans le menu -- void Print_in_menu(const char * str, short position) { Print_general((18+(position<<3))*Menu_factor_X,Menu_status_Y,str,MC_Black,MC_Light); Update_rect((18+(position<<3))*Menu_factor_X,Menu_status_Y,strlen(str)*8*Menu_factor_X,8*Menu_factor_Y); } // -- Afficher les coordonnées du pinceau dans le menu -- // Note : cette fonction n'affiche que les chiffres, pas les X: Y: qui sont dans la gestion principale, car elle est apellée très souvent. void Print_coordinates(void) { char temp[5]; if (Menu_is_visible && !Cursor_in_menu) { if ( (Current_operation==OPERATION_COLORPICK) || (Current_operation==OPERATION_REPLACE) ) { if ( (Paintbrush_X>=0) && (Paintbrush_Y>=0) && (Paintbrush_X12) { display_name[11]=ELLIPSIS_CHARACTER; name_size = 12; } Block(Screen_width-96*Menu_factor_X, Menu_status_Y,Menu_factor_X*96,Menu_factor_Y<<3,MC_Light); Print_general(Screen_width-name_size*8*Menu_factor_X,Menu_status_Y,display_name,MC_Black,MC_Light); } } // Fonction d'affichage d'une chaine numérique avec une fonte très fine // Spécialisée pour les compteurs RGB void Print_counter(short x,short y,const char * str,byte text_color,byte background_color) { // Macros pour écrire des litteraux binaires. // Ex: Ob(11110000) == 0xF0 #define Ob(x) ((unsigned)Ob_(0 ## x ## uL)) #define Ob_(x) ((x & 1) | (x >> 2 & 2) | (x >> 4 & 4) | (x >> 6 & 8) | \ (x >> 8 & 16) | (x >> 10 & 32) | (x >> 12 & 64) | (x >> 14 & 128)) byte thin_font[14][8] = { { // 0 Ob(00011100), Ob(00110110), Ob(00110110), Ob(00110110), Ob(00110110), Ob(00110110), Ob(00110110), Ob(00011100) }, { // 1 Ob(00001100), Ob(00011100), Ob(00111100), Ob(00001100), Ob(00001100), Ob(00001100), Ob(00001100), Ob(00001100) }, { // 2 Ob(00011100), Ob(00110110), Ob(00000110), Ob(00000110), Ob(00000110), Ob(00001100), Ob(00011000), Ob(00111110) }, { // 3 Ob(00011100), Ob(00110110), Ob(00000110), Ob(00001100), Ob(00000110), Ob(00000110), Ob(00110110), Ob(00011100) }, { // 4 Ob(00001100), Ob(00001100), Ob(00011000), Ob(00011000), Ob(00110000), Ob(00110100), Ob(00111110), Ob(00000100) }, { // 5 Ob(00111110), Ob(00110000), Ob(00110000), Ob(00111100), Ob(00000110), Ob(00000110), Ob(00110110), Ob(00011100) }, { // 6 Ob(00011100), Ob(00110110), Ob(00110000), Ob(00111100), Ob(00110110), Ob(00110110), Ob(00110110), Ob(00011100) }, { // 7 Ob(00111110), Ob(00000110), Ob(00000110), Ob(00001100), Ob(00011000), Ob(00011000), Ob(00011000), Ob(00011000) }, { // 8 Ob(00011100), Ob(00110110), Ob(00110110), Ob(00011100), Ob(00110110), Ob(00110110), Ob(00110110), Ob(00011100) }, { // 9 Ob(00011100), Ob(00110110), Ob(00110110), Ob(00011110), Ob(00000110), Ob(00000110), Ob(00110110), Ob(00011100) }, { // (espace) Ob(00000000), Ob(00000000), Ob(00000000), Ob(00000000), Ob(00000000), Ob(00000000), Ob(00000000), Ob(00000000) }, { // + Ob(00000000), Ob(00001000), Ob(00001000), Ob(00111110), Ob(00001000), Ob(00001000), Ob(00000000), Ob(00000000) }, { // - Ob(00000000), Ob(00000000), Ob(00000000), Ob(00111110), Ob(00000000), Ob(00000000), Ob(00000000), Ob(00000000) }, { // +- Ob(00001000), Ob(00001000), Ob(00111110), Ob(00001000), Ob(00001000), Ob(00000000), Ob(00111110), Ob(00000000) } }; word index; short x_pos; short y_pos; for (index=0;str[index]!='\0';index++) { int char_number; switch(str[index]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': char_number=str[index]-'0'; break; case ' ': default: char_number=10; break; case '+': char_number=11; break; case '-': char_number=12; break; case '±': char_number=13; break; } for (y_pos=0;y_pos<8;y_pos++) { for (x_pos=0;x_pos<6;x_pos++) { byte color = (thin_font[char_number][y_pos] & (1 << (6-x_pos))) ? text_color:background_color; Pixel_in_window(x+(index*6+x_pos),y+y_pos,color); } } } Update_rect(Window_pos_X+x*Menu_factor_X,Window_pos_Y+y*Menu_factor_Y,strlen(str)*Menu_factor_X*6,8*Menu_factor_Y); } //---- Fenêtre demandant de confirmer une action et renvoyant la réponse ----- byte Confirmation_box(char * message) { short clicked_button; word window_width; window_width=(strlen(message)<<3)+20; if (window_width<120) window_width=120; Open_window(window_width,60,"Confirmation"); Print_in_window((window_width>>1)-(strlen(message)<<2),20,message,MC_Black,MC_Light); Window_set_normal_button((window_width/3)-20 ,37,40,14,"Yes",1,1,SDLK_y); // 1 Window_set_normal_button(((window_width<<1)/3)-20,37,40,14,"No" ,1,1,SDLK_n); // 2 Update_rect(Window_pos_X,Window_pos_Y,Menu_factor_X*window_width,Menu_factor_Y*60); Display_cursor(); do { clicked_button=Window_clicked_button(); if (Key==SDLK_RETURN) clicked_button=1; if (Key==KEY_ESC) clicked_button=2; } while (clicked_button<=0); Key=0; Close_window(); Display_cursor(); return (clicked_button==1)? 1 : 0; } //---- Fenêtre avertissant de quelque chose et attendant un click sur OK ----- void Warning_message(char * message) { short clicked_button; word window_width; window_width=(strlen(message)<<3)+20; if (window_width<120) window_width=120; Open_window(window_width,60,"Warning!"); Print_in_window((window_width>>1)-(strlen(message)<<2),20,message,MC_Black,MC_Light); Window_set_normal_button((window_width>>1)-20 ,37,40,14,"OK",1,1,SDLK_RETURN); // 1 Update_rect(Window_pos_X,Window_pos_Y,Menu_factor_X*window_width,Menu_factor_Y*60); Display_cursor(); do clicked_button=Window_clicked_button(); while ((clicked_button<=0) && (Key!=KEY_ESC) && (Key!=SDLK_o)); Key=0; Close_window(); Display_cursor(); } // -- Redessiner le sprite d'un bouton dans le menu -- void Display_sprite_in_menu(int btn_number,int sprite_number) { word x_pos; word y_pos; word menu_x_pos; word menu_y_pos; byte color; menu_y_pos=Buttons_Pool[btn_number].Y_offset; menu_x_pos=Buttons_Pool[btn_number].X_offset; if (Buttons_Pool[btn_number].Shape != BUTTON_SHAPE_TRIANGLE_BOTTOM_RIGHT) { menu_y_pos+=1; menu_x_pos+=1; } for (y_pos=0;y_pos à 64 lignes fct(Menu_Facteur) word nb_colors =(block_start<=block_end)?block_end-block_start+1:block_start-block_end+1; word Selected_line_mode=(block_start<=block_end)?0:total_lines-1; word start_x =Window_pos_X+(Menu_factor_X*x_pos); word line_width =Menu_factor_X<<4; // <=> à 16 pixels fct(Menu_Facteur) word start_y =Window_pos_Y+(Menu_factor_Y*y_pos); word end_y =start_y+total_lines; word index; if (block_start>block_end) { index=block_start; block_start=block_end; block_end=index; } for (index=start_y;index=corner_y) || (end_x<=Window_pos_X) || (start_x>=corner_x) ) Block(start_x,start_y,width,height,real_color); else { if (start_x>=Window_pos_X) { if ( (end_x>corner_x) || (end_y>corner_y) ) { if ( (end_x>corner_x) && (end_y>corner_y) ) { Block(corner_x,start_y,end_x-corner_x,corner_y-start_y,real_color); Block(start_x,corner_y,width,end_y-corner_y,real_color); } else { if (end_y>corner_y) Block(start_x,corner_y,width,end_y-corner_y,real_color); else Block(corner_x,start_y,end_x-corner_x,height,real_color); } } } else { if (end_xcorner_y) { Block(start_x,start_y,Window_pos_X-start_x,corner_y-start_y,real_color); Block(start_x,corner_y,width,end_y-corner_y,real_color); } else Block(start_x,start_y,Window_pos_X-start_x,height,real_color); } else { if (end_y>corner_y) { Block(start_x,start_y,Window_pos_X-start_x,corner_y-start_y,real_color); Block(corner_x,start_y,end_x-corner_x,corner_y-start_y,real_color); Block(start_x,corner_y,width,end_y-corner_y,real_color); } else { Block(start_x,start_y,Window_pos_X-start_x,height,real_color); Block(corner_x,start_y,end_x-corner_x,height,real_color); } } } } { // Affichage du bloc directement dans le "buffer de fond" de la fenetre. // Cela permet au bloc de couleur d'apparaitre si on déplace la fenetre. short x_pos; short y_pos; short relative_x; // besoin d'une variable signée short relative_y; // besoin d'une variable signée // Attention aux unités relative_x = ((short)start_x - (short)Window_pos_X); relative_y = ((short)start_y - (short)Window_pos_Y); for (y_pos=relative_y;y_pos<(relative_y+height)&&y_pos=0&&y_pos>=0) Pixel_background(x_pos,y_pos,real_color); } } } Update_rect(MENU_WIDTH*Menu_factor_X,Menu_Y_before_window,Screen_width-(MENU_WIDTH*Menu_factor_X),(MENU_HEIGHT-9)*Menu_factor_Y); } // -------- Calcul des bornes de la partie d'image visible à l'écran --------- void Compute_limits(void) /* Avant l'appel à cette fonction, les données de la loupe doivent être à jour. */ { if (Main_magnifier_mode) { // -- Calcul des limites de la partie non zoomée de l'image -- Limit_top =Main_offset_Y; Limit_left=Main_offset_X; Limit_visible_bottom =Limit_top+Menu_Y-1; Limit_visible_right=Limit_left+Main_separator_position-1; if (Limit_visible_bottom>=Main_image_height) Limit_bottom=Main_image_height-1; else Limit_bottom=Limit_visible_bottom; if (Limit_visible_right>=Main_image_width) Limit_right=Main_image_width-1; else Limit_right=Limit_visible_right; // -- Calcul des limites de la partie zoomée de l'image -- Limit_top_zoom =Main_magnifier_offset_Y; Limit_left_zoom=Main_magnifier_offset_X; Limit_visible_bottom_zoom =Limit_top_zoom+Main_magnifier_height-1; Limit_visible_right_zoom=Limit_left_zoom+Main_magnifier_width-1; if (Limit_visible_bottom_zoom>=Main_image_height) Limit_bottom_zoom=Main_image_height-1; else Limit_bottom_zoom=Limit_visible_bottom_zoom; if (Limit_visible_right_zoom>=Main_image_width) Limit_right_zoom=Main_image_width-1; else Limit_right_zoom=Limit_visible_right_zoom; } else { // -- Calcul des limites de la partie visible de l'image -- Limit_top =Main_offset_Y; Limit_left=Main_offset_X; Limit_visible_bottom =Limit_top+(Menu_is_visible?Menu_Y:Screen_height)-1; // A REVOIR POUR SIMPLIFICATION Limit_visible_right=Limit_left+Screen_width-1; if (Limit_visible_bottom>=Main_image_height) Limit_bottom=Main_image_height-1; else Limit_bottom=Limit_visible_bottom; if (Limit_visible_right>=Main_image_width) Limit_right=Main_image_width-1; else Limit_right=Limit_visible_right; } } // -- Calculer les coordonnées du pinceau en fonction du snap et de la loupe - void Compute_paintbrush_coordinates(void) { if ((Main_magnifier_mode) && (Mouse_X>=Main_X_zoom)) { Paintbrush_X=((Mouse_X-Main_X_zoom)/Main_magnifier_factor)+Main_magnifier_offset_X; Paintbrush_Y=(Mouse_Y/Main_magnifier_factor)+Main_magnifier_offset_Y; } else { Paintbrush_X=Mouse_X+Main_offset_X; Paintbrush_Y=Mouse_Y+Main_offset_Y; } if (Snap_mode) { Paintbrush_X=(((Paintbrush_X+(Snap_width>>1)-Snap_offset_X)/Snap_width)*Snap_width)+Snap_offset_X; Paintbrush_Y=(((Paintbrush_Y+(Snap_height>>1)-Snap_offset_Y)/Snap_height)*Snap_height)+Snap_offset_Y; } } // -- Affichage de la limite de l'image ------------------------------------- void Display_image_limits(void) { short start; short pos; short end; byte right_is_visible; byte bottom_is_visible; short old_zoom_limit; right_is_visible=Main_image_width<((Main_magnifier_mode)?Main_separator_position:Screen_width); bottom_is_visible =Main_image_heightMain_separator_position) { Main_offset_X=Main_magnifier_offset_X+(Main_magnifier_width>>1) -(Main_separator_position>>1); if (Main_offset_X<0) Main_offset_X=0; else if (Main_image_widthMenu_Y) { Main_offset_Y=Main_magnifier_offset_Y+(Main_magnifier_height>>1) -(Menu_Y>>1); if (Main_offset_Y<0) Main_offset_Y=0; else if (Main_image_height>1)-theoric_X)/Main_magnifier_factor)*Main_magnifier_factor); Main_separator_position=Main_X_zoom-(Menu_factor_X*SEPARATOR_WIDTH); // Correction en cas de débordement sur la gauche while (Main_separator_position*(Main_magnifier_factor+1)=theoric_X) { Main_separator_position-=Main_magnifier_factor; Main_X_zoom-=Main_magnifier_factor; } } // -------------------- Calcul des information de la loupe ------------------- void Compute_magnifier_data(void) /* Après modification des données de la loupe, il faut recalculer les limites. */ { Compute_separator_data(); Main_magnifier_width=(Screen_width-Main_X_zoom)/Main_magnifier_factor; Main_magnifier_height=Menu_Y/Main_magnifier_factor; if (Menu_Y%Main_magnifier_factor) Main_magnifier_height++; if (Main_magnifier_mode && Main_magnifier_offset_X) { if (Main_image_width>1); center_y=Main_magnifier_offset_Y+(Main_magnifier_height>>1); Main_magnifier_factor=ZOOM_FACTOR[factor_index]; Zoom_factor_table=Magnify_table[factor_index]; Compute_magnifier_data(); if (Main_magnifier_mode) { // Recalculer le décalage de la loupe // Centrage "brut" de lécran par rapport à la loupe Main_magnifier_offset_X=center_x-(Main_magnifier_width>>1); Main_magnifier_offset_Y=center_y-(Main_magnifier_height>>1); // Correction en cas de débordement de l'image if (Main_magnifier_offset_X+Main_magnifier_width>Main_image_width) Main_magnifier_offset_X=Main_image_width-Main_magnifier_width; if (Main_magnifier_offset_Y+Main_magnifier_height>Main_image_height) Main_magnifier_offset_Y=Main_image_height-Main_magnifier_height; if (Main_magnifier_offset_X<0) Main_magnifier_offset_X=0; if (Main_magnifier_offset_Y<0) Main_magnifier_offset_Y=0; Position_screen_according_to_zoom(); Pixel_preview=Pixel_preview_magnifier; } else Pixel_preview=Pixel_preview_normal; Compute_limits(); Compute_paintbrush_coordinates(); } // -- Afficher la barre de séparation entre les parties zoomées ou non en // mode Loupe -- void Display_separator(void) { // Partie grise du milieu Block(Main_separator_position+(Menu_factor_X<<1),Menu_factor_Y, (SEPARATOR_WIDTH-4)*Menu_factor_X, Menu_Y-(Menu_factor_Y<<1),MC_Light); // Barre noire de gauche Block(Main_separator_position,0,Menu_factor_X,Menu_Y,MC_Black); // Barre noire de droite Block(Main_X_zoom-Menu_factor_X,0,Menu_factor_X,Menu_Y,MC_Black); // Bord haut (blanc) Block(Main_separator_position+Menu_factor_X,0, (SEPARATOR_WIDTH-3)*Menu_factor_X,Menu_factor_Y,MC_White); // Bord gauche (blanc) Block(Main_separator_position+Menu_factor_X,Menu_factor_Y, Menu_factor_X,(Menu_Y-(Menu_factor_Y<<1)),MC_White); // Bord droite (gris foncé) Block(Main_X_zoom-(Menu_factor_X<<1),Menu_factor_Y, Menu_factor_X,(Menu_Y-(Menu_factor_Y<<1)),MC_Dark); // Bord bas (gris foncé) Block(Main_separator_position+(Menu_factor_X<<1),Menu_Y-Menu_factor_Y, (SEPARATOR_WIDTH-3)*Menu_factor_X,Menu_factor_Y,MC_Dark); // Coin bas gauche Block(Main_separator_position+Menu_factor_X,Menu_Y-Menu_factor_Y, Menu_factor_X,Menu_factor_Y,MC_Light); // Coin haut droite Block(Main_X_zoom-(Menu_factor_X<<1),0, Menu_factor_X,Menu_factor_Y,MC_Light); Update_rect(Main_separator_position,0,SEPARATOR_WIDTH*Menu_factor_X,Menu_Y); // On réaffiche toute la partie à gauche du split, ce qui permet d'effacer son ancienne position } // -- Fonctions de manipulation du curseur ----------------------------------- // -- Afficher une barre horizontale XOR zoomée void Horizontal_XOR_line_zoom(short x_pos, short y_pos, short width) { short real_x_pos=Main_X_zoom+(x_pos-Main_magnifier_offset_X)*Main_magnifier_factor; short real_y_pos=(y_pos-Main_magnifier_offset_Y)*Main_magnifier_factor; short real_width=width*Main_magnifier_factor; short end_y_pos=(real_y_pos+Main_magnifier_factor=Main_X_zoom) ) ) || (Windows_open) || (Cursor_shape==CURSOR_SHAPE_HOURGLASS) ) shape=Cursor_shape; else shape=CURSOR_SHAPE_ARROW; switch(shape) { case CURSOR_SHAPE_TARGET : if (!Paintbrush_hidden) Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,1); if (!Cursor_hidden) { if (Config.Cursor==1) { start_y=(Mouse_Y<6)?6-Mouse_Y:0; if (start_y<4) Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-6,4-start_y); start_x=(Mouse_X<6)?(short)6-Mouse_X:0; if (start_x<4) Horizontal_XOR_line(Mouse_X+start_x-6,Mouse_Y,4-start_x); end_x=(Mouse_X+7>Screen_width)?Mouse_X+7-Screen_width:0; if (end_x<4) Horizontal_XOR_line(Mouse_X+3,Mouse_Y,4-end_x); end_y=(Mouse_Y+7>Screen_height)?Mouse_Y+7-Screen_height:0; if (end_y<4) Vertical_XOR_line (Mouse_X,Mouse_Y+3,4-end_y); Update_rect(Mouse_X+start_x-6,Mouse_Y+start_y-6,13-end_x,13-end_y); } else { temp=(Config.Cursor)?CURSOR_SHAPE_THIN_TARGET:CURSOR_SHAPE_TARGET; start_x=Mouse_X-Cursor_offset_X[temp]; start_y=Mouse_Y-Cursor_offset_Y[temp]; for (x_pos=start_x,counter_x=0;counter_x<15 && x_pos < Screen_width;x_pos++,counter_x++) { if( x_pos < 0 ) continue; for (y_pos=start_y,counter_y=0;counter_y<15 && y_pos < Screen_height;y_pos++,counter_y++) { if( y_pos < 0 || y_pos >= Screen_height) continue; color=GFX_cursor_sprite[temp][counter_y][counter_x]; CURSOR_BACKGROUND[counter_y][counter_x]=Read_pixel(x_pos,y_pos); if (color!=MC_Trans) Pixel(x_pos,y_pos,color); } } Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y); } } break; case CURSOR_SHAPE_COLORPICKER: if (!Paintbrush_hidden) Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,1); if (!Cursor_hidden) { if (Config.Cursor==1) { // Barres formant la croix principale start_y=(Mouse_Y<5)?5-Mouse_Y:0; if (start_y<3) Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-5,3-start_y); start_x=(Mouse_X<5)?(short)5-Mouse_X:0; if (start_x<3) Horizontal_XOR_line(Mouse_X+start_x-5,Mouse_Y,3-start_x); end_x=(Mouse_X+6>Screen_width)?Mouse_X+6-Screen_width:0; if (end_x<3) Horizontal_XOR_line(Mouse_X+3,Mouse_Y,3-end_x); end_y=(Mouse_Y+6>Menu_Y/*Screen_height*/)?Mouse_Y+6-Menu_Y/*Screen_height*/:0; if (end_y<3) Vertical_XOR_line (Mouse_X,Mouse_Y+3,3-end_y); // Petites barres aux extrémités start_x=(!Mouse_X); start_y=(!Mouse_Y); end_x=(Mouse_X>=Screen_width-1); end_y=(Mouse_Y>=Menu_Y-1); if (Mouse_Y>5) Horizontal_XOR_line(start_x+Mouse_X-1,Mouse_Y-6,3-(start_x+end_x)); if (Mouse_X>5) Vertical_XOR_line (Mouse_X-6,start_y+Mouse_Y-1,3-(start_y+end_y)); if (Mouse_X=Screen_width) break; for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++) { if(y_pos<0) continue; if(y_pos>=Screen_height) break; color=GFX_cursor_sprite[temp][counter_y][counter_x]; // On sauvegarde dans CURSOR_BACKGROUND pour restaurer plus tard CURSOR_BACKGROUND[counter_y][counter_x]=Read_pixel(x_pos,y_pos); if (color!=MC_Trans) Pixel(x_pos,y_pos,color); } } Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y); } } break; case CURSOR_SHAPE_MULTIDIRECTIONAL : case CURSOR_SHAPE_HORIZONTAL : if (Cursor_hidden) break; case CURSOR_SHAPE_ARROW : case CURSOR_SHAPE_HOURGLASS : start_x=Mouse_X-Cursor_offset_X[shape]; start_y=Mouse_Y-Cursor_offset_Y[shape]; for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++) { if(x_pos<0) continue; if(x_pos>=Screen_width) break; for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++) { if(y_pos<0) continue; if(y_pos>=Screen_height) break; color=GFX_cursor_sprite[shape][counter_y][counter_x]; // On sauvegarde dans CURSOR_BACKGROUND pour restaurer plus tard CURSOR_BACKGROUND[counter_y][counter_x]=Read_pixel(x_pos,y_pos); if (color!=MC_Trans) Pixel(x_pos,y_pos,color); } } Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y); break; case CURSOR_SHAPE_XOR_TARGET : x_pos=Paintbrush_X-Main_offset_X; y_pos=Paintbrush_Y-Main_offset_Y; counter_x=(Main_magnifier_mode)?Main_separator_position:Screen_width; // width de la barre XOR if ((y_pos=Limit_top)) { Horizontal_XOR_line(0,Paintbrush_Y-Main_offset_Y,counter_x); Update_rect(0,Paintbrush_Y-Main_offset_Y,counter_x,1); } if ((x_pos=Limit_left)) { Vertical_XOR_line(Paintbrush_X-Main_offset_X,0,Menu_Y); Update_rect(Paintbrush_X-Main_offset_X,0,1,Menu_Y); } if (Main_magnifier_mode) { // UPDATERECT if ((Paintbrush_Y>=Limit_top_zoom) && (Paintbrush_Y<=Limit_visible_bottom_zoom)) Horizontal_XOR_line_zoom(Limit_left_zoom,Paintbrush_Y,Main_magnifier_width); if ((Paintbrush_X>=Limit_left_zoom) && (Paintbrush_X<=Limit_visible_right_zoom)) Vertical_XOR_line_zoom(Paintbrush_X,Limit_top_zoom,Main_magnifier_height); } break; case CURSOR_SHAPE_XOR_RECTANGLE : // !!! Cette forme ne peut pas être utilisée en mode Loupe !!! // Petite croix au centre start_x=(Mouse_X-3); start_y=(Mouse_Y-3); end_x =(Mouse_X+4); end_y =(Mouse_Y+4); if (start_x<0) start_x=0; if (start_y<0) start_y=0; if (end_x>Screen_width) end_x=Screen_width; if (end_y>Menu_Y) end_y=Menu_Y; Horizontal_XOR_line(start_x,Mouse_Y,end_x-start_x); Vertical_XOR_line (Mouse_X,start_y,end_y-start_y); // Grand rectangle autour start_x=Mouse_X-(Main_magnifier_width>>1); start_y=Mouse_Y-(Main_magnifier_height>>1); if (start_x+Main_magnifier_width>=Limit_right-Main_offset_X) start_x=Limit_right-Main_magnifier_width-Main_offset_X+1; if (start_y+Main_magnifier_height>=Limit_bottom-Main_offset_Y) start_y=Limit_bottom-Main_magnifier_height-Main_offset_Y+1; if (start_x<0) start_x=0; if (start_y<0) start_y=0; end_x=start_x+Main_magnifier_width-1; end_y=start_y+Main_magnifier_height-1; Horizontal_XOR_line(start_x,start_y,Main_magnifier_width); Vertical_XOR_line(start_x,start_y+1,Main_magnifier_height-2); Vertical_XOR_line( end_x,start_y+1,Main_magnifier_height-2); Horizontal_XOR_line(start_x, end_y,Main_magnifier_width); Update_rect(start_x,start_y,end_x+1-start_x,end_y+1-start_y); break; default: //case CURSOR_SHAPE_XOR_ROTATION : start_x=1-(Brush_width>>1); start_y=1-(Brush_height>>1); end_x=start_x+Brush_width-1; end_y=start_y+Brush_height-1; if (Brush_rotation_center_is_defined) { if ( (Brush_rotation_center_X==Paintbrush_X) && (Brush_rotation_center_Y==Paintbrush_Y) ) { cos_a=1.0; sin_a=0.0; } else { x_pos=Paintbrush_X-Brush_rotation_center_X; y_pos=Paintbrush_Y-Brush_rotation_center_Y; cos_a=(float)x_pos/sqrt((x_pos*x_pos)+(y_pos*y_pos)); sin_a=sin(acos(cos_a)); if (y_pos>0) sin_a=-sin_a; } Transform_point(start_x,start_y, cos_a,sin_a, &x1,&y1); Transform_point(end_x ,start_y, cos_a,sin_a, &x2,&y2); Transform_point(start_x,end_y , cos_a,sin_a, &x3,&y3); Transform_point(end_x ,end_y , cos_a,sin_a, &x4,&y4); x1+=Brush_rotation_center_X; y1+=Brush_rotation_center_Y; x2+=Brush_rotation_center_X; y2+=Brush_rotation_center_Y; x3+=Brush_rotation_center_X; y3+=Brush_rotation_center_Y; x4+=Brush_rotation_center_X; y4+=Brush_rotation_center_Y; Pixel_figure_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,0); Draw_line_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,Paintbrush_X,Paintbrush_Y,0); } else { x1=x3=1-Brush_width; y1=y2=start_y; x2=x4=Paintbrush_X; y3=y4=end_y; x1+=Paintbrush_X; y1+=Paintbrush_Y; y2+=Paintbrush_Y; x3+=Paintbrush_X; y3+=Paintbrush_Y; y4+=Paintbrush_Y; Pixel_figure_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,0); Draw_line_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,Paintbrush_X,Paintbrush_Y,0); } Draw_line_preview_xor(x1,y1,x2,y2,0); Draw_line_preview_xor(x2,y2,x4,y4,0); Draw_line_preview_xor(x4,y4,x3,y3,0); Draw_line_preview_xor(x3,y3,x1,y1,0); } } // -- Effacer le curseur -- void Hide_cursor(void) { byte shape; int start_x; // int car sont parfois négatifs ! (quand on dessine sur un bord) int start_y; short end_x; short end_y; int x_pos; int y_pos; short counter_x; short counter_y; //short end_counter_x; // Position X ou s'arrête l'affichage de la brosse/pinceau //short end_counter_y; // Position Y ou s'arrête l'affichage de la brosse/pinceau int temp; //byte color; float cos_a,sin_a; short x1,y1,x2,y2,x3,y3,x4,y4; if ( ( (Mouse_Y=Main_X_zoom) ) ) || (Windows_open) || (Cursor_shape==CURSOR_SHAPE_HOURGLASS) ) shape=Cursor_shape; else shape=CURSOR_SHAPE_ARROW; switch(shape) { case CURSOR_SHAPE_TARGET : if (!Cursor_hidden) { if (Config.Cursor==1) { start_y=(Mouse_Y<6)?6-Mouse_Y:0; if (start_y<4) Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-6,4-start_y); start_x=(Mouse_X<6)?(short)6-Mouse_X:0; if (start_x<4) Horizontal_XOR_line(Mouse_X+start_x-6,Mouse_Y,4-start_x); end_x=(Mouse_X+7>Screen_width)?Mouse_X+7-Screen_width:0; if (end_x<4) Horizontal_XOR_line(Mouse_X+3,Mouse_Y,4-end_x); end_y=(Mouse_Y+7>Screen_height)?Mouse_Y+7-Screen_height:0; if (end_y<4) Vertical_XOR_line (Mouse_X,Mouse_Y+3,4-end_y); Update_rect(Mouse_X+start_x-6,Mouse_Y+start_y-6,13-end_x,13-end_y); } else { temp=(Config.Cursor)?CURSOR_SHAPE_THIN_TARGET:CURSOR_SHAPE_TARGET; start_x=Mouse_X-Cursor_offset_X[temp]; start_y=Mouse_Y-Cursor_offset_Y[temp]; for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++) { if(y_pos>=Screen_height) break; for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++) { if ( (x_pos<0) || (y_pos < 0)) continue; else if (x_pos>=Screen_width) break; Pixel(x_pos,y_pos,CURSOR_BACKGROUND[counter_y][counter_x]); } } Update_rect(Max(start_x,0),Max(start_y,0),x_pos-start_x,y_pos-start_y); } } if (!Paintbrush_hidden) { Hide_paintbrush(Paintbrush_X,Paintbrush_Y); } break; case CURSOR_SHAPE_COLORPICKER: if (!Cursor_hidden) { if (Config.Cursor==1) { // Barres formant la croix principale start_y=(Mouse_Y<5)?5-Mouse_Y:0; if (start_y<3) Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-5,3-start_y); start_x=(Mouse_X<5)?(short)5-Mouse_X:0; if (start_x<3) Horizontal_XOR_line(Mouse_X+start_x-5,Mouse_Y,3-start_x); end_x=(Mouse_X+6>Screen_width)?Mouse_X+6-Screen_width:0; if (end_x<3) Horizontal_XOR_line(Mouse_X+3,Mouse_Y,3-end_x); end_y=(Mouse_Y+6>Screen_height)?Mouse_Y+6-Screen_height:0; if (end_y<3) Vertical_XOR_line (Mouse_X,Mouse_Y+3,3-end_y); start_x=(!Mouse_X); start_y=(!Mouse_Y); end_x=(Mouse_X>=Screen_width-1); end_y=(Mouse_Y>=Menu_Y-1); if (Mouse_Y>5) Horizontal_XOR_line(start_x+Mouse_X-1,Mouse_Y-6,3-(start_x+end_x)); if (Mouse_X>5) Vertical_XOR_line (Mouse_X-6,start_y+Mouse_Y-1,3-(start_y+end_y)); if (Mouse_X=Screen_width) break; for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++) { if(y_pos<0) continue; if(y_pos>=Screen_height) break; Pixel(x_pos,y_pos,CURSOR_BACKGROUND[counter_y][counter_x]); } } Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y); } } if (!Paintbrush_hidden) Hide_paintbrush(Paintbrush_X,Paintbrush_Y); break; case CURSOR_SHAPE_MULTIDIRECTIONAL : case CURSOR_SHAPE_HORIZONTAL : if (Cursor_hidden) break; case CURSOR_SHAPE_ARROW : case CURSOR_SHAPE_HOURGLASS : start_x=Mouse_X-Cursor_offset_X[shape]; start_y=Mouse_Y-Cursor_offset_Y[shape]; for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++) { if(x_pos<0) continue; if(x_pos>=Screen_width) break; for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++) { if(y_pos<0) continue; if(y_pos>=Screen_height) break; Pixel(x_pos,y_pos,CURSOR_BACKGROUND[counter_y][counter_x]); } } Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y); break; case CURSOR_SHAPE_XOR_TARGET : x_pos=Paintbrush_X-Main_offset_X; y_pos=Paintbrush_Y-Main_offset_Y; counter_x=(Main_magnifier_mode)?Main_separator_position:Screen_width; // width de la barre XOR if ((y_pos=Limit_top)) { Horizontal_XOR_line(0,Paintbrush_Y-Main_offset_Y,counter_x); Update_rect(0,Paintbrush_Y-Main_offset_Y,counter_x,1); } if ((x_pos=Limit_left)) { Vertical_XOR_line(Paintbrush_X-Main_offset_X,0,Menu_Y); Update_rect(Paintbrush_X-Main_offset_X,0,1,Menu_Y); } if (Main_magnifier_mode) { // UPDATERECT if ((Paintbrush_Y>=Limit_top_zoom) && (Paintbrush_Y<=Limit_visible_bottom_zoom)) Horizontal_XOR_line_zoom(Limit_left_zoom,Paintbrush_Y,Main_magnifier_width); if ((Paintbrush_X>=Limit_left_zoom) && (Paintbrush_X<=Limit_visible_right_zoom)) Vertical_XOR_line_zoom(Paintbrush_X,Limit_top_zoom,Main_magnifier_height); } break; case CURSOR_SHAPE_XOR_RECTANGLE : // !!! Cette forme ne peut pas être utilisée en mode Loupe !!! // Petite croix au centre start_x=(Mouse_X-3); start_y=(Mouse_Y-3); end_x =(Mouse_X+4); end_y =(Mouse_Y+4); if (start_x<0) start_x=0; if (start_y<0) start_y=0; if (end_x>Screen_width) end_x=Screen_width; if (end_y>Menu_Y) end_y=Menu_Y; Horizontal_XOR_line(start_x,Mouse_Y,end_x-start_x); Vertical_XOR_line (Mouse_X,start_y,end_y-start_y); // Grand rectangle autour start_x=Mouse_X-(Main_magnifier_width>>1); start_y=Mouse_Y-(Main_magnifier_height>>1); if (start_x+Main_magnifier_width>=Limit_right-Main_offset_X) start_x=Limit_right-Main_magnifier_width-Main_offset_X+1; if (start_y+Main_magnifier_height>=Limit_bottom-Main_offset_Y) start_y=Limit_bottom-Main_magnifier_height-Main_offset_Y+1; if (start_x<0) start_x=0; if (start_y<0) start_y=0; end_x=start_x+Main_magnifier_width-1; end_y=start_y+Main_magnifier_height-1; Horizontal_XOR_line(start_x,start_y,Main_magnifier_width); Vertical_XOR_line(start_x,start_y+1,Main_magnifier_height-2); Vertical_XOR_line( end_x,start_y+1,Main_magnifier_height-2); Horizontal_XOR_line(start_x, end_y,Main_magnifier_width); Update_rect(start_x,start_y,end_x+1-start_x,end_y+1-start_y); break; default: //case CURSOR_SHAPE_XOR_ROTATION : start_x=1-(Brush_width>>1); start_y=1-(Brush_height>>1); end_x=start_x+Brush_width-1; end_y=start_y+Brush_height-1; if (Brush_rotation_center_is_defined) { if ( (Brush_rotation_center_X==Paintbrush_X) && (Brush_rotation_center_Y==Paintbrush_Y) ) { cos_a=1.0; sin_a=0.0; } else { x_pos=Paintbrush_X-Brush_rotation_center_X; y_pos=Paintbrush_Y-Brush_rotation_center_Y; cos_a=(float)x_pos/sqrt((x_pos*x_pos)+(y_pos*y_pos)); sin_a=sin(acos(cos_a)); if (y_pos>0) sin_a=-sin_a; } Transform_point(start_x,start_y, cos_a,sin_a, &x1,&y1); Transform_point(end_x ,start_y, cos_a,sin_a, &x2,&y2); Transform_point(start_x,end_y , cos_a,sin_a, &x3,&y3); Transform_point(end_x ,end_y , cos_a,sin_a, &x4,&y4); x1+=Brush_rotation_center_X; y1+=Brush_rotation_center_Y; x2+=Brush_rotation_center_X; y2+=Brush_rotation_center_Y; x3+=Brush_rotation_center_X; y3+=Brush_rotation_center_Y; x4+=Brush_rotation_center_X; y4+=Brush_rotation_center_Y; Pixel_figure_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,0); Draw_line_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,Paintbrush_X,Paintbrush_Y,0); } else { x1=x3=1-Brush_width; y1=y2=start_y; x2=x4=Paintbrush_X; y3=y4=end_y; x1+=Paintbrush_X; y1+=Paintbrush_Y; y2+=Paintbrush_Y; x3+=Paintbrush_X; y3+=Paintbrush_Y; y4+=Paintbrush_Y; Pixel_figure_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,0); Draw_line_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,Paintbrush_X,Paintbrush_Y,0); } Draw_line_preview_xor(x1,y1,x2,y2,0); Draw_line_preview_xor(x2,y2,x4,y4,0); Draw_line_preview_xor(x4,y4,x3,y3,0); Draw_line_preview_xor(x3,y3,x1,y1,0); } } // -- Fonction diverses d'affichage ------------------------------------------ // -- Reafficher toute l'image (en prenant en compte le facteur de zoom) -- void Display_all_screen(void) { word width; word height; // ---/\/\/\ Partie non zoomée: /\/\/\--- if (Main_magnifier_mode) { if (Main_image_width>8) + 4*delta_g*delta_g + (((767-rmean)*delta_b*delta_b)>>8))) //if (!(dist=(delta_r*delta_r*30)+(delta_g*delta_g*59)+(delta_b*delta_b*11))) return col; if (dist>8) + 4*delta_g*delta_g + (((767-rmean)*delta_b*delta_b)>>8))) //if (!(dist=(delta_r*delta_r*30)+(delta_g*delta_g*59)+(delta_b*delta_b*11))) return col; if (dist