unit my_frame_bitmap; {Ecrit par Denis Bertin pour son logiciel et pour Delphi-7 le 28.12.2010} {Une recompilation pour Borland Delphi-7 qui me permet d'obtenir des résultats avérés exacts (c) db} interface uses windows,col_plan,wBase; function Frame_Bitmap(awindow:wbase.twindow; une_col_plan:col_plan.Tcol_plan; sa_fenetre:hwnd; avec_le_zoom_actif:real):boolean; implementation uses messages,haide,Wintypes,utile,wutil,WRegles,Graphics,wformes, dialbase,wformes1,wformebm,g_base,sysutils,u_object,u_tablis, my_math,hls_rvb,wHelp,relation,U_preference,wmain,font_ob1; Type Tcasealgorythme = (TCA_remplissage_point_par_ppoint,TCA_remplissage_qqs_dist,TCA_remplissage_plus_proche); Trec_Frame_Buffer = record bool_check_bitmap_simple:bool; bool_check_Proximiter_simple:bool; bool_check_Proximiter_parametrer:bool; edit_distance_de_proximiter:longint; bool_check_avec_une_interaction:bool; end; {Trec_Frame_Buffer} var rec_frame_buffer : Trec_Frame_Buffer; const id_check_bitmap_simple = 100; id_check_Proximiter_simple = 101; id_check_Proximiter_parametrer = 102; id_check_avec_une_interaction = 103; id_edit_son_parametre_de_distance = 200; type TVector_in_frame_Dialog = class(Whelp.ThelpDialog) public constructor Create(AParent:WBase.TWindow); procedure wmcommand(var msg:TMessage); override; {Recouvrement en français} private check_bitmap_simple:wbase.TCheckBox; check_Proximiter_simple:wbase.TCheckBox; check_Proximiter_parametrer:wbase.TCheckBox; edit_son_parametre_de_distance:dialbase.TNumEdit_plus_moins; check_avec_une_interaction:wbase.TCheckBox; end; {TVector_in_frame_Dialog} procedure TVector_in_frame_Dialog.wmcommand(var msg:TMessage); begin inherited wmcommand(msg); case loword(msg.wparam) of id_check_bitmap_simple: begin check_Proximiter_simple.Uncheck; check_Proximiter_parametrer.Uncheck; end; id_check_Proximiter_simple: begin check_bitmap_simple.Uncheck; check_Proximiter_parametrer.Uncheck; end; id_check_Proximiter_parametrer: begin check_bitmap_simple.Uncheck; check_Proximiter_simple.Uncheck; end; end; {case} enablewindow(check_avec_une_interaction.hwindow, check_Proximiter_parametrer.GetCheck=bf_checked); end; {TVector_in_frame_Dialog.wmcommand} constructor TVector_in_frame_Dialog.Create(AParent:wbase.twindow); const dial_id_diaogue_frame_bitmap = 1676; begin inherited Create(AParent,dial_id_diaogue_frame_bitmap,0); check_bitmap_simple:=wbase.TCheckBox.Create(Self,id_check_bitmap_simple,0); check_Proximiter_simple:=wbase.TCheckBox.Create(Self,id_check_Proximiter_simple,0); check_Proximiter_parametrer:=wbase.TCheckBox.Create(Self,id_check_Proximiter_parametrer,0); edit_son_parametre_de_distance:=dialbase.TNumEdit_plus_moins.Create(Self,id_edit_son_parametre_de_distance,5,0,9999,0); check_avec_une_interaction:=wbase.TCheckBox.Create(Self,id_check_avec_une_interaction,0); self.TransferBuffer:=@rec_frame_buffer; end; {TVector_in_frame_Dialog.Create} procedure fill_bitmap_with_this_color(sa_fenetre:hwnd; un_object:wformes.tforme_tab; dun_bitmap:hbitmap); var i,j:integer; adc,adcmem:hdc; bm:wintypes.tbitmap; begin adc:=getdc(sa_fenetre); adcmem:=Createcompatibledc(adc); Selectobject(adcmem,dun_bitmap); GetObject(dun_bitmap,SizeOf(bm),@bm); for i:=0 to bm.bmWidth do for j:=0 to bm.bmheight do begin haide.Show_horloge_curseur(i*100 div bm.bmWidth); setpixel(adcmem,i,j,un_object.brush1.lbcolor); end; Deletedc(adcmem); Releasedc(sa_fenetre,adc); end; procedure do_un_parcours_selon_ce_tableau(sa_fenetre:hwnd; un_object:wformes.tforme_tab; dun_bitmap:hbitmap; avec_le_zoom_actif:real); const k_origine_zero:tpoint=(x:0;y:0); var i,j,k,this_k:integer; bm:wintypes.tbitmap; adc,adcmem:hdc; un_point,deux_point,trois_point,found_point:tpoint; {$ifdef debug} apc:wutil.pc100; {$endif debug} un_tableau:u_tablis.o_tabpt; une_distance,max_distance:real; teinte,luminositer,saturation:real; maximum:real; anode:font_ob1.testnode; donc_un_angle,doux_cette_angle,difference_angle:real; avec_un_seul_element:boolean; un_cas_dans_cette_plage:real; begin if not ((un_object.ClassType=wformes1.tforme_dessin) or (un_object.ClassType=wformes1.tforme_text)) then exit; avec_un_seul_element:=not rec_frame_buffer.bool_check_avec_une_interaction; maximum:=relation._10mm_to_log_pouce(rec_frame_buffer.edit_distance_de_proximiter); adc:=getdc(sa_fenetre); adcmem:=Createcompatibledc(adc); Selectobject(adcmem,dun_bitmap); wregles.map_mode(adc,client,k_origine_zero,avec_le_zoom_actif); GetObject(dun_bitmap,SizeOf(bm),@bm); {$ifdef debug} inttopchar(bm.bmWidth,apc); box(0,apc); inttopchar(bm.bmheight,apc); box(0,apc); inttopchar(un_object.brush1.lbcolor,apc); box(0,apc); {$endif debug} hls_rvb.tcolorref_to_hls(un_object.brush1.lbcolor,teinte,luminositer,saturation); for i:=0 to bm.bmWidth do for j:=0 to bm.bmheight do begin haide.Show_horloge_curseur(i*100 div bm.bmWidth); un_point.x:=i; un_point.y:=j; {Convertir les pixels de device à logique} dptolp(adc,un_point,sizeof(un_point) div sizeof(un_point)); if un_object.listtabpt<>nil then begin un_tableau:=un_object.listtabpt.at(0); if un_tableau<>nil then begin //Seulement avec le point le plus proche max_distance:=1e99; this_k:=-1; for k:=1 to un_tableau.Npt do begin deux_point.x:=un_tableau.tab[k].x; deux_point.y:=un_tableau.tab[k].y; une_distance:=utile.distance(un_point.x,un_point.y,deux_point.x,deux_point.y); if une_distance<max_distance then begin max_distance:=une_distance; this_k:=k; end; end; {for k} {Afficher ce point i,j ici} if max_distance<maximum then begin if avec_un_seul_element then begin Setpixel(adcmem,i,j,hls_rvb.Get_HLS_RGB(teinte,0.5+(1.0-max_distance/maximum)/2,0.5)); //saturation end else begin {k_avec d'autre éléments} donc_un_angle:=utile.angle_degree(un_point.x,un_point.y,deux_point.x,deux_point.y); for k:=1 to un_tableau.Npt do begin if this_k<>k then begin trois_point.x:=un_tableau.tab[k].x; trois_point.y:=un_tableau.tab[k].y; doux_cette_angle:=utile.angle_degree(un_point.x,un_point.y,trois_point.x,trois_point.y); difference_angle:=abs(donc_un_angle-doux_cette_angle); if difference_angle<=6 then Setpixel(adcmem,i,j,hls_rvb.Get_HLS_RGB(teinte,0.5+(1.0-max_distance/maximum)/2,difference_angle/6)); end; end; end; {k_avec d'autre éléments} end; end; end {un_tableau<>nil} else begin {avec les éléments} max_distance:=1e99; this_k:=-1; for k:=0 to pred(wformes1.tforme_dessin(un_object).elements.count) do begin anode:=wformes1.tforme_dessin(un_object).elements.at(k); deux_point.x:=anode.x+wformes1.tforme_dessin(un_object).x; deux_point.y:=anode.y+wformes1.tforme_dessin(un_object).y; une_distance:=utile.distance(un_point.x,un_point.y,deux_point.x,deux_point.y); if une_distance<max_distance then begin max_distance:=une_distance; this_k:=k; found_point:=deux_point; end; end; {Afficher ce point i,j ici} if max_distance<maximum then begin if avec_un_seul_element then begin Setpixel(adcmem,i,j,hls_rvb.Get_HLS_RGB(teinte,0.5+(1.0-max_distance/maximum)/2,0.5)); //saturation end else begin un_cas_dans_cette_plage:=0; donc_un_angle:=round(utile.angle_degree(un_point.x,un_point.y,found_point.x,found_point.y)+180) mod 360; for k:=0 to pred(wformes1.tforme_dessin(un_object).elements.count) do begin if this_k<>k then begin anode:=wformes1.tforme_dessin(un_object).elements.at(k); trois_point.x:=anode.x+wformes1.tforme_dessin(un_object).x; trois_point.y:=anode.y+wformes1.tforme_dessin(un_object).y; doux_cette_angle:=utile.angle_degree(un_point.x,un_point.y,trois_point.x,trois_point.y); difference_angle:=abs(donc_un_angle-doux_cette_angle); if difference_angle=0 then begin end else if (difference_angle>=1) and (difference_angle<=20) then un_cas_dans_cette_plage:=difference_angle; end; end; {for k} if un_cas_dans_cette_plage<>0 then begin Setpixel(adcmem,i,j,hls_rvb.Get_HLS_RGB(teinte,0.5+(1.0-max_distance/maximum)/2,1.0-(un_cas_dans_cette_plage)/40)) end else begin Setpixel(adcmem,i,j,hls_rvb.Get_HLS_RGB(teinte,0.5+(1.0-max_distance/maximum)/2,0.5)); end; end; end; end; {avec les éléments} end; {i,j} Deletedc(adcmem); Releasedc(sa_fenetre,adc); end; {do_un_parcours_selon_ce_tableau} procedure do_un_parcours_avec_max_distance(sa_fenetre:hwnd; un_object:wformes.tforme_tab; dun_bitmap:hbitmap; avec_le_zoom_actif:real); const k_origine_zero:tpoint=(x:0;y:0); var i,j,k:integer; bm:wintypes.tbitmap; adc,adcmem:hdc; un_point,deux_point:tpoint; {$ifdef debug} apc:wutil.pc100; {$endif debug} un_tableau:u_tablis.o_tabpt; une_distance,max_distance:real; teinte,luminositer,saturation:real; maximum,local_cette_distance:real; anode:font_ob1.testnode; begin maximum:=relation._10mm_to_log_pouce(rec_frame_buffer.edit_distance_de_proximiter); adc:=getdc(sa_fenetre); adcmem:=Createcompatibledc(adc); Selectobject(adcmem,dun_bitmap); wregles.map_mode(adc,client,k_origine_zero,avec_le_zoom_actif); GetObject(dun_bitmap,SizeOf(bm),@bm); {$ifdef debug} inttopchar(bm.bmWidth,apc); box(0,apc); inttopchar(bm.bmheight,apc); box(0,apc); inttopchar(un_object.brush1.lbcolor,apc); box(0,apc); {$endif debug} hls_rvb.tcolorref_to_hls(un_object.brush1.lbcolor,teinte,luminositer,saturation); //seulement avec le point le plus proche max_distance:=0; for i:=0 to bm.bmWidth do for j:=0 to bm.bmheight do begin haide.Show_horloge_curseur(i*100 div bm.bmWidth); un_point.x:=i; un_point.y:=j; {Convertir les pixels de device à logique} dptolp(adc,un_point,sizeof(un_point) div sizeof(un_point)); if un_object.listtabpt<>nil then begin un_tableau:=un_object.listtabpt.at(0); if un_tableau<>nil then begin for k:=1 to un_tableau.Npt do begin deux_point.x:=un_tableau.tab[k].x; deux_point.y:=un_tableau.tab[k].y; une_distance:=utile.distance(un_point.x,un_point.y,deux_point.x,deux_point.y); if une_distance>max_distance then begin max_distance:=une_distance; end; end; {for k} end; {un_tableau<>nil} end {un_object.listtabpt} else begin {avec des éléments} for k:=0 to pred(wformes1.tforme_dessin(un_object).elements.count) do begin anode:=wformes1.tforme_dessin(un_object).elements.at(k); deux_point.x:=anode.x+wformes1.tforme_dessin(un_object).x; deux_point.y:=anode.y+wformes1.tforme_dessin(un_object).y; une_distance:=utile.distance(un_point.x,un_point.y,deux_point.x,deux_point.y); if une_distance>max_distance then begin max_distance:=une_distance; end; end; end; {avec des éléments} end; {i,j} //max distance étant déterminé for i:=0 to bm.bmWidth do for j:=0 to bm.bmheight do begin haide.Show_horloge_curseur(i*100 div bm.bmWidth); un_point.x:=i; un_point.y:=j; {Convertir les pixels de device à logique} dptolp(adc,un_point,sizeof(un_point) div sizeof(un_point)); if un_object.listtabpt<>nil then begin un_tableau:=un_object.listtabpt.at(0); if un_tableau<>nil then begin local_cette_distance:=1e99; for k:=1 to un_tableau.Npt do begin deux_point.x:=un_tableau.tab[k].x; deux_point.y:=un_tableau.tab[k].y; une_distance:=utile.distance(un_point.x,un_point.y,deux_point.x,deux_point.y); if une_distance<local_cette_distance then begin local_cette_distance:=une_distance; end; end; {for k} Setpixel(adcmem,i,j,hls_rvb.Get_HLS_RGB(teinte,0.5+(1.0-local_cette_distance/max_distance)/2,0.5)); end; {un_tableau<>nil} end {un_object.listtabpt<>nil} else begin {avec des éléments} local_cette_distance:=1e99; for k:=0 to pred(wformes1.tforme_dessin(un_object).elements.count) do begin anode:=wformes1.tforme_dessin(un_object).elements.at(k); deux_point.x:=anode.x+wformes1.tforme_dessin(un_object).x; deux_point.y:=anode.y+wformes1.tforme_dessin(un_object).y; une_distance:=utile.distance(un_point.x,un_point.y,deux_point.x,deux_point.y); if une_distance<local_cette_distance then begin local_cette_distance:=une_distance; end; Setpixel(adcmem,i,j,hls_rvb.Get_HLS_RGB(teinte,0.5+(1.0-local_cette_distance/max_distance)/2,0.5)); end; {for k} end; {avec des éléments} end; {i,j} Deletedc(adcmem); Releasedc(sa_fenetre,adc); end; {do_un_parcours_avec_max_distance} function Frame_Bitmap(awindow:wbase.twindow; une_col_plan:col_plan.Tcol_plan; sa_fenetre:hwnd; avec_le_zoom_actif:real):boolean; const k_origine_zero:tpoint=(x:0;y:0); var i:integer; un_case_algorythme:Tcasealgorythme; adc:hdc; taille_du_bitmap:tpoint; abitmap:hbitmap; un_dib:wformebm.Tforme_TBitMap; un_bitmap_borland:Graphics.tbitmap; {Ceci pour transformer les unités device en pixels} cadre_the_selection:trect; {Sarko c'est un homme qui n'admet pas que ramayade soit plus intelligente que lui} un_layer_actif:col_plan.TCalque; un_index:u_object.Tindex; un_object:wformes.tforme_tab; before_deplace:tpoint; un_dial_frame_bitmap:TVector_in_frame_Dialog; resultat:boolean; oldcursor:hcursor; begin Frame_Bitmap:=false; cadre_the_selection:=une_col_plan.rect_select.rect; adc:=getdc(sa_fenetre); wregles.map_mode(adc,client,k_origine_zero,avec_le_zoom_actif); lptodp(adc,cadre_the_selection,sizeof(trect) div sizeof(tpoint)); taille_du_bitmap.x:=cadre_the_selection.right-cadre_the_selection.left; taille_du_bitmap.y:=cadre_the_selection.bottom-cadre_the_selection.top; abitmap:=createcompatiblebitmap(adc,taille_du_bitmap.x,taille_du_bitmap.Y); Releasedc(sa_fenetre,adc); un_layer_actif:=une_col_plan.Get_calque_actif; if un_layer_actif=nil then exit; {Création du dialogue de convertion du bitmap selon ces algorythmes-c'db} un_dial_frame_bitmap:=TVector_in_frame_Dialog.Create(awindow); resultat:=un_dial_frame_bitmap.Execdialog(awindow.hwindow)=id_ok; un_dial_frame_bitmap.Free; if not resultat then exit; if rec_frame_buffer.bool_check_bitmap_simple then begin oldcursor:=setcursor(loadcursor(0,IDC_WAIT)); abitmap:=une_col_plan.get_bitmap_image(awindow.hwindow, U_preference.Form_preference.TrackBar1.Position/100, wmain.MainWindow.rec_taille_doc.couleur,true); setcursor(oldcursor); end else begin if rec_frame_buffer.bool_check_Proximiter_simple then un_case_algorythme:=TCA_remplissage_qqs_dist else un_case_algorythme:=TCA_remplissage_plus_proche; {Prendre le premier élément pour le colorier} un_index:=un_layer_actif.col_select.at(pred(un_layer_actif.col_select.Count)); if un_index<>nil then begin un_object:=wformes.tforme_tab(un_layer_actif.formindex(un_index)); if un_object<>nil then fill_bitmap_with_this_color(sa_fenetre,un_object,abitmap); end; {Parcourir les éléments suivant et aussi le premier} for i:=pred(un_layer_actif.col_select.Count) downto 0 do begin un_index:=un_layer_actif.col_select.at(i); if un_index<>nil then begin un_object:=wformes.tforme_tab(un_layer_actif.formindex(un_index)); if un_object<>nil then if (un_object.ClassType=wformes1.Tforme_dessin) or (un_object.ClassType=wformes1.tforme_text) then begin before_deplace.x:=une_col_plan.rect_select.rect.left; before_deplace.y:=une_col_plan.rect_select.rect.top; un_object.deplace(-before_deplace.x,-before_deplace.y,0); case un_case_algorythme of TCA_remplissage_plus_proche: do_un_parcours_selon_ce_tableau(sa_fenetre, un_object,abitmap,avec_le_zoom_actif); TCA_remplissage_qqs_dist: do_un_parcours_avec_max_distance(sa_fenetre, un_object,abitmap,avec_le_zoom_actif); end; {case} un_object.deplace(before_deplace.x,before_deplace.y,0); end; end; {un_index<>nil} end; {for i} end; oldcursor:=setcursor(loadcursor(0,IDC_WAIT)); un_bitmap_borland:=Graphics.tbitmap.create; un_bitmap_borland.Handle:=abitmap; with une_col_plan.rect_select.rect do un_dib:=wformebm.Tforme_TBitMap.Create(left,top,right,bottom,un_bitmap_borland,0,'',10,'Arial',g_base.RGB_Noir); strcopy(un_dib.name,'Initiate'); un_layer_actif:=une_col_plan.Get_calque_actif; if un_layer_actif<>nil then begin for i:=0 to pred(un_layer_actif.col_select.count) do begin un_index:=un_layer_actif.col_select.at(i); if un_index<>nil then begin un_object:=wformes.tforme_tab(un_layer_actif.formindex(un_index)); if un_object<>nil then un_layer_actif.list.remove(un_object); end; end; un_layer_actif.Add(un_dib); un_layer_actif.col_select.freeall; un_layer_actif.col_select.add(u_object.tindex.Create(pred(un_layer_actif.count))); end; setcursor(oldcursor); end; {Frame_Bitmap} begin rec_frame_buffer.bool_check_bitmap_simple:=true; rec_frame_buffer.bool_check_Proximiter_simple:=false; rec_frame_buffer.bool_check_Proximiter_parametrer:=false; rec_frame_buffer.edit_distance_de_proximiter:=100; rec_frame_buffer.bool_check_avec_une_interaction:=false; end.