You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							905 lines
						
					
					
						
							30 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							905 lines
						
					
					
						
							30 KiB
						
					
					
				
								/*******************************/
							 | 
						|
								/**** Routine de trace HPGL ****/
							 | 
						|
								/*******************************/
							 | 
						|
								
							 | 
						|
								#include "fctsys.h"
							 | 
						|
								
							 | 
						|
								#include "common.h"
							 | 
						|
								#include "plot_common.h"
							 | 
						|
								#include "pcbnew.h"
							 | 
						|
								#include "pcbplot.h"
							 | 
						|
								#include "trigo.h"
							 | 
						|
								
							 | 
						|
								#include "protos.h"
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/* Variables locales : */
							 | 
						|
								static int pen_rayon;           /* Rayon de la plume en unites pcb */
							 | 
						|
								static int pen_diam;            /* Diametre de la plume en unites pcb */
							 | 
						|
								static int pen_recouvrement;    /* recouvrement en remplissage en unites pcb */
							 | 
						|
								
							 | 
						|
								/* Routines Locales */
							 | 
						|
								
							 | 
						|
								/*****************************************************************************/
							 | 
						|
								void WinEDA_BasePcbFrame::Genere_HPGL( const wxString& FullFileName, int Layer )
							 | 
						|
								/*****************************************************************************/
							 | 
						|
								{
							 | 
						|
								    int     modetrace;
							 | 
						|
								    wxSize  SheetSize;
							 | 
						|
								    wxSize  BoardSize;
							 | 
						|
								    wxPoint BoardCenter;
							 | 
						|
								    double  scale_x, scale_y;
							 | 
						|
								    int     marge  = 0 * U_PCB; // Extra margin (set to 0)
							 | 
						|
								    bool    Center = FALSE;
							 | 
						|
								
							 | 
						|
								    modetrace = Plot_Mode;
							 | 
						|
								
							 | 
						|
								    /* Calcul des echelles de conversion */
							 | 
						|
								    scale_x = Scale_X * SCALE_HPGL;
							 | 
						|
								    scale_y = Scale_Y * SCALE_HPGL;
							 | 
						|
								
							 | 
						|
								    // calcul en unites internes des dimensions de la feuille ( connues en 1/1000 pouce )
							 | 
						|
								    SheetSize.x = m_CurrentScreen->m_CurrentSheet->m_Size.x * U_PCB;
							 | 
						|
								    SheetSize.y = m_CurrentScreen->m_CurrentSheet->m_Size.y * U_PCB;
							 | 
						|
								
							 | 
						|
								    g_PlotOffset.x = 0;
							 | 
						|
								    g_PlotOffset.y = (int) (SheetSize.y * scale_y);
							 | 
						|
								
							 | 
						|
								    // Compute pen_dim (from g_HPGL_Pen_Diam in mils) in pcb units,
							 | 
						|
								    // with plot scale (if Scale is 2, pen diametre is always g_HPGL_Pen_Diam
							 | 
						|
								    // so apparent pen diam is real pen diam / Scale
							 | 
						|
								    pen_diam  = (int) round( (g_HPGL_Pen_Diam * U_PCB) / Scale_X ); // Assume Scale_X # Scale_Y
							 | 
						|
								    pen_rayon = pen_diam / 2;
							 | 
						|
								
							 | 
						|
								    nb_plot_erreur = 0;
							 | 
						|
								
							 | 
						|
								    // compute pen_recouvrement (from g_HPGL_Pen_Recouvrement in mils)
							 | 
						|
								    // with plot scale
							 | 
						|
								    if( g_HPGL_Pen_Recouvrement < 0 )
							 | 
						|
								        g_HPGL_Pen_Recouvrement = 0;
							 | 
						|
								    if( g_HPGL_Pen_Recouvrement >= g_HPGL_Pen_Diam )
							 | 
						|
								        g_HPGL_Pen_Recouvrement = g_HPGL_Pen_Diam - 1;
							 | 
						|
								    pen_recouvrement = (int) round( g_HPGL_Pen_Recouvrement * 10.0 / Scale_X );
							 | 
						|
								
							 | 
						|
								    dest = wxFopen( FullFileName, wxT( "wt" ) );
							 | 
						|
								    if( dest == NULL )
							 | 
						|
								    {
							 | 
						|
								        wxString msg = _( "Unable to create " ) + FullFileName;
							 | 
						|
								        DisplayError( this, msg );
							 | 
						|
								        return;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    setlocale( LC_NUMERIC, "C" );
							 | 
						|
								
							 | 
						|
								    Affiche_1_Parametre( this, 0, _( "File" ), FullFileName, CYAN );
							 | 
						|
								
							 | 
						|
								    PrintHeaderHPGL( dest, g_HPGL_Pen_Speed, g_HPGL_Pen_Num );
							 | 
						|
								
							 | 
						|
								    if( Plot_Sheet_Ref && (g_PlotScaleOpt == 1) )
							 | 
						|
								    {
							 | 
						|
								        int tmp = g_PlotOrient; g_PlotOrient = 0;
							 | 
						|
								        InitPlotParametresHPGL( g_PlotOffset, scale_x, scale_y, g_PlotOrient );
							 | 
						|
								        PlotWorkSheet( PLOT_FORMAT_HPGL, m_CurrentScreen );
							 | 
						|
								        g_PlotOrient = tmp;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* calcul des dimensions et centre du PCB */
							 | 
						|
								    m_Pcb->ComputeBoundaryBox();
							 | 
						|
								    BoardSize   = m_Pcb->m_BoundaryBox.GetSize();
							 | 
						|
								    BoardCenter = m_Pcb->m_BoundaryBox.Centre();
							 | 
						|
								
							 | 
						|
								    if( g_PlotScaleOpt == 0 )       // Optimum scale
							 | 
						|
								    {
							 | 
						|
								        float Xscale, Yscale;
							 | 
						|
								        Xscale  = (float) ( SheetSize.x - ( 2 * marge) ) / BoardSize.x;
							 | 
						|
								        Yscale  = (float) ( SheetSize.y - ( 2 * marge) ) / BoardSize.y;
							 | 
						|
								        scale_x = scale_y = MIN( Xscale, Yscale ) * SCALE_HPGL;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    BoardCenter.x = (int) (BoardCenter.x * scale_x);
							 | 
						|
								    BoardCenter.y = (int) (BoardCenter.y * scale_y);
							 | 
						|
								
							 | 
						|
								    if( g_PlotScaleOpt != 1 )
							 | 
						|
								        Center = TRUE;                          // Echelle != 1
							 | 
						|
								
							 | 
						|
								    /* Calcul du cadrage */
							 | 
						|
								    marge = (int) (marge * SCALE_HPGL);
							 | 
						|
								    if( Center )
							 | 
						|
								        g_PlotOffset.x = (int) (-SheetSize.x / 2 * SCALE_HPGL) +
							 | 
						|
								                         BoardCenter.x + marge;
							 | 
						|
								
							 | 
						|
								    switch( g_PlotOrient )
							 | 
						|
								    {
							 | 
						|
								    default:
							 | 
						|
								        if( Center )
							 | 
						|
								        {
							 | 
						|
								            g_PlotOffset.y = (int) (SheetSize.y / 2 * SCALE_HPGL) +
							 | 
						|
								                             BoardCenter.y + marge;
							 | 
						|
								        }
							 | 
						|
								        break;
							 | 
						|
								
							 | 
						|
								    case PLOT_MIROIR:
							 | 
						|
								        if( Center )
							 | 
						|
								            g_PlotOffset.y = (int) (-SheetSize.y / 2 * SCALE_HPGL) + BoardCenter.y;
							 | 
						|
								        else
							 | 
						|
								            g_PlotOffset.y = (int) ( ( -SheetSize.y +
							 | 
						|
								                                      m_Pcb->m_BoundaryBox.GetBottom() +
							 | 
						|
								                                      m_Pcb->m_BoundaryBox.GetY() ) * SCALE_HPGL );
							 | 
						|
								        break;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    InitPlotParametresHPGL( g_PlotOffset, scale_x, scale_y, g_PlotOrient );
							 | 
						|
								
							 | 
						|
									// Specify that the contents of the "Edges Pcb" layer are to be plotted
							 | 
						|
									// in addition to the contents of the currently specified layer.
							 | 
						|
									int layer_mask = g_TabOneLayerMask[Layer] | EDGE_LAYER;
							 | 
						|
								
							 | 
						|
								    switch( Layer )
							 | 
						|
								    {
							 | 
						|
								    case COPPER_LAYER_N:
							 | 
						|
								    case LAYER_N_2:
							 | 
						|
								    case LAYER_N_3:
							 | 
						|
								    case LAYER_N_4:
							 | 
						|
								    case LAYER_N_5:
							 | 
						|
								    case LAYER_N_6:
							 | 
						|
								    case LAYER_N_7:
							 | 
						|
								    case LAYER_N_8:
							 | 
						|
								    case LAYER_N_9:
							 | 
						|
								    case LAYER_N_10:
							 | 
						|
								    case LAYER_N_11:
							 | 
						|
								    case LAYER_N_12:
							 | 
						|
								    case LAYER_N_13:
							 | 
						|
								    case LAYER_N_14:
							 | 
						|
								    case LAYER_N_15:
							 | 
						|
								    case CMP_N:
							 | 
						|
								        Plot_Layer_HPGL( dest, layer_mask, 0, 1, modetrace );
							 | 
						|
								        break;
							 | 
						|
								
							 | 
						|
								    case SILKSCREEN_N_CU:
							 | 
						|
								    case SILKSCREEN_N_CMP:
							 | 
						|
								        Plot_Serigraphie( PLOT_FORMAT_HPGL, dest, layer_mask );
							 | 
						|
								        break;
							 | 
						|
								
							 | 
						|
								    case SOLDERMASK_N_CU:
							 | 
						|
								    case SOLDERMASK_N_CMP:       /* Trace du vernis epargne */
							 | 
						|
								    {
							 | 
						|
								        int tracevia;
							 | 
						|
								        if( g_DrawViaOnMaskLayer )
							 | 
						|
								            tracevia = 1;
							 | 
						|
								        else
							 | 
						|
								            tracevia = 0;
							 | 
						|
								        Plot_Layer_HPGL( dest, layer_mask,
							 | 
						|
								                         g_DesignSettings.m_MaskMargin, tracevia, modetrace );
							 | 
						|
								    }
							 | 
						|
								        break;
							 | 
						|
								
							 | 
						|
								    case SOLDERPASTE_N_CU:
							 | 
						|
								    case SOLDERPASTE_N_CMP:       /* Trace du masque de pate de soudure */
							 | 
						|
								        Plot_Layer_HPGL( dest, layer_mask, 0, 0, modetrace );
							 | 
						|
								        break;
							 | 
						|
								
							 | 
						|
								    default:       /* Trace des autres couches (dessin, adhesives,eco,comment) */
							 | 
						|
								        Plot_Serigraphie( PLOT_FORMAT_HPGL, dest, layer_mask );
							 | 
						|
								        break;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* fin */
							 | 
						|
								    CloseFileHPGL( dest );
							 | 
						|
								    setlocale( LC_NUMERIC, "" );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*********************************************************************/
							 | 
						|
								void WinEDA_BasePcbFrame::Plot_Layer_HPGL( FILE* File, int masque_layer,
							 | 
						|
								                                           int garde, int tracevia, int modetrace )
							 | 
						|
								/*********************************************************************/
							 | 
						|
								
							 | 
						|
								/* Trace en format HPGL. d'une couche cuivre ou masque
							 | 
						|
								 *  1 unite HPGL = 0.98 mils ( 1 mil = 1.02041 unite HPGL ) .
							 | 
						|
								 */
							 | 
						|
								{
							 | 
						|
								    wxSize      size;
							 | 
						|
								    wxPoint     start, end;
							 | 
						|
								    MODULE*     Module;
							 | 
						|
								    D_PAD*      PtPad;
							 | 
						|
								    TRACK*      pts;
							 | 
						|
								    BOARD_ITEM* PtStruct;
							 | 
						|
								    wxString    msg;
							 | 
						|
								
							 | 
						|
								// 	(Following command has been superceded by new command on line 135.)
							 | 
						|
								//  masque_layer |= EDGE_LAYER; /* Les elements de la couche EDGE sont tj traces */
							 | 
						|
								
							 | 
						|
								    /* trace des elements type Drawings Pcb : */
							 | 
						|
								    PtStruct = m_Pcb->m_Drawings;
							 | 
						|
								    for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
							 | 
						|
								    {
							 | 
						|
								        switch( PtStruct->Type() )
							 | 
						|
								        {
							 | 
						|
								        case TYPEDRAWSEGMENT:
							 | 
						|
								            PlotDrawSegment( (DRAWSEGMENT*) PtStruct, PLOT_FORMAT_HPGL,
							 | 
						|
								                            masque_layer );
							 | 
						|
								            break;
							 | 
						|
								
							 | 
						|
								        case TYPETEXTE:
							 | 
						|
								            PlotTextePcb( (TEXTE_PCB*) PtStruct, PLOT_FORMAT_HPGL,
							 | 
						|
								                         masque_layer );
							 | 
						|
								            break;
							 | 
						|
								
							 | 
						|
								        case TYPECOTATION:
							 | 
						|
								            PlotCotation( (COTATION*) PtStruct, PLOT_FORMAT_HPGL,
							 | 
						|
								                         masque_layer );
							 | 
						|
								            break;
							 | 
						|
								
							 | 
						|
								        case TYPEMIRE:
							 | 
						|
								            PlotMirePcb( (MIREPCB*) PtStruct, PLOT_FORMAT_HPGL,
							 | 
						|
								                        masque_layer );
							 | 
						|
								            break;
							 | 
						|
								
							 | 
						|
								        case TYPEMARQUEUR:
							 | 
						|
								            break;
							 | 
						|
								
							 | 
						|
								        default:
							 | 
						|
								            DisplayError( this, wxT( "Type Draw non gere" ) );
							 | 
						|
								            break;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Trace des Elements des modules autres que pads */
							 | 
						|
								    nb_items = 0;
							 | 
						|
								    Affiche_1_Parametre( this, 48, wxT( "DrawMod" ), wxEmptyString, GREEN );
							 | 
						|
								    Module = m_Pcb->m_Modules;
							 | 
						|
								    for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
							 | 
						|
								    {
							 | 
						|
								        PtStruct = Module->m_Drawings;
							 | 
						|
								        for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
							 | 
						|
								        {
							 | 
						|
								            switch( PtStruct->Type() )
							 | 
						|
								            {
							 | 
						|
								            case TYPEEDGEMODULE:
							 | 
						|
								                if( masque_layer &
							 | 
						|
								                    g_TabOneLayerMask[ PtStruct->GetLayer() ] )
							 | 
						|
								                    Plot_1_EdgeModule( PLOT_FORMAT_HPGL, (EDGE_MODULE*) PtStruct );
							 | 
						|
								                break;
							 | 
						|
								
							 | 
						|
								            default:
							 | 
						|
								                break;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Trace des Elements des modules : Pastilles */
							 | 
						|
								    nb_items = 0;
							 | 
						|
								    Affiche_1_Parametre( this, 48, wxT( "Pads    " ), wxEmptyString, GREEN );
							 | 
						|
								    Module = m_Pcb->m_Modules;
							 | 
						|
								    for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
							 | 
						|
								    {
							 | 
						|
								        PtPad = (D_PAD*) Module->m_Pads;
							 | 
						|
								        for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Pnext )
							 | 
						|
								        {
							 | 
						|
								            wxPoint shape_pos;
							 | 
						|
								            if( (PtPad->m_Masque_Layer & masque_layer) == 0 )
							 | 
						|
								                continue;
							 | 
						|
								
							 | 
						|
								            shape_pos = PtPad->ReturnShapePos();
							 | 
						|
								            start   = shape_pos;
							 | 
						|
								            size    = PtPad->m_Size;
							 | 
						|
								            size.x += garde * 2; size.y += garde * 2;
							 | 
						|
								
							 | 
						|
								            nb_items++;
							 | 
						|
								
							 | 
						|
								            switch( PtPad->m_PadShape & 0x7F )
							 | 
						|
								            {
							 | 
						|
								            case CIRCLE:
							 | 
						|
								                trace_1_pastille_RONDE_HPGL( start, size.x, modetrace );
							 | 
						|
								                break;
							 | 
						|
								
							 | 
						|
								            case OVALE:
							 | 
						|
								            {
							 | 
						|
								                trace_1_pastille_OVALE_HPGL( start, size, PtPad->m_Orient, modetrace );
							 | 
						|
								                break;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            case TRAPEZE:
							 | 
						|
								            {
							 | 
						|
								                wxSize delta;
							 | 
						|
								                delta = PtPad->m_DeltaSize;
							 | 
						|
								                trace_1_pad_TRAPEZE_HPGL( start, size, delta,
							 | 
						|
								                                          PtPad->m_Orient, modetrace );
							 | 
						|
								                break;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            case RECT:
							 | 
						|
								            default:
							 | 
						|
								                PlotRectangularPad_HPGL( start, size,
							 | 
						|
								                                         PtPad->m_Orient, modetrace );
							 | 
						|
								                break;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            msg.Printf( wxT( "%d" ), nb_items );
							 | 
						|
								            Affiche_1_Parametre( this, 48, wxT( "Pads" ), msg, GREEN );
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* trace des VIAS : */
							 | 
						|
								    if( tracevia )
							 | 
						|
								    {
							 | 
						|
								        TRACK* pts;
							 | 
						|
								
							 | 
						|
								        nb_items = 0;
							 | 
						|
								        Affiche_1_Parametre( this, 56, wxT( "Vias" ), wxEmptyString, RED );
							 | 
						|
								
							 | 
						|
								        for( pts = m_Pcb->m_Track; pts != NULL; pts = (TRACK*) pts->Pnext )
							 | 
						|
								        {
							 | 
						|
								            if( pts->Type() != TYPEVIA )
							 | 
						|
								                continue;
							 | 
						|
								            SEGVIA* Via = (SEGVIA*) pts;
							 | 
						|
								
							 | 
						|
								            /* vias not plotted if not on selected layer, but if layer
							 | 
						|
								             *  == SOLDERMASK_LAYER_CU or SOLDERMASK_LAYER_CMP, vias are drawn ,
							 | 
						|
								             *  if they are on a external copper layer
							 | 
						|
								             */
							 | 
						|
								            int     via_mask_layer = Via->ReturnMaskLayer();
							 | 
						|
								            if( (via_mask_layer & CUIVRE_LAYER ) )
							 | 
						|
								                via_mask_layer |= SOLDERMASK_LAYER_CU;
							 | 
						|
								            if( (via_mask_layer & CMP_LAYER ) )
							 | 
						|
								                via_mask_layer |= SOLDERMASK_LAYER_CMP;
							 | 
						|
								            if( (via_mask_layer & masque_layer) == 0 )
							 | 
						|
								                continue;
							 | 
						|
								
							 | 
						|
								            start  = Via->m_Start;
							 | 
						|
								            size.x = Via->m_Width + (garde * 2);
							 | 
						|
								
							 | 
						|
								            trace_1_pastille_RONDE_HPGL( start, size.x, modetrace );
							 | 
						|
								            nb_items++; msg.Printf( wxT( "%d" ), nb_items );
							 | 
						|
								            Affiche_1_Parametre( this, 56, wxT( "Vias" ), msg, RED );
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        fputs( "PU;\n", dest );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* trace des segments pistes */
							 | 
						|
								    nb_items = 0;
							 | 
						|
								    Affiche_1_Parametre( this, 64, wxT( "Tracks  " ), wxEmptyString, YELLOW );
							 | 
						|
								    for( pts = m_Pcb->m_Track; pts != NULL; pts = (TRACK*) pts->Pnext )
							 | 
						|
								    {
							 | 
						|
								        if( pts->Type() == TYPEVIA )
							 | 
						|
								            continue;
							 | 
						|
								
							 | 
						|
								        if( (g_TabOneLayerMask[pts->GetLayer()] & masque_layer) == 0 )
							 | 
						|
								            continue;
							 | 
						|
								
							 | 
						|
								        size.x = size.y = pts->m_Width;
							 | 
						|
								        start  = pts->m_Start;
							 | 
						|
								        end    = pts->m_End;
							 | 
						|
								
							 | 
						|
								        if( size.x > pen_diam ) /* c.a.d si largeur piste > diam plume */
							 | 
						|
								            trace_1_pastille_RONDE_HPGL( start, size.x, modetrace );
							 | 
						|
								
							 | 
						|
								        /* Trace d'un segment de piste */
							 | 
						|
								        trace_1_segment_HPGL( start.x, start.y, end.x, end.y, size.x );
							 | 
						|
								        /* Complement de Trace en mode Remplissage */
							 | 
						|
								        if( (Plot_Mode == FILLED) && (pen_diam <= size.x ) )
							 | 
						|
								        {
							 | 
						|
								            while( ( size.x -= (int) ( (pen_rayon - pen_recouvrement) * 2 ) ) > 0 )
							 | 
						|
								            {
							 | 
						|
								                trace_1_segment_HPGL( start.x, start.y, end.x, end.y,
							 | 
						|
								                                     MAX( size.x, pen_diam ) );
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if( size.x > pen_diam )
							 | 
						|
								            trace_1_pastille_RONDE_HPGL( end, size.x, modetrace );
							 | 
						|
								
							 | 
						|
								        nb_items++; msg.Printf( wxT( "%d" ), nb_items );
							 | 
						|
								        Affiche_1_Parametre( this, 64, wxEmptyString, msg, YELLOW );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* trace des segments pistes et zones */
							 | 
						|
								    nb_items = 0;
							 | 
						|
								    Affiche_1_Parametre( this, 64, wxT( "Zones  " ), wxEmptyString, YELLOW );
							 | 
						|
								    for( pts = m_Pcb->m_Zone; pts != NULL; pts = (TRACK*) pts->Pnext )
							 | 
						|
								    {
							 | 
						|
								        if( g_TabOneLayerMask[pts->GetLayer()] & masque_layer )
							 | 
						|
								        {
							 | 
						|
								            size.x = size.y = pts->m_Width;
							 | 
						|
								            start  = pts->m_Start;
							 | 
						|
								            end    = pts->m_End;
							 | 
						|
								
							 | 
						|
								            if( size.x > pen_diam ) /* c.a.d si largeur piste > diam plume */
							 | 
						|
								                trace_1_pastille_RONDE_HPGL( start, size.x, modetrace );
							 | 
						|
								
							 | 
						|
								            /* Trace d'un segment de piste */
							 | 
						|
								            trace_1_segment_HPGL( start.x, start.y, end.x, end.y, size.x );
							 | 
						|
								            /* Complement de Trace en mode Remplissage */
							 | 
						|
								            if( (Plot_Mode == FILLED) && (pen_diam <= size.x ) )
							 | 
						|
								            {
							 | 
						|
								                while( ( size.x -= (int) ( (pen_rayon - pen_recouvrement) * 2 ) ) > 0 )
							 | 
						|
								                {
							 | 
						|
								                    trace_1_segment_HPGL( start.x, start.y, end.x, end.y,
							 | 
						|
								                                         MAX( size.x, pen_diam ) );
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            if( size.x > pen_diam )
							 | 
						|
								                trace_1_pastille_RONDE_HPGL( end, size.x, modetrace );
							 | 
						|
								
							 | 
						|
								            nb_items++; msg.Printf( wxT( "%d" ), nb_items );
							 | 
						|
								            Affiche_1_Parametre( this, 64, wxEmptyString, msg, YELLOW );
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/************************************************************************************/
							 | 
						|
								void trace_1_pastille_OVALE_HPGL( wxPoint pos, wxSize size, int orient, int modetrace )
							 | 
						|
								/************************************************************************************/
							 | 
						|
								/* Trace 1 pastille OVALE en position pos_X,Y , de dim size.x, size.y */
							 | 
						|
								{
							 | 
						|
								    int rayon, deltaxy, cx, cy;
							 | 
						|
								    int trace_orient = orient;
							 | 
						|
								
							 | 
						|
								    /* la pastille est ramenee a une pastille ovale avec size.y > size.x
							 | 
						|
								     *  ( ovale vertical en orientation 0 ) */
							 | 
						|
								    if( size.x > size.y )
							 | 
						|
								    {
							 | 
						|
								        EXCHG( size.x, size.y ); trace_orient += 900;
							 | 
						|
								        if( orient >= 3600 )
							 | 
						|
								            trace_orient -= 3600;
							 | 
						|
								    }
							 | 
						|
								    deltaxy = size.y - size.x; /* = distance entre centres de l'ovale */
							 | 
						|
								    rayon   = size.x / 2;
							 | 
						|
								
							 | 
						|
								    if( modetrace == FILLED )
							 | 
						|
								    {
							 | 
						|
								        PlotRectangularPad_HPGL( pos, wxSize( size.x, deltaxy ),
							 | 
						|
								                                 orient, modetrace );
							 | 
						|
								        cx = 0; cy = deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        trace_1_pastille_RONDE_HPGL( wxPoint( cx + pos.x, cy + pos.y ), size.x, modetrace );
							 | 
						|
								        Plume_HPGL( 'U' );
							 | 
						|
								        cx = 0; cy = -deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        trace_1_pastille_RONDE_HPGL( wxPoint( cx + pos.x, cy + pos.y ), size.x, modetrace );
							 | 
						|
								    }
							 | 
						|
								    else    /* Trace en mode FILAIRE */
							 | 
						|
								    {
							 | 
						|
								        cx = -rayon; cy = -deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'U' );
							 | 
						|
								        cx = -rayon; cy = deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'D' );
							 | 
						|
								
							 | 
						|
								        cx = rayon; cy = -deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'U' );
							 | 
						|
								        cx = rayon; cy = deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( cx + pos.x, cy + pos.y ), 'D' );
							 | 
						|
								        Plume_HPGL( 'U' );
							 | 
						|
								
							 | 
						|
								        cx = 0; cy = -deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        PlotArc( PLOT_FORMAT_HPGL, wxPoint( cx + pos.x, cy + pos.y ),
							 | 
						|
								                 trace_orient, trace_orient + 1800,
							 | 
						|
								                 size.x / 2, pen_diam );
							 | 
						|
								        cx = 0; cy = deltaxy / 2;
							 | 
						|
								        RotatePoint( &cx, &cy, trace_orient );
							 | 
						|
								        PlotArc( PLOT_FORMAT_HPGL, wxPoint( cx + pos.x, cy + pos.y ),
							 | 
						|
								                 trace_orient + 1800, trace_orient,
							 | 
						|
								                 size.x / 2, pen_diam );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    Plume_HPGL( 'U' );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**************************************************************************/
							 | 
						|
								void trace_1_pastille_RONDE_HPGL( wxPoint pos, int diametre, int modetrace )
							 | 
						|
								/**************************************************************************/
							 | 
						|
								/* Trace 1 pastille RONDE (via,pad rond) en position pos */
							 | 
						|
								{
							 | 
						|
								    int rayon, delta;
							 | 
						|
								
							 | 
						|
								    UserToDeviceCoordinate( pos );
							 | 
						|
								
							 | 
						|
								    delta = pen_diam - pen_recouvrement;
							 | 
						|
								    rayon = diametre / 2;
							 | 
						|
								    if( modetrace != FILAIRE )
							 | 
						|
								    {
							 | 
						|
								        rayon = (diametre - pen_diam ) / 2;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if( rayon < 0 )
							 | 
						|
								    {
							 | 
						|
								        rayon = 0; nb_plot_erreur++; Affiche_erreur( nb_plot_erreur );
							 | 
						|
								    }
							 | 
						|
								    wxSize rsize( rayon, rayon );
							 | 
						|
								
							 | 
						|
								    UserToDeviceSize( rsize );
							 | 
						|
								
							 | 
						|
								    Plume_HPGL( 'U' );
							 | 
						|
								    sprintf( cbuf, "PA %d,%d;CI %d;\n", pos.x, pos.y, rsize.x );
							 | 
						|
								    fputs( cbuf, dest );
							 | 
						|
								    if( modetrace == FILLED ) /* Trace en mode Remplissage */
							 | 
						|
								    {
							 | 
						|
								        if( delta > 0 )
							 | 
						|
								        {
							 | 
						|
								            while( (rayon -= delta ) >= 0 )
							 | 
						|
								            {
							 | 
						|
								                rsize.x = rsize.y = rayon;
							 | 
						|
								                UserToDeviceSize( rsize );
							 | 
						|
								                sprintf( cbuf, "PA %d,%d; CI %d;\n", pos.x, pos.y, rsize.x );
							 | 
						|
								                fputs( cbuf, dest );
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    Plume_HPGL( 'U' ); return;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/***************************************************************/
							 | 
						|
								void PlotRectangularPad_HPGL( wxPoint padpos, wxSize padsize,
							 | 
						|
								                              int orient, int modetrace )
							 | 
						|
								/****************************************************************/
							 | 
						|
								
							 | 
						|
								/*
							 | 
						|
								 *  Trace 1 pad rectangulaire vertical ou horizontal ( Pad rectangulaire )
							 | 
						|
								 *  donne par son centre et ses dimensions X et Y
							 | 
						|
								 *  Units are user units
							 | 
						|
								 */
							 | 
						|
								{
							 | 
						|
								    wxSize size;
							 | 
						|
								    int    delta;
							 | 
						|
								    int    ox, oy, fx, fy;
							 | 
						|
								
							 | 
						|
								    size.x = padsize.x / 2;  size.y = padsize.y / 2;
							 | 
						|
								    if( modetrace != FILAIRE )
							 | 
						|
								    {
							 | 
						|
								        size.x = (padsize.x - (int) pen_diam) / 2;
							 | 
						|
								        size.y = (padsize.y - (int) pen_diam) / 2;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if( (size.x < 0 ) || (size.y < 0) )
							 | 
						|
								    {
							 | 
						|
								        nb_plot_erreur++; Affiche_erreur( nb_plot_erreur );
							 | 
						|
								    }
							 | 
						|
								    if( size.x < 0 )
							 | 
						|
								        size.x = 0;if( size.y < 0 )
							 | 
						|
								        size.y = 0;
							 | 
						|
								
							 | 
						|
								    /* Si une des dimensions est nulle, le trace se reduit a 1 trait */
							 | 
						|
								    if( size.x == 0 )
							 | 
						|
								    {
							 | 
						|
								        ox = padpos.x; oy = padpos.y - size.y;
							 | 
						|
								        RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
							 | 
						|
								        fx = padpos.x; fy = padpos.y + size.y;
							 | 
						|
								        RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( ox, oy ), 'U' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								        Plume_HPGL( 'U' ); return;
							 | 
						|
								    }
							 | 
						|
								    if( size.y == 0 )
							 | 
						|
								    {
							 | 
						|
								        ox = padpos.x - size.x; oy = padpos.y;
							 | 
						|
								        RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
							 | 
						|
								        fx = padpos.x + size.x; fy = padpos.y;
							 | 
						|
								        RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( ox, oy ), 'U' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								        Plume_HPGL( 'U' ); return;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    ox = padpos.x - size.x; oy = padpos.y - size.y;
							 | 
						|
								    RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
							 | 
						|
								    Move_Plume_HPGL( wxPoint( ox, oy ), 'U' );
							 | 
						|
								
							 | 
						|
								    fx = padpos.x - size.x; fy = padpos.y + size.y;
							 | 
						|
								    RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								    Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								
							 | 
						|
								    fx = padpos.x + size.x; fy = padpos.y + size.y;
							 | 
						|
								    RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								    Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								
							 | 
						|
								    fx = padpos.x + size.x; fy = padpos.y - size.y;
							 | 
						|
								    RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								    Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								
							 | 
						|
								    Move_Plume_HPGL( wxPoint( ox, oy ), 'D' );
							 | 
						|
								
							 | 
						|
								    if( modetrace != FILLED )
							 | 
						|
								    {
							 | 
						|
								        Plume_HPGL( 'U' ); return;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Trace en mode Remplissage */
							 | 
						|
								    delta = (int) (pen_diam - pen_recouvrement);
							 | 
						|
								    if( delta > 0 )
							 | 
						|
								        while( (size.x > 0) && (size.y > 0) )
							 | 
						|
								        {
							 | 
						|
								            size.x -= delta; size.y -= delta;
							 | 
						|
								            if( size.x < 0 )
							 | 
						|
								                size.x = 0;if( size.y < 0 )
							 | 
						|
								                size.y = 0;
							 | 
						|
								
							 | 
						|
								            ox = padpos.x - size.x; oy = padpos.y - size.y;
							 | 
						|
								            RotatePoint( &ox, &oy, padpos.x, padpos.y, orient );
							 | 
						|
								            Move_Plume_HPGL( wxPoint( ox, oy ), 'D' );
							 | 
						|
								
							 | 
						|
								            fx = padpos.x - size.x; fy = padpos.y + size.y;
							 | 
						|
								            RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								            Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								
							 | 
						|
								            fx = padpos.x + size.x; fy = padpos.y + size.y;
							 | 
						|
								            RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								            Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								
							 | 
						|
								            fx = padpos.x + size.x; fy = padpos.y - size.y;
							 | 
						|
								            RotatePoint( &fx, &fy, padpos.x, padpos.y, orient );
							 | 
						|
								            Move_Plume_HPGL( wxPoint( fx, fy ), 'D' );
							 | 
						|
								
							 | 
						|
								            Move_Plume_HPGL( wxPoint( ox, oy ), 'D' );
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    Plume_HPGL( 'U' );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/********************************************************************/
							 | 
						|
								void trace_1_pad_TRAPEZE_HPGL( wxPoint padpos, wxSize size, wxSize delta,
							 | 
						|
								                               int orient, int modetrace )
							 | 
						|
								/********************************************************************/
							 | 
						|
								
							 | 
						|
								/*
							 | 
						|
								 *  Trace 1 pad trapezoidal donne par :
							 | 
						|
								 *  son centre padpos.x,padpos.y
							 | 
						|
								 *  ses dimensions dimX et dimY
							 | 
						|
								 *  les variations deltaX et deltaY
							 | 
						|
								 *  son orientation orient et 0.1 degres
							 | 
						|
								 *  le mode de trace (FILLED, SKETCH, FILAIRE)
							 | 
						|
								 *  Le trace n'est fait que pour un trapeze, c.a.d que deltaX ou deltaY
							 | 
						|
								 *  = 0.
							 | 
						|
								 * 
							 | 
						|
								 *  les notation des sommets sont ( vis a vis de la table tracante )
							 | 
						|
								 *      0 ------------- 3
							 | 
						|
								 *        .			   .
							 | 
						|
								 *          .		  .
							 | 
						|
								 *           .		 .
							 | 
						|
								 *            1 --- 2
							 | 
						|
								 */
							 | 
						|
								{
							 | 
						|
								    int     ii, jj;
							 | 
						|
								    wxPoint polygone[4];    /* coord des sommets / centre du pad */
							 | 
						|
								    wxPoint coord[4];       /* coord reelles des sommets du trapeze a tracer */
							 | 
						|
								    float   fangle;         /* angle d'inclinaison des cotes du trapeze */
							 | 
						|
								    int     rayon;          /* rayon de la plume */
							 | 
						|
								    int     moveX, moveY;/* variation de position plume selon axe X et Y , lors
							 | 
						|
								                     *  du remplissage du trapeze */
							 | 
						|
								
							 | 
						|
								    rayon = (int) pen_rayon; if( modetrace == FILAIRE )
							 | 
						|
								        rayon = 0;
							 | 
						|
								    moveX = moveY = rayon;
							 | 
						|
								
							 | 
						|
								    size.x  /= 2;  size.y /= 2;
							 | 
						|
								    delta.x /= 2; delta.y /= 2;
							 | 
						|
								
							 | 
						|
								    polygone[0].x = -size.x - delta.y; polygone[0].y = +size.y + delta.x;
							 | 
						|
								    polygone[1].x = -size.x + delta.y; polygone[1].y = -size.y - delta.x;
							 | 
						|
								    polygone[2].x = +size.x - delta.y; polygone[2].y = -size.y + delta.x;
							 | 
						|
								    polygone[3].x = +size.x + delta.y; polygone[3].y = +size.y - delta.x;
							 | 
						|
								
							 | 
						|
								    /* Calcul du demi angle d'inclinaison des cotes du trapeze */
							 | 
						|
								    if( delta.y ) /* Trapeze horizontal */
							 | 
						|
								    {
							 | 
						|
								        fangle = atan2( (float) (polygone[1].y - polygone[0].y),
							 | 
						|
								                       (float) (polygone[1].x - polygone[0].x) ) / 2;
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        fangle = atan2( (float) (polygone[3].y - polygone[0].y),
							 | 
						|
								                       (float) (polygone[3].x - polygone[0].x) ) / 2;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Trace du contour */
							 | 
						|
								    polygone[0].x += moveX; polygone[0].y -= moveY;
							 | 
						|
								    polygone[1].x += moveX; polygone[1].y += moveY;
							 | 
						|
								    polygone[2].x -= moveX; polygone[2].y += moveY;
							 | 
						|
								    polygone[3].x -= moveX; polygone[3].y -= moveY;
							 | 
						|
								
							 | 
						|
								    for( ii = 0; ii < 4; ii++ )
							 | 
						|
								    {
							 | 
						|
								        coord[ii].x = polygone[ii].x + padpos.x;
							 | 
						|
								        coord[ii].y = polygone[ii].y + padpos.y;
							 | 
						|
								        RotatePoint( &coord[ii], padpos, orient );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    // Plot edge:
							 | 
						|
								    Move_Plume_HPGL( coord[0], 'U' );
							 | 
						|
								    Move_Plume_HPGL( coord[1], 'D' );
							 | 
						|
								    Move_Plume_HPGL( coord[2], 'D' );
							 | 
						|
								    Move_Plume_HPGL( coord[3], 'D' );
							 | 
						|
								    Move_Plume_HPGL( coord[0], 'D' );
							 | 
						|
								
							 | 
						|
								    if( modetrace != FILLED )
							 | 
						|
								    {
							 | 
						|
								        Plume_HPGL( 'U' ); return;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Fill the shape */
							 | 
						|
								
							 | 
						|
								    moveX = moveY = pen_diam - pen_recouvrement;
							 | 
						|
								    /* calcul de jj = hauteur du remplissage */
							 | 
						|
								    if( delta.y ) /* Trapeze horizontal */
							 | 
						|
								    {
							 | 
						|
								        jj = size.y - (int) ( pen_diam + (2 * pen_recouvrement) );
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        jj = size.x - (int) ( pen_diam + (2 * pen_recouvrement) );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Calcul de jj = nombre de segments a tracer pour le remplissage */
							 | 
						|
								    jj = jj / (int) (pen_diam - pen_recouvrement);
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								    /* Trace du contour */
							 | 
						|
								    for( ; jj > 0; jj-- )
							 | 
						|
								    {
							 | 
						|
								        polygone[0].x += moveX; polygone[0].y -= moveY;
							 | 
						|
								        polygone[1].x += moveX; polygone[1].y += moveY;
							 | 
						|
								        polygone[2].x -= moveX; polygone[2].y += moveY;
							 | 
						|
								        polygone[3].x -= moveX; polygone[3].y -= moveY;
							 | 
						|
								
							 | 
						|
								        /* Test de limitation de variation des dimensions :
							 | 
						|
								         *  si les sommets se "croisent", il ne faut plus modifier les
							 | 
						|
								         *  coordonnees correspondantes */
							 | 
						|
								        if( polygone[0].x > polygone[3].x )
							 | 
						|
								        {  /* croisement sur axe X des 2 sommets 0 et 3 */
							 | 
						|
								            polygone[0].x = polygone[3].x = 0;
							 | 
						|
								        }
							 | 
						|
								        if( polygone[1].x > polygone[2].x )
							 | 
						|
								        {  /* croisement sur axe X des 2 sommets 1 et 2 */
							 | 
						|
								            polygone[1].x = polygone[2].x = 0;
							 | 
						|
								        }
							 | 
						|
								        if( polygone[1].y > polygone[0].y )
							 | 
						|
								        {  /* croisement sur axe Y des 2 sommets 0 et 1 */
							 | 
						|
								            polygone[0].y = polygone[1].y = 0;
							 | 
						|
								        }
							 | 
						|
								        if( polygone[2].y > polygone[3].y )
							 | 
						|
								        {  /* croisement sur axe Y des 2 sommets 2 et 3 */
							 | 
						|
								            polygone[2].y = polygone[3].y = 0;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        for( ii = 0; ii < 4; ii++ )
							 | 
						|
								        {
							 | 
						|
								            coord[ii].x = polygone[ii].x + padpos.x;
							 | 
						|
								            coord[ii].y = polygone[ii].y + padpos.y;
							 | 
						|
								            RotatePoint( &coord[ii], padpos, orient );
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        Move_Plume_HPGL( coord[0], 'U' );
							 | 
						|
								        Move_Plume_HPGL( coord[1], 'D' );
							 | 
						|
								        Move_Plume_HPGL( coord[2], 'D' );
							 | 
						|
								        Move_Plume_HPGL( coord[3], 'D' );
							 | 
						|
								        Move_Plume_HPGL( coord[0], 'D' );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    Plume_HPGL( 'U' );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/********************************************************************/
							 | 
						|
								void trace_1_segment_HPGL( int pos_X0, int pos_Y0, int pos_X1, int pos_Y1,
							 | 
						|
								                           int epaisseur )
							 | 
						|
								/********************************************************************/
							 | 
						|
								
							 | 
						|
								/* Trace 1 rectangle donne par son axe et son epaisseur (piste rectangulaire)
							 | 
						|
								 *  en mode SKETCH
							 | 
						|
								 */
							 | 
						|
								{
							 | 
						|
								    float  alpha;   /* angle de l'axe du rectangle */
							 | 
						|
								    wxSize size;    /* coord relatives a l'origine du segment de sa fin */
							 | 
						|
								    int    dh;      /* demi epaisseur du segment compte tenu de la
							 | 
						|
								                     *  largeur de la plume */
							 | 
						|
								    int    dx_rot;  /* coord du segment en repere modifie ( size.y_rot etant nul )*/
							 | 
						|
								    float  sin_alpha, cos_alpha;
							 | 
						|
								
							 | 
						|
								    size.x = pos_X1 - pos_X0; size.y = pos_Y1 - pos_Y0;
							 | 
						|
								    dh = (epaisseur - (int) pen_diam ) / 2;
							 | 
						|
								    if( dh < 0 )
							 | 
						|
								    {
							 | 
						|
								        dh = 0; nb_plot_erreur++; Affiche_erreur( nb_plot_erreur );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if( (dh == 0) || (Plot_Mode == FILAIRE) )  /* Le trace se reduit a 1 trait */
							 | 
						|
								    {
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0, pos_Y0 ), 'U' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X1, pos_Y1 ), 'D' );
							 | 
						|
								        Plume_HPGL( 'U' );
							 | 
						|
								        return;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if( size.x < 0 )
							 | 
						|
								    {
							 | 
						|
								        EXCHG( pos_X0, pos_X1 );  EXCHG( pos_Y0, pos_Y1 );
							 | 
						|
								        size.y = -size.y; size.x = -size.x;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if( size.y == 0 )  /* segment horizontal */
							 | 
						|
								    {
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0, pos_Y0 - dh ), 'U' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X1, pos_Y1 - dh ), 'D' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X1, pos_Y1 + dh ), 'D' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0, pos_Y0 + dh ), 'D' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0, pos_Y0 - dh ), 'D' );
							 | 
						|
								    }
							 | 
						|
								    else if( size.x == 0 )  /* vertical */
							 | 
						|
								    {
							 | 
						|
								        if( size.y < 0 )
							 | 
						|
								            dh = -dh;
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 - dh, pos_Y0 ), 'U' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X1 - dh, pos_Y1 ), 'D' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X1 + dh, pos_Y1 ), 'D' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 + dh, pos_Y0 ), 'D' );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 - dh, pos_Y0 ), 'D' );
							 | 
						|
								    }
							 | 
						|
								    else    /* piste inclinee */
							 | 
						|
								    {
							 | 
						|
								        /* On calcule les coord des extremites du rectangle dans le repere
							 | 
						|
								         *  a axe x confondu avec l'axe du rect. puis on revient dans le repere
							 | 
						|
								         *  de trace par 2 rotations inverses
							 | 
						|
								         *   coord :  xrot = x*cos + y*sin
							 | 
						|
								         *            yrot = y*cos - x*sin
							 | 
						|
								         * 
							 | 
						|
								         *  avec ici yrot = 0 puisque le segment est horizontal dans le nouveau repere
							 | 
						|
								         *  Transformee inverse :
							 | 
						|
								         *   coord :  x = xrot*cos - yrot*sin
							 | 
						|
								         *            y = yrot*cos + xrot*sin
							 | 
						|
								         */
							 | 
						|
								
							 | 
						|
								        int dx0, dy0, dx1, dy1;
							 | 
						|
								
							 | 
						|
								        if( size.x == size.y ) /* alpah = 45 degre */
							 | 
						|
								        {
							 | 
						|
								            sin_alpha = cos_alpha = 0.70711;
							 | 
						|
								        }
							 | 
						|
								        else if( size.x == -size.y ) /* alpah = -45 degre */
							 | 
						|
								        {
							 | 
						|
								            cos_alpha = 0.70711; sin_alpha = -0.70711;
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								        {
							 | 
						|
								            alpha     = atan2( (float) size.y, (float) size.x );
							 | 
						|
								            sin_alpha = sin( alpha );
							 | 
						|
								            cos_alpha = cos( alpha );
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        dx_rot = (int) (size.x * cos_alpha + size.y * sin_alpha);
							 | 
						|
								        /* size.y_rot = (int)(size.y * cos_alpha - size.x * sin_alpha) ; doit etre NULL */
							 | 
						|
								
							 | 
						|
								        /* calcul du point de coord 0,-dh */
							 | 
						|
								        dx0 = (int) ( dh * sin_alpha);
							 | 
						|
								        dy0 = (int) (-dh * cos_alpha );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 + dx0, pos_Y0 + dy0 ), 'U' );
							 | 
						|
								
							 | 
						|
								        /* calcul du point de coord size.xrot,-dh */
							 | 
						|
								        dx1 = (int) (dx_rot * cos_alpha + dh * sin_alpha);
							 | 
						|
								        dy1 = (int) (-dh * cos_alpha + dx_rot * sin_alpha );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 + dx1, pos_Y0 + dy1 ), 'D' );
							 | 
						|
								
							 | 
						|
								        /* calcul du point de coord size.xrot,+dh */
							 | 
						|
								        dx1 = (int) (dx_rot * cos_alpha - dh * sin_alpha);
							 | 
						|
								        dy1 = (int) (dh * cos_alpha + dx_rot * sin_alpha );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 + dx1, pos_Y0 + dy1 ), 'D' );
							 | 
						|
								
							 | 
						|
								        /* calcul du point de coord 0,+dh */
							 | 
						|
								        dx1 = (int) ( -dh * sin_alpha);
							 | 
						|
								        dy1 = (int) (dh * cos_alpha );
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 + dx1, pos_Y0 + dy1 ), 'D' );
							 | 
						|
								
							 | 
						|
								        /* retour au point de depart */
							 | 
						|
								        Move_Plume_HPGL( wxPoint( pos_X0 + dx0, pos_Y0 + dy0 ), 'D' );
							 | 
						|
								    }
							 | 
						|
								    Plume_HPGL( 'U' );
							 | 
						|
								}
							 |