void EDGE_MODULE::Draw(WinEDA_DrawPanel * panel, wxDC * DC, const wxPoint & offset, int draw_mode) /********************************************************************************/ /* Affichage d'un segment contour de module : Entree : ox, oy = offset de trace draw_mode = mode de trace ( GR_OR, GR_XOR, GR_AND) Les contours sont de differents type: - Segment - Cercles - Arcs */ { int ux0, uy0, dx, dy,rayon, StAngle, EndAngle; int color , type_trace; int zoom; int typeaff; PCB_SCREEN * screen; WinEDA_BasePcbFrame * frame; MODULE * Module = NULL; if ( m_Parent && (m_Parent->m_StructType == TYPEMODULE) ) Module = (MODULE*) m_Parent; GRSetDrawMode(DC, draw_mode); color = g_DesignSettings.m_LayerColor[m_Layer]; if ( panel ) screen = (PCB_SCREEN *) panel->m_Parent->m_CurrentScreen; else screen = ActiveScreen; frame = screen->GetParentPcbFrame(); zoom = screen->GetZoom(); type_trace = m_Shape; ux0 = m_Start.x - offset.x; uy0 = m_Start.y - offset.y; dx = m_End.x - offset.x ; dy = m_End.y - offset.y ; typeaff = frame->m_DisplayModEdge; if( m_Layer <= CMP_N ) typeaff = frame->m_DisplayPcbTrackFill; if( (m_Width /zoom) < L_MIN_DESSIN ) typeaff = FILAIRE; switch (type_trace ) { case S_SEGMENT: if( typeaff == FILAIRE) GRLine(&panel->m_ClipBox, DC, ux0, uy0, dx, dy, color); else Affiche_1_Segment(panel, DC, ux0,uy0,dx,dy,m_Width, typeaff,color); break ; case S_CIRCLE: rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) ); if( typeaff == FILAIRE) { GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon, color) ; } else { if(typeaff == FILLED ) { GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon, m_Width, color); } else { GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon + (m_Width/2), color) ; GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon - (m_Width/2), color) ; } } break; case S_ARC: rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) ); StAngle = (int)ArcTangente( dy-uy0, dx-ux0 ); EndAngle = StAngle + m_Angle; if ( StAngle > EndAngle) EXCHG (StAngle, EndAngle); if( typeaff == FILAIRE) { GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon, color) ; } else if(typeaff == FILLED ) { GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon, m_Width, color); } else { GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon + (m_Width/2), color) ; GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon - (m_Width/2), color) ; } break; case S_POLYGON: { // We must compute true coordinates from m_PolyList // which are relative to module position, orientation 0 int ii, * source, * ptr, * ptr_base; ptr = ptr_base = (int*) MyMalloc( 2 * m_PolyCount * sizeof(int) ); source = m_PolyList; for (ii = 0; ii < m_PolyCount; ii++ ) { int x, y; x = *source; source++; y = *source; source++; if ( Module ) { RotatePoint (&x, &y, Module->m_Orient); x += Module->m_Pos.x; y += Module->m_Pos.y; } x += m_Start0.x - offset.x; y += m_Start0.y - offset.y; *ptr = x; ptr++; *ptr = y; ptr++; } GRPoly(&panel->m_ClipBox, DC, m_PolyCount, ptr_base, TRUE, color, color); free ( ptr_base); break; } } }
/* * This is the real print function: print the active screen */ void BOARD_PRINTOUT_CONTROLER::DrawPage() { int tmpzoom; wxPoint tmp_startvisu; wxPoint old_org; wxPoint DrawOffset; // Offset de trace double userscale; double DrawZoom = 1; wxDC* dc = GetDC(); PCB_SCREEN* screen = (PCB_SCREEN*) m_Parent->GetScreen(); bool printMirror = m_PrintParams.m_PrintMirror; wxBusyCursor dummy; // Save old draw scale and draw offset tmp_startvisu = screen->m_StartVisu; tmpzoom = screen->GetZoom(); old_org = screen->m_DrawOrg; // Change draw scale and offset to draw the whole page screen->SetScalingFactor( DrawZoom ); screen->m_DrawOrg.x = screen->m_DrawOrg.y = 0; screen->m_StartVisu.x = screen->m_StartVisu.y = 0; PCB_BASE_FRAME* pcbframe = (PCB_BASE_FRAME*) m_Parent; wxSize pageSizeIU = pcbframe->GetPageSizeIU(); // internal units EDA_RECT bbbox = pcbframe->GetBoard()->ComputeBoundingBox(); // In module editor, the module is located at 0,0 but for printing // it is moved to pageSizeIU.x/2, pageSizeIU.y/2. // So the equivalent board must be moved: if( m_Parent->IsType( MODULE_EDITOR_FRAME ) ) { bbbox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) ); } // Compute the PCB size in internal units userscale = m_PrintParams.m_PrintScale; if( userscale == 0 ) // fit in page { // Margin = 0.4 inch #if defined(KICAD_NANOMETRE) int extra_margin = int( 0.4 * 25400 ); // nanometers #else int extra_margin = int( 0.4 * 1000 ); // deci-mils #endif pageSizeIU.x = bbbox.GetWidth() + extra_margin * 2; pageSizeIU.y = bbbox.GetHeight() + extra_margin * 2; userscale = 0.99; } if( (m_PrintParams.m_PrintScale > 1.0) // scale > 1 -> Recadrage || (m_PrintParams.m_PrintScale == 0) ) // fit in page { DrawOffset += bbbox.Centre(); } if( m_PrintParams.m_PageSetupData ) { wxSize pagesize; pagesize.x = int( pageSizeIU.x / userscale ); pagesize.y = int( pageSizeIU.y / userscale ); FitThisSizeToPageMargins( pagesize, *m_PrintParams.m_PageSetupData ); } // Compute Accurate scale 1 if( userscale == 1.0 ) { // We want a 1:1 scale and margins for printing MapScreenSizeToPaper(); int w, h; GetPPIPrinter( &w, &h ); double accurate_Xscale = ( (double) ( DrawZoom * w ) ) / (double) PCB_INTERNAL_UNIT; double accurate_Yscale = ( (double) ( DrawZoom * h ) ) / (double) PCB_INTERNAL_UNIT; if( IsPreview() ) // Scale must take in account the DC size in Preview { // Get the size of the DC in pixels wxSize PlotAreaSize; dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y ); GetPageSizePixels( &w, &h ); accurate_Xscale *= PlotAreaSize.x; accurate_Xscale /= (double) w; accurate_Yscale *= PlotAreaSize.y; accurate_Yscale /= (double) h; } accurate_Xscale *= m_PrintParams.m_XScaleAdjust; accurate_Yscale *= m_PrintParams.m_YScaleAdjust; // Fine scale adjust dc->SetUserScale( accurate_Xscale, accurate_Yscale ); } // Get the final size of the DC in pixels wxSize PlotAreaSizeInPixels; dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y ); double scalex, scaley; dc->GetUserScale(&scalex, &scaley); wxSize PlotAreaSizeInUserUnits; PlotAreaSizeInUserUnits.x = (int) (PlotAreaSizeInPixels.x/scalex); PlotAreaSizeInUserUnits.y = (int) (PlotAreaSizeInPixels.y/scaley); /* In some cases the plot origin is the centre of the page * when: * - Asked * - scale > 1 * - fit in page */ if( m_PrintParams.m_ForceCentered || (m_PrintParams.m_PrintScale > 1.0) // scale > 1 || (m_PrintParams.m_PrintScale == 0) ) // fit in page { DrawOffset.x -= PlotAreaSizeInUserUnits.x / 2; DrawOffset.y -= PlotAreaSizeInUserUnits.y / 2; } screen->m_DrawOrg = DrawOffset; GRResetPenAndBrush( dc ); if( m_PrintParams.m_Print_Black_and_White ) GRForceBlackPen( true ); EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); EDA_RECT tmp = *panel->GetClipBox(); // Set clip box to the max size #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer // and that allows calculations without overflow panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) ); m_Parent->GetScreen()->m_IsPrinting = true; int bg_color = g_DrawBgColor; if( m_PrintParams.m_Print_Sheet_Ref ) m_Parent->TraceWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize ); if( printMirror ) { // To plot mirror, we reverse the y axis, and modify the plot y origin dc->SetAxisOrientation( true, true ); if( userscale < 1.0 ) scaley /= userscale; /* Plot offset y is moved by the y plot area size in order to have * the old draw area in the new draw area, because the draw origin has not moved * (this is the upper left corner) but the Y axis is reversed, therefore the plotting area * is the y coordinate values from - PlotAreaSize.y to 0 */ int y_dc_offset = PlotAreaSizeInPixels.y; y_dc_offset = (int) ( ( double ) y_dc_offset * userscale ); dc->SetDeviceOrigin( 0, y_dc_offset ); int ysize = (int) ( PlotAreaSizeInPixels.y / scaley ); DrawOffset.y += ysize; /* in order to keep the board position in the sheet * (when user scale <= 1) the y offset in moved by the distance between * the middle of the page and the middle of the board * This is equivalent to put the mirror axis to the board centre * for scales > 1, the DrawOffset was already computed to have the board centre * to the middle of the page. */ wxPoint pcb_centre = bbbox.Centre(); if( userscale <= 1.0 ) DrawOffset.y += pcb_centre.y - (ysize / 2); dc->SetLogicalOrigin( screen->m_DrawOrg.x, screen->m_DrawOrg.y ); panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE/2, -MAX_VALUE/2 ), panel->GetClipBox()->GetSize() ) ); } g_DrawBgColor = WHITE; /* when printing in color mode, we use the graphic OR mode that gives the same look as the screen * But because the background is white when printing, we must use a trick: * In order to plot on a white background in OR mode we must: * 1 - Plot all items in black, this creates a local black backgroud * 2 - Plot in OR mode on black "local" background */ if( !m_PrintParams.m_Print_Black_and_White ) { // Creates a "local" black background GRForceBlackPen( true ); m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); GRForceBlackPen( false ); } m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); g_DrawBgColor = bg_color; m_Parent->GetScreen()->m_IsPrinting = false; panel->SetClipBox( tmp ); GRForceBlackPen( false ); screen->m_StartVisu = tmp_startvisu; screen->m_DrawOrg = old_org; screen->SetZoom( tmpzoom ); }