Salve a todos


ho sviluppato un software per la visualizzazione di mappe.
Ed ovviamente ho implementato un sistema di stampa.

Il mio problema è che, non riesco a capire perché, la stampa viene "diversa", ovvero viene qualche millimetro più grande o più piccola.

Per esserne sicuro ho fatto la prova disegnando 2 linee a distanza di un centimetro, scansionando l'immagine e poi stampandola col mio software

Con il righello vedevo che erano + grandi le linee e risultava il tutto 11mm invece che 10mm come doveva essere

Essendo mappe topografiche, anche il mezzo millimetro può essere problematico, dato che la scala della mappa è 1 a 2000.

Ho pensato come prima cosa al settaggio della stampante, infatti ormai molte stampanti ridimensionano l'immagine stampata per farla entrare nel foglio, poi ho verificato anche che l'immagine fosse corretta in partenza ... ma niente in assoluto!
Anche xche ritagliando la stessa area e mandandola in stampa sia con paint shop pro viene perfetta!

Qui di seguito vi posto il codice che inizializza la stampante e la stampa


questo inizializza la stampante
codice:
PageSetupDialog oTMPPrintPSD = new PageSetupDialog();
oTMPPrintPSD.AllowMargins = true;
				oTMPPrintPSD.AllowOrientation = true;
oTMPPrintPSD.AllowPaper = true;
oTMPPrintPSD.AllowPrinter = true;
oTMPPrintPSD.PrinterSettings = oPrinterSettings;
oTMPPrintPSD.PageSettings = new PageSettings();
				
oTMPPrintPSD.ShowDialog();
				
oPrintDocument.DefaultPageSettings = oTMPPrintPSD.PageSettings;
mentre questo inizializza la stampa
codice:
this.__ImageToPrint = this.pctImage.GetImageRect(this.pctImage.SelectedArea);

oPrintDocument.PrinterSettings = oPrinterSettings;
					
PrintPreviewDialog oTMPPPD = new PrintPreviewDialog();
oTMPPPD.Document = oPrintDocument;
oTMPPPD.ShowDialog();
il codice che riporto di seguito, invece, è quello che disegna la mappa, se necessario, spezzandola su + pagine

codice:
Graphics g = ea.Graphics;
g.Clear(Color.White);

g.SetClip(new Rectangle(ea.MarginBounds.Location, ea.MarginBounds.Size));

Rectangle MyMargins = new Rectangle(ea.MarginBounds.Location, ea.MarginBounds.Size);

//
// Crea la stringa col nome dell'ente e ne imposta la dimensione
//
Font oTMPEnteNameFont = new Font(FontFamily.GenericSansSerif, 30, FontStyle.Bold, GraphicsUnit.Pixel);
Size oTMPEnteNameSize = new Size(0, 0);
while(true)
{
	oTMPEnteNameSize = (g.MeasureString(this.sEnteName, oTMPEnteNameFont)).ToSize();
	
	if (oTMPEnteNameSize.Width > MyMargins.Height)
	{
		oTMPEnteNameFont = new Font(FontFamily.GenericSansSerif, oTMPEnteNameFont.Size - 1, FontStyle.Bold, GraphicsUnit.Pixel);
	}
	else
	{
		break;
	}
}

MyMargins = new Rectangle(
                          MyMargins.X + oTMPEnteNameSize.Height,
                          MyMargins.Y,
                          MyMargins.Width - oTMPEnteNameSize.Height,
                          MyMargins.Height
                         );

if (
    	this.__ImageToPrint.Width > MyMargins.Width ||
    	this.__ImageToPrint.Height > MyMargins.Height
    )
{
	//
	// Verifica se è stato richiesto l'incremento della X
	// e dell'altezza
	//
	int iNewX = 0;
	int iNewY = 0;
	
	for(int iCurrPage = 0; iCurrPage < this.__PageCounter; iCurrPage++)
	{
		//
		// Verifica se la larghezza dell'area selezionata e minore
		// della larghezza totale dell'immagine
		//
		if (iNewX + MyMargins.Width < this.__ImageToPrint.Width)
	    {
			iNewX += MyMargins.Width;
	    }
		
		//
		// deve aumentare la Y e resettare la X
		//
		else
		{
			iNewY += MyMargins.Height;
			iNewX = 0;
		}
	}
	
	g.TranslateTransform(-iNewX, -iNewY);
	
	if (iNewX > 0)
	{
		g.TranslateTransform(oTMPEnteNameSize.Height, 0);
	}
	
	//
	// Verifica se ci sono nuove pagine
	//
	if (
	    	iNewX + MyMargins.Width < this.__ImageToPrint.Width ||
	    	iNewY + MyMargins.Height < this.__ImageToPrint.Height
	    )
	{
		ea.HasMorePages = true;
	}
	
	this.__PageCounter++;
}


g.DrawImageUnscaled(this.__ImageToPrint, MyMargins);

g.ResetTransform();

g.DrawString(
             this.sCode + " - Zoom: " + ((int)this.pctImage.ZoomLevel * 100).ToString() + "%",
             new Font(FontFamily.GenericSansSerif, 20, FontStyle.Bold, GraphicsUnit.Pixel),
             new SolidBrush(Color.Black),
             MyMargins.X,
             MyMargins.Y
            );

g.FillRectangle(new SolidBrush(Color.White), new Rectangle(
                                                           ea.MarginBounds.Location.X,
                                                           ea.MarginBounds.Location.Y,
                                                           oTMPEnteNameSize.Height,
                                                           ea.MarginBounds.Size.Height
                                                          ));

g.DrawString(
             this.sEnteName,
             oTMPEnteNameFont,
             new SolidBrush(Color.Black),
             ea.MarginBounds.Location.X,
             ea.MarginBounds.Location.Y,
             new StringFormat(StringFormatFlags.DirectionVertical)
            );
PS:
this.__ImageToPrint = this.pctImage.GetImageRect(this.pctImage.SelectedA rea);

questo codice non fa altro che richiamare un metodo del mio controllo per visualizzare le immagini, ovvero richiede di aver "ritagliato" una parte delle immagini. Ho dovuto far cosi xche le immagini sono MOLTO GRANDI (anche 10000px per 10000px) e mi collassava tutto usando le normali funzioni delle GDI+. Comunque quel codice non fa altro che copiare una porzione dell'immagine in memoria nell'immagine da ritornare