714 lines
20 KiB
C++
714 lines
20 KiB
C++
/*************************************/
|
|
/**** Pcbnew: Routine de trace PS ****/
|
|
/*************************************/
|
|
|
|
#include "fctsys.h"
|
|
#include "gr_basic.h"
|
|
|
|
#include "common.h"
|
|
#include "plot_common.h"
|
|
#include "pcbnew.h"
|
|
#include "pcbplot.h"
|
|
#include "trigo.h"
|
|
|
|
#include "protos.h"
|
|
|
|
/* Routines Locales */
|
|
static void PrintDrillMark(BOARD * Pcb);
|
|
static Ki_PageDescr * SheetPS;
|
|
|
|
/* variables locales: */
|
|
|
|
#define DRILL_MARK 1
|
|
|
|
/****************************************************************************/
|
|
void WinEDA_BasePcbFrame::Genere_PS(const wxString & FullFileName, int Layer)
|
|
/****************************************************************************/
|
|
/* Genere un fichier POSTSCRIPT (*.ps) de trace du circuit, couche layer
|
|
if layer < 0: all layers
|
|
*/
|
|
{
|
|
int modetrace, tracevia;
|
|
wxSize PcbSheetSize;
|
|
wxSize PaperSize;
|
|
wxSize BoardSize;
|
|
wxPoint BoardCenter;
|
|
bool Center = FALSE;
|
|
Ki_PageDescr * currentsheet = m_CurrentScreen->m_CurrentSheet;
|
|
double scale_format; // Facteur correctif pour conversion forlat Ax->A4
|
|
double scale_x, scale_y;
|
|
int PlotMarge_in_mils = 0;
|
|
|
|
MsgPanel->EraseMsgBox();
|
|
|
|
dest = wxFopen(FullFileName, wxT("wt") );
|
|
if (dest == NULL)
|
|
{
|
|
wxString msg = _("Unable to create file ") + FullFileName;
|
|
DisplayError(this, msg); return ;
|
|
}
|
|
|
|
Affiche_1_Parametre(this, 0,_("File"),FullFileName,CYAN) ;
|
|
|
|
if( g_PlotScaleOpt != 1 ) Center = TRUE; // Echelle != 1 donc trace centree du PCB
|
|
modetrace = Plot_Mode;
|
|
scale_format = 1.0;
|
|
/* Set default line width */
|
|
if( g_PlotLine_Width < 1 ) g_PlotLine_Width = 1;
|
|
// calcul en unites internes des dimensions des feuilles ( connues en 1/1000 pouce )
|
|
PcbSheetSize.x = currentsheet->m_Size.x * U_PCB;
|
|
PcbSheetSize.y = currentsheet->m_Size.y * U_PCB;
|
|
if ( g_ForcePlotPS_On_A4 )
|
|
{
|
|
SheetPS = &g_Sheet_A4;
|
|
PaperSize.x = g_Sheet_A4.m_Size.x * U_PCB;
|
|
PaperSize.y = g_Sheet_A4.m_Size.y * U_PCB;
|
|
scale_format = (float) PaperSize.x / PcbSheetSize.x;
|
|
}
|
|
else
|
|
{
|
|
SheetPS = currentsheet;
|
|
PaperSize = PcbSheetSize;
|
|
}
|
|
|
|
// calcul de l'offset de trace:
|
|
// calcul du cadrage horizontal du mode paysage( val algebr. plus grande = decalage a gauche )
|
|
g_PlotOffset.x = PlotMarge_in_mils * 10;
|
|
// cadrage vertical du mode paysage( val algebr. plus grande = decalage vers le haut )
|
|
g_PlotOffset.y = PaperSize.y - (PlotMarge_in_mils*10);
|
|
|
|
int BBox[4];
|
|
BBox[0] = BBox[1] = PlotMarge_in_mils;
|
|
BBox[2] = SheetPS->m_Size.x - PlotMarge_in_mils;
|
|
BBox[3] = SheetPS->m_Size.y - PlotMarge_in_mils;
|
|
scale_x = scale_y = 1.0;
|
|
InitPlotParametresPS( g_PlotOffset, SheetPS, 1.0/m_InternalUnits, 1.0/m_InternalUnits);
|
|
SetDefaultLineWidthPS(g_PlotLine_Width);
|
|
PrintHeaderPS(dest, wxT("PCBNEW-PS"), FullFileName, BBox);
|
|
|
|
if ( Plot_Sheet_Ref )
|
|
{
|
|
int tmp = g_PlotOrient; g_PlotOrient = 0;
|
|
SetPlotScale( 1.0, 1.0);
|
|
PlotWorkSheet( PLOT_FORMAT_POST, 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();
|
|
|
|
scale_x = Scale_X; scale_y = Scale_Y;
|
|
if( g_PlotScaleOpt == 0 ) // Optimum scale
|
|
{
|
|
float Xscale, Yscale;
|
|
int noprint_size = 2 * PlotMarge_in_mils * U_PCB;
|
|
if ( Plot_Sheet_Ref ) noprint_size += 500 * U_PCB;
|
|
Xscale = (float) (PaperSize.x - noprint_size ) / BoardSize.x;
|
|
Yscale = (float) (PaperSize.y - noprint_size ) / BoardSize.y;
|
|
scale_x = scale_y = min( Xscale, Yscale);
|
|
}
|
|
|
|
BoardCenter.x = (int) (BoardCenter.x * scale_x);
|
|
BoardCenter.y = (int) (BoardCenter.y * scale_y);
|
|
|
|
/* Calcul du cadrage (echelle != 1 donc recadrage du trace) */
|
|
if ( Center )
|
|
{
|
|
g_PlotOffset.x -= PaperSize.x/2 - BoardCenter.x + (PlotMarge_in_mils*10);
|
|
g_PlotOffset.y = PaperSize.y/2 + BoardCenter.y; // cadrage horizontal du mode paysage
|
|
}
|
|
|
|
if ( g_PlotOrient == PLOT_MIROIR )
|
|
{
|
|
if ( Center ) g_PlotOffset.y = - PaperSize.y/2 + BoardCenter.y;
|
|
else g_PlotOffset.y = - PaperSize.y +
|
|
(m_Pcb->m_BoundaryBox.GetBottom() + m_Pcb->m_BoundaryBox.GetY())
|
|
+ (PlotMarge_in_mils*10) ;
|
|
}
|
|
|
|
InitPlotParametresPS( g_PlotOffset, SheetPS, scale_x, scale_y, g_PlotOrient);
|
|
|
|
// If plot a negative board:
|
|
// Draw a black rectangle (background for plot board in white )
|
|
// and switch the current color to WHITE
|
|
if( g_Plot_PS_Negative)
|
|
{
|
|
int Rectangle[10]; // Put here the board corners
|
|
int margin = 500; // Add a 0.1 inch margin around the board
|
|
Rectangle[0] = m_Pcb->m_BoundaryBox.GetX() - margin;
|
|
Rectangle[1] = m_Pcb->m_BoundaryBox.GetY() - margin;
|
|
Rectangle[2] = m_Pcb->m_BoundaryBox.GetRight() + margin;
|
|
Rectangle[3] = Rectangle[1];
|
|
Rectangle[4] = Rectangle[2];
|
|
Rectangle[5] = m_Pcb->m_BoundaryBox.GetBottom() + margin;
|
|
Rectangle[6] = Rectangle[0];
|
|
Rectangle[7] = Rectangle[5];
|
|
Rectangle[8] = Rectangle[0];
|
|
Rectangle[9] = Rectangle[1];
|
|
SetColorMapPS(BLACK);
|
|
PlotPolyPS( 5, Rectangle, TRUE);
|
|
SetColorMapPS(WHITE);
|
|
}
|
|
|
|
switch(Layer)
|
|
{
|
|
case -1:
|
|
Plot_Layer_PS(dest, g_TabOneLayerMask[Layer], 0, 1, modetrace);
|
|
break;
|
|
|
|
case CUIVRE_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_PS(dest, g_TabOneLayerMask[Layer], 0, 1, modetrace);
|
|
break;
|
|
|
|
case SILKSCREEN_N_CU :
|
|
case SILKSCREEN_N_CMP :
|
|
Plot_Serigraphie(PLOT_FORMAT_POST, dest, g_TabOneLayerMask[Layer]);
|
|
break;
|
|
|
|
case SOLDERMASK_N_CU :
|
|
case SOLDERMASK_N_CMP : /* Trace du vernis epargne */
|
|
if (g_DrawViaOnMaskLayer) tracevia = 1;
|
|
else tracevia = 0;
|
|
Plot_Layer_PS(dest, g_TabOneLayerMask[Layer], g_DesignSettings.m_MaskMargin,
|
|
tracevia, modetrace);
|
|
break;
|
|
|
|
case SOLDERPASTE_N_CU :
|
|
case SOLDERPASTE_N_CMP : /* Trace du masque de pate de soudure */
|
|
Plot_Layer_PS(dest, g_TabOneLayerMask[Layer], 0, 0, modetrace);
|
|
break;
|
|
|
|
default:
|
|
Plot_Serigraphie(PLOT_FORMAT_POST,dest, g_TabOneLayerMask[Layer]);
|
|
break;
|
|
}
|
|
/* fin */
|
|
CloseFilePS(dest) ;
|
|
}
|
|
|
|
|
|
/********************************************************************/
|
|
void WinEDA_BasePcbFrame::Plot_Layer_PS(FILE * File,int masque_layer,
|
|
int garde, int tracevia, int modetrace)
|
|
/********************************************************************/
|
|
/* Trace en format POSTSCRIPT d'une couche cuivre ou masque */
|
|
{
|
|
wxPoint pos, end;
|
|
wxSize size;
|
|
MODULE * Module;
|
|
D_PAD * PtPad;
|
|
TRACK * pts ;
|
|
EDA_BaseStruct * PtStruct;
|
|
wxString msg;
|
|
|
|
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->Pnext )
|
|
{
|
|
switch( PtStruct->m_StructType )
|
|
{
|
|
case TYPEDRAWSEGMENT:
|
|
PlotDrawSegment( (DRAWSEGMENT*) PtStruct, PLOT_FORMAT_POST,
|
|
masque_layer);
|
|
break;
|
|
|
|
case TYPETEXTE:
|
|
PlotTextePcb((TEXTE_PCB*) PtStruct,PLOT_FORMAT_POST,
|
|
masque_layer);
|
|
break;
|
|
|
|
case TYPECOTATION:
|
|
PlotCotation((COTATION*) PtStruct, PLOT_FORMAT_POST,
|
|
masque_layer);
|
|
break;
|
|
|
|
case TYPEMIRE:
|
|
PlotMirePcb((MIREPCB*) PtStruct, PLOT_FORMAT_POST,
|
|
masque_layer);
|
|
break;
|
|
|
|
case TYPEMARQUEUR:
|
|
break;
|
|
|
|
default:
|
|
DisplayError(this, wxT("WinEDA_BasePcbFrame::Plot_Layer_PS() : Unexpected Draw Type"));
|
|
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->Pnext )
|
|
{
|
|
switch( PtStruct->m_StructType )
|
|
{
|
|
case TYPEEDGEMODULE:
|
|
if( masque_layer &
|
|
g_TabOneLayerMask[((EDGE_MODULE*)PtStruct)->m_Layer] )
|
|
Plot_1_EdgeModule(PLOT_FORMAT_POST, (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 )
|
|
{
|
|
if( (PtPad->m_Masque_Layer & masque_layer) == 0)
|
|
continue ;
|
|
wxPoint shape_pos = PtPad->ReturnShapePos();
|
|
pos = shape_pos;
|
|
|
|
size.x = PtPad->m_Size.x + (garde * 2) ;
|
|
size.y = PtPad->m_Size.y + (garde * 2) ;
|
|
|
|
nb_items++ ;
|
|
|
|
switch (PtPad->m_PadShape)
|
|
{
|
|
case CIRCLE :
|
|
trace_1_pastille_RONDE_POST(pos,size.x, modetrace) ;
|
|
break ;
|
|
|
|
case OVALE :
|
|
{
|
|
trace_1_pastille_OVALE_POST(pos,size, PtPad->m_Orient, modetrace);
|
|
break ;
|
|
}
|
|
|
|
case TRAPEZE :
|
|
{
|
|
wxSize delta;
|
|
delta = PtPad->m_DeltaSize;
|
|
trace_1_pad_TRAPEZE_POST(pos,size,delta,
|
|
PtPad->m_Orient, modetrace) ;
|
|
break ;
|
|
}
|
|
|
|
case RECT:
|
|
default:
|
|
trace_1_pad_rectangulaire_POST(pos,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)
|
|
{
|
|
nb_items = 0 ;
|
|
Affiche_1_Parametre(this, 56,_("Vias"),wxEmptyString,RED) ;
|
|
for( pts = m_Pcb->m_Track;pts != NULL; pts = pts->Next())
|
|
{
|
|
if( pts->m_StructType != 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;
|
|
|
|
pos = Via->m_Start;
|
|
size.x = size.y = Via->m_Width + (garde*2);
|
|
trace_1_pastille_RONDE_POST(pos,size.x, modetrace) ;
|
|
nb_items++ ; msg.Printf( wxT("%d"),nb_items) ;
|
|
Affiche_1_Parametre(this, 56,wxEmptyString,msg,RED) ;
|
|
}
|
|
}
|
|
/* trace des pistes et zones: */
|
|
nb_items = 0 ;
|
|
Affiche_1_Parametre(this, 64,_("Tracks"),wxEmptyString,YELLOW) ;
|
|
|
|
for( pts = m_Pcb->m_Track; pts != NULL; pts = (TRACK*) pts->Pnext)
|
|
{
|
|
if ( pts->m_StructType == TYPEVIA ) continue ;
|
|
|
|
if( (g_TabOneLayerMask[pts->m_Layer] & masque_layer) == 0 ) continue;
|
|
size.x = size.y = pts->m_Width;
|
|
pos = pts->m_Start; end = pts->m_End;
|
|
|
|
PlotFilledSegmentPS(pos,end, size.x);
|
|
|
|
nb_items++ ; msg.Printf( wxT("%d"),nb_items) ;
|
|
Affiche_1_Parametre(this, 64,wxEmptyString,msg,YELLOW) ;
|
|
}
|
|
|
|
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->m_Layer] & masque_layer) == 0 ) continue;
|
|
size.x = size.y = pts->m_Width;
|
|
pos = pts->m_Start; end = pts->m_End;
|
|
PlotFilledSegmentPS(pos,end, size.x);
|
|
nb_items++ ; msg.Printf( wxT("%d"),nb_items) ;
|
|
Affiche_1_Parametre(this, 64,wxEmptyString,msg,YELLOW) ;
|
|
}
|
|
|
|
/* Trace des trous de percage */
|
|
if( modetrace == FILLED )
|
|
{
|
|
PrintDrillMark(m_Pcb);
|
|
}
|
|
}
|
|
|
|
|
|
/*************************************/
|
|
static void PrintDrillMark(BOARD * Pcb)
|
|
/*************************************/
|
|
/* Draw a drill mark for pads and vias.
|
|
Must be called after all drawings, because it redraw the drill mark
|
|
on a pad or via
|
|
*/
|
|
{
|
|
#define SMALL_DRILL 150
|
|
wxPoint pos;
|
|
wxSize diam;
|
|
MODULE * Module;
|
|
D_PAD * PtPad;
|
|
TRACK * pts ;
|
|
|
|
if (g_DrillShapeOpt == 0 ) return;
|
|
|
|
if ( g_Plot_PS_Negative ) fprintf(dest," 0 setgray\n");
|
|
else fprintf(dest," 1 setgray\n");
|
|
|
|
diam.x = diam.y = (g_DrillShapeOpt == DRILL_MARK) ? SMALL_DRILL :
|
|
g_DesignSettings.m_ViaDrill;
|
|
|
|
for( pts = Pcb->m_Track;pts != NULL; pts = (TRACK*)pts->Pnext)
|
|
{
|
|
if( pts->m_StructType != TYPEVIA ) continue;
|
|
pos = pts->m_Start;
|
|
if (g_DrillShapeOpt == DRILL_MARK) diam.x = diam.y = SMALL_DRILL;
|
|
else
|
|
{
|
|
if (pts->m_Drill < 0)
|
|
diam.x = diam.y = g_DesignSettings.m_ViaDrill;
|
|
else
|
|
diam.x = diam.y = pts->m_Drill;
|
|
}
|
|
trace_1_pastille_RONDE_POST(pos,diam.x, FILLED);
|
|
}
|
|
|
|
Module = Pcb->m_Modules;
|
|
for( ; Module != NULL; Module = (MODULE *)Module->Pnext )
|
|
{
|
|
PtPad = (D_PAD*) Module->m_Pads;
|
|
for ( ; PtPad != NULL ; PtPad = (D_PAD*)PtPad->Pnext )
|
|
{
|
|
if( PtPad->m_Drill.x == 0 ) continue;
|
|
|
|
/* calcul de la position des trous, selon echelle */
|
|
pos = PtPad->m_Pos;
|
|
diam.x = diam.y = (g_DrillShapeOpt == DRILL_MARK) ? SMALL_DRILL :
|
|
PtPad->m_Drill.x;
|
|
trace_1_pastille_RONDE_POST(pos, diam.x, FILLED);
|
|
}
|
|
}
|
|
|
|
fprintf(dest," 0 setgray\n");
|
|
}
|
|
|
|
/***********************************************************************************/
|
|
void trace_1_pastille_OVALE_POST(wxPoint pos, wxSize size, int orient, int modetrace)
|
|
/************************************************************************************/
|
|
/* Trace 1 pastille OVALE en position pos_X,Y:
|
|
dimensions dx,dy,
|
|
orientation orient
|
|
La forme est tracee comme un segment
|
|
*/
|
|
{
|
|
int x0, y0, x1, y1, delta;
|
|
int w, rayon;
|
|
|
|
/* la pastille est ramenee a une pastille ovale avec dy > dx */
|
|
if(size.x > size.y )
|
|
{
|
|
EXCHG(size.x,size.y); orient += 900;
|
|
if ( orient >= 3600 ) orient -= 3600;
|
|
}
|
|
|
|
delta = size.y - size.x;
|
|
x0 = 0; y0 = -delta / 2;
|
|
x1 = 0; y1 = delta / 2;
|
|
RotatePoint(&x0,&y0, orient);
|
|
RotatePoint(&x1,&y1, orient);
|
|
|
|
if( modetrace == FILLED )
|
|
{
|
|
PlotFilledSegmentPS(wxPoint(pos.x + x0, pos.y + y0),
|
|
wxPoint(pos.x + x1, pos.y + y1), size.x);
|
|
}
|
|
else
|
|
{
|
|
w = g_PlotLine_Width;
|
|
rayon = (size.x - w) / 2;
|
|
if(rayon < 1 ) rayon = 1 ;
|
|
if ( rayon < w ) w = rayon;
|
|
PlotArcPS( wxPoint(pos.x + x1,pos.y + y1), -orient, -orient + 1800, rayon, w);
|
|
PlotArcPS( wxPoint(pos.x + x0,pos.y + y0), -orient + 1800, -orient ,rayon, w);
|
|
|
|
x0 = -rayon; y0 = -delta / 2;
|
|
x1 = -rayon; y1 = delta / 2;
|
|
RotatePoint(&x0, &y0, orient);
|
|
RotatePoint(&x1, &y1, orient);
|
|
PlotFilledSegmentPS( wxPoint(pos.x+x0, pos.y+y0) ,
|
|
wxPoint(pos.x+x1, pos.y+y1), w);
|
|
|
|
x0 = rayon; y0 = -delta / 2;
|
|
x1 = rayon; y1 = delta / 2;
|
|
RotatePoint(&x0, &y0, orient);
|
|
RotatePoint(&x1, &y1, orient);
|
|
PlotFilledSegmentPS( wxPoint(pos.x+x0, pos.y+y0),
|
|
wxPoint(pos.x+x1, pos.y+y1), w);
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************************************/
|
|
void trace_1_pastille_RONDE_POST(wxPoint centre, int diametre, int modetrace)
|
|
/*******************************************************************************/
|
|
/* Trace 1 pastille RONDE (via,pad rond) en position pos_X,Y */
|
|
{
|
|
int rayon, w;
|
|
wxSize diam(diametre, diametre);
|
|
|
|
UserToDeviceCoordinate(centre);
|
|
UserToDeviceSize(diam);
|
|
|
|
if( modetrace == FILLED )
|
|
{
|
|
fprintf(dest,"%d setlinewidth\n", g_PlotLine_Width);
|
|
rayon = (diam.x) / 2;
|
|
if(rayon < 1 ) rayon = 1 ;
|
|
fprintf(dest,"newpath %d %d %d 0 360 arc fill stroke\n",
|
|
centre.x, centre.y, rayon);
|
|
}
|
|
|
|
else
|
|
{
|
|
w = g_PlotLine_Width;
|
|
rayon = (diam.x - w) / 2;
|
|
if(rayon < 1 ) rayon = 1 ;
|
|
if ( rayon < w ) w = rayon;
|
|
fprintf(dest,"%d setlinewidth\n", w);
|
|
fprintf(dest,"newpath %d %d %d 0 360 arc stroke\n",
|
|
centre.x, centre.y, rayon);
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
void trace_1_pad_rectangulaire_POST(wxPoint centre,
|
|
wxSize size, int orient, int modetrace)
|
|
/**************************************************************************/
|
|
/*
|
|
Trace 1 pad rectangulaire d'orientation quelconque
|
|
donne par son centre, ses dimensions,
|
|
et son orientation orient
|
|
*/
|
|
{
|
|
int x0, y0, x1, y1, w;
|
|
|
|
if( modetrace == FILLED )
|
|
{
|
|
x0 = centre.x - size.x/2; x1 = centre.x + size.x/2;
|
|
y0 = y1 = centre.y; w = size.y;
|
|
|
|
RotatePoint(&x0,&y0, centre.x, centre.y, orient);
|
|
RotatePoint(&x1,&y1, centre.x, centre.y, orient);
|
|
|
|
fprintf(dest,"0 setlinewidth 0 setlinecap 0 setlinejoin\n");
|
|
ForcePenReinit(); // Force init line width for PlotFilledSegmentPS
|
|
PlotFilledSegmentPS(wxPoint(x0, y0), wxPoint(x1, y1), w);
|
|
ForcePenReinit();
|
|
SetCurrentLineWidthPS(0); // Force init line width to default
|
|
fprintf(dest,"1 setlinecap 1 setlinejoin\n");
|
|
}
|
|
|
|
else {
|
|
w = g_PlotLine_Width;
|
|
size.x -= w; if ( size.x < 1 ) size.x = 1;
|
|
size.y -= w; if ( size.y < 1 ) size.y = 1;
|
|
trace_1_contour_POST(centre, size, wxSize(0, 0), w, orient);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************/
|
|
void trace_1_contour_POST(wxPoint centre, wxSize size, wxSize delta,
|
|
int dim_trait, int orient)
|
|
/**************************************************************/
|
|
/*
|
|
Trace 1 contour rectangulaire ou trapezoidal d'orientation quelconque
|
|
donne par son centre centre,
|
|
ses dimensions size,
|
|
ses variations delta
|
|
epaisseur de trait dim_trait
|
|
et son orientation orient (en 0.1 degres)
|
|
*/
|
|
{
|
|
int ii;
|
|
int dx, dy, lpen;
|
|
int ddx, ddy;
|
|
wxPoint coord[4];
|
|
|
|
lpen = dim_trait;
|
|
|
|
dx = size.x / 2; dy = size.y / 2 ;
|
|
ddx = delta.x >> 1; ddy = delta.y >> 1 ; /* demi dim dx et dy */
|
|
|
|
coord[0].x = centre.x - dx - ddy;
|
|
coord[0].y = centre.y + dy + ddx;
|
|
|
|
coord[1].x = centre.x - dx + ddy;
|
|
coord[1].y = centre.y - dy - ddx;
|
|
|
|
coord[2].x = centre.x + dx - ddy;
|
|
coord[2].y = centre.y - dy + ddx;
|
|
|
|
coord[3].x = centre.x + dx + ddy;
|
|
coord[3].y = centre.y + dy - ddx;
|
|
|
|
for (ii = 0; ii < 4; ii++)
|
|
{
|
|
RotatePoint(&coord[ii], centre, orient);
|
|
}
|
|
|
|
|
|
PlotFilledSegmentPS( coord[0], coord[1], lpen);
|
|
PlotFilledSegmentPS( coord[1], coord[2], lpen);
|
|
PlotFilledSegmentPS( coord[2], coord[3], lpen);
|
|
PlotFilledSegmentPS( coord[3], coord[0], lpen);
|
|
}
|
|
|
|
|
|
/*******************************************************************/
|
|
void trace_1_pad_TRAPEZE_POST(wxPoint centre, wxSize size, wxSize delta,
|
|
int orient,int modetrace)
|
|
/*******************************************************************/
|
|
/*
|
|
Trace 1 pad trapezoidal donne par :
|
|
son centre centre
|
|
ses dimensions size
|
|
les variations delta ( 1 des deux au moins doit etre nulle)
|
|
son orientation orient en 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 "
|
|
" . . "
|
|
" . O . "
|
|
" . . "
|
|
" 1 ---- 2 "
|
|
|
|
|
|
exemple de Disposition pour deltaY > 0, deltaX = 0
|
|
" 1 ---- 2 "
|
|
" . . "
|
|
" . O . "
|
|
" . . "
|
|
" 0 ------------- 3 "
|
|
|
|
|
|
exemple de Disposition pour deltaY = 0, deltaX > 0
|
|
" 0 "
|
|
" . . "
|
|
" . . "
|
|
" . 3 "
|
|
" . . "
|
|
" . O . "
|
|
" . . "
|
|
" . 2 "
|
|
" . . "
|
|
" . . "
|
|
" 1 "
|
|
*/
|
|
{
|
|
int ii;
|
|
int dx,dy;
|
|
wxPoint polygone[4]; /* coord des sommets / centre du pad */
|
|
int ddx, ddy ;
|
|
int l_pen; /* diam spot (plume) */
|
|
|
|
l_pen = 1;
|
|
if( (modetrace == FILAIRE) || ( Plot_Mode == FILAIRE ) )
|
|
{
|
|
wxSize lsize(g_PlotLine_Width,g_PlotLine_Width);
|
|
UserToDeviceSize(lsize);
|
|
l_pen = lsize.x;
|
|
}
|
|
|
|
dx = size.x / 2; dy = size.y / 2 ;
|
|
ddx = delta.x / 2; ddy = delta.y / 2 ;
|
|
|
|
polygone[0].x = - dx - ddy; polygone[0].y = + dy + ddx;
|
|
polygone[1].x = - dx + ddy; polygone[1].y = - dy - ddx;
|
|
polygone[2].x = + dx - ddy; polygone[2].y = - dy + ddx;
|
|
polygone[3].x = + dx + ddy; polygone[3].y = + dy - ddx;
|
|
|
|
for (ii = 0; ii < 4; ii++)
|
|
{
|
|
RotatePoint(&polygone[ii].x, &polygone[ii].y, orient);
|
|
polygone[ii].x += centre.x; polygone[ii].y += centre.y;
|
|
}
|
|
|
|
SetCurrentLineWidthPS( l_pen);
|
|
|
|
UserToDeviceCoordinate(polygone[0]);
|
|
fprintf(dest,"newpath %d %d moveto\n", polygone[0].x, polygone[0].y);
|
|
|
|
for (ii = 1; ii < 4; ii++)
|
|
{
|
|
UserToDeviceCoordinate(polygone[ii]);
|
|
fprintf(dest,"%d %d lineto\n", polygone[ii].x, polygone[ii].y);
|
|
}
|
|
|
|
fprintf(dest,"%d %d lineto ", polygone[0].x, polygone[0].y);
|
|
|
|
if(modetrace == FILLED ) fprintf(dest, "fill ");;
|
|
fprintf(dest, "stroke\n");;
|
|
}
|
|
|