Autor Beitrag
georgfischerx
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 37



BeitragVerfasst: Mi 18.06.03 18:12 
Hallo allerseits,

ich habe das Problem, dass ich eine A4-Seite mit Texten und kleinen Graphiken sehr präzise an den richtigen Ort drucken sollte - und dies absolut druckerunabhängig auf 0.5 mm genau. WinWord kann das.

Mein Programm, das Printer.Canvas.TextOut etc. benützt, kann das aber nicht. Es kommt nicht auf genau dasselbe hinaus, ob auf einen HP-Laserjet 6MP oder Lexmark Optra M gedruckt wird. Kleine Abweichungen sind immer da.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
  If FrmMain.DlgPrint.Execute Then Begin
   With Printer Do Begin
    Orientation := poPortrait;
    BeginDoc;

    Long := Printer.Canvas.Font.PixelsPerInch;
    Frac := Long / 600 + 0.0000001;

    Koordinat[1] := Trunc(800*Frac);
    Koordinat[2] := Trunc(800*Frac);
    Koordinat[3] := Trunc((Bmp.Width + 800) * Frac);
    Koordinat[4] := Trunc((Bmp.Height + 800)* Frac);

    MyRect := Rect(Koordinat[1], Koordinat[2],
                   Koordinat[3], Koordinat[4]);
    Canvas.StretchDraw(MyRect,
                   Bmp);

    StringX[1] := '                        Katalog                ';
    StringX[2] := '                 Kassettendienst               ';

    StringX[3] := '   Die   Kassetten  in   diesem   Katalog      ';
    StringX[4] := '   sind   nicht  für  den    Leihdienst  be-   ';
    StringX[5] := '   stimmt. Sie  können  zum  Stückpreis        ';
    StringX[6] := '   von  Fr.  8.--   (inkl.  Porto   und   Ver- ';
    StringX[7] := '   packung) bezogen werden.                    ';
    StringX[8] := '   Bitte  beiliegende Bestellkarte  (letzte    ';
    StringX[9] := '   te Seite) benützen.                         ';

    Canvas.Font.Style := [fsBold];
    Canvas.Font.Name := 'Arial';
    Canvas.Font.Size := 33;

    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(3000*Frac), StringX[1]);
    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(3300*Frac), StringX[2]);

    Canvas.Font.Style := [];
    Canvas.Font.Size := 30;

    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(4200*Frac), StringX[3]);
    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(4500*Frac), StringX[4]);
    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(4800*Frac), StringX[5]);
    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(5100*Frac), StringX[6]);
    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(5400*Frac), StringX[7]);
    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(5700*Frac), StringX[8]);
    Canvas.TextOut(Trunc(60*Frac),
                   Trunc(6000*Frac), StringX[9]);

    NewPage;

etc.

Woran liegt das? Besten Dank im Voraus für die Antworten!

GeorgX

Moderiert von user profile icontommie-lie: Code- durch Delphi-Tags ersetzt
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Mi 18.06.03 19:45 
Hallo,

versuch' mal, mit "SetMapMode()" auf 0,01mm zu setzen ("HIMETRIC"). Genauer geht's nicht mehr.

_________________
Life is a bad adventure, but the graphic is really good!
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mi 18.06.03 20:09 
Auf Delphi-Source gibt es dazu ein Tutorial

_________________
Ist Zeit wirklich Geld?
georgfischerx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 37



BeitragVerfasst: Fr 20.06.03 19:44 
Titel: Präziser Ausdruck ...
Sorry, aber das funktioniert leider gar nicht. Das Einzige, was jetzt geht, sind die präzisen Koordinaten. Aber die Schriften sehen jetzt TOTAL anders aus, je nachdem, welchen Drucker man verwendet.
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
  If PrintDialog1.Execute Then Begin
   With Printer Do
    Begin
      Printer.Orientation := poPortrait;
      BeginDoc;
      SetMapMode(Printer.Canvas.Handle, MM_LOMETRIC);
      Long := Printer.Canvas.Font.PixelsPerInch;

      Koordinat[1] := 300;
      Koordinat[2] := -300;
      Koordinat[3] := Bmp.Width + 300;
      Koordinat[4] := - Bmp.Height - 300;

      MyRect := Rect(Koordinat[1], Koordinat[2],
                     Koordinat[3], Koordinat[4]);
      Canvas.StretchDraw(MyRect,
                  Bmp);

      StringX[1] := '                   Katalog                     ';
      StringX[2] := '             Kassettendienst                   ';

      StringX[3] := '   Die   Kassetten  in   diesem   Katalog      ';
      StringX[4] := '   sind   nicht  für  den    Leihdienst  be-   ';
      StringX[5] := '   stimmt. Sie  können  zum  Stückpreis        ';
      StringX[6] := '   von  Fr.  8.--   (inkl.  Porto   und   Ver- ';
      StringX[7] := '   packung) bezogen werden.                    ';
      StringX[8] := '   Bitte  beiliegende Bestellkarte  (letzte    ';
      StringX[9] := '   te Seite) benützen.                         ';

      Canvas.Font.Style := [fsBold];
      Canvas.Font.Name := 'Arial';
      Canvas.Font.Size := 15;

      Canvas.TextOut(100, -1100, StringX[1]);
      Canvas.TextOut(100, -1250, StringX[2]);

      Canvas.Font.Style := [];
      Canvas.Font.Size := 12;

      Canvas.TextOut(100, -1500 , StringX[3]);
      Canvas.TextOut(100, -1630 , StringX[4]);
      Canvas.TextOut(100, -1760 , StringX[5]);
      Canvas.TextOut(100, -1890 , StringX[6]);
      Canvas.TextOut(100, -2020 , StringX[7]);
      Canvas.TextOut(100, -2150 , StringX[8]);
      Canvas.TextOut(100, -2280 , StringX[9]);

      EndDoc;
   End;

Auf einem HP PSC 500 (Tintenstrahler) ein TOTAL anderes Ergebnis als auf einem HP Laserjet. Woran liegt das ?

Ich freue mich auf Eure Antworten !

Georg

P.S. Auch die Koordinaten stimmen nicht auf jedem Drucker. Ich habe soeben 20 verschiedene Drucker ausprobiert. Ergebnis: Deprimierend.
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Fr 20.06.03 22:48 
Villeicht, wenn du nicht Font.Size, sondern Sonft.Height setzt ????

_________________
Life is a bad adventure, but the graphic is really good!
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Sa 21.06.03 00:39 
Titel: Re: Präziser Ausdruck ...
georgfischerx hat folgendes geschrieben:
Auf einem HP PSC 500 (Tintenstrahler) ein TOTAL anderes Ergebnis
als auf einem HP Laserjet. Woran liegt das ?

Das liegt an der bedruckbaren Fläche. Nicht jeder Drucker beginnt ganz links oben auf dem Papier. Du musst also den PHYSICALOFFSETX/Y, den du in DPI bekommst (also Umrechnen auf 1/10 mm ist angesagt) einberechnen.


Zitat:
Auch die Koordinaten stimmen nicht auf jedem Drucker. Ich habe soeben 20 verschiedene Drucker ausprobiert. Ergebnis: Deprimierend.

Wie schon gesagt die Druckfläche, insbesondere der Ort, an dem für den Drucker, der Nullpunkt ist.

Zitat:
ausblenden Delphi-Quelltext
1:
Canvas.StretchDraw(MyRect, Bmp);					

Bei den 20 Druckern ist dir keiner untergekommen, der das Bild nicht druckt? Bei mir reichten da schon 2. Eine bessere StretchDraw Funktion ist da die API Funktion StretchDIBits.

Und noch was für dein Font.Size:
Quelle: efg's Computer Lab - Delphi Printing Info and Links
Zitat:
Set the Height in a device-independent way and never use the font.size.
ausblenden Delphi-Quelltext
1:
Printer.Canvas.Font.Height := MulDiv(GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY), FontSize, 72);					

_________________
Ist Zeit wirklich Geld?
georgfischerx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 37



BeitragVerfasst: Sa 21.06.03 10:46 
Titel: Präziser Audruck ...
Vielen Dank für Eure Antworten. Wie ich sehe, wird das Ganze für mich zu kompliziert. Einen einfachen, druckerunabhängigen Druck gibt es nicht. Offenbar haben die WinWord-Programmierer sehr viel Code gebraucht, um so etwas zu realisieren. Ich gebe auf.

Georg
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Sa 21.06.03 11:15 
Titel: Re: Präziser Audruck ...
georgfischerx hat folgendes geschrieben:
Ich gebe auf.

Na so unheimlich schwer ist es nun auch wieder nicht. Bei Bitmaps wird es halt etwas kompliziert, aber das lässt sich mit einer "einmal geschrieben, immer wieder benutzt"en Funktion in den Griff bekommen.


Zu den Koordinaten:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
function GetPrintAreaStart: TPoint;
{ Nullpunkt des Druckers - Startposition relativ zur Papierkante }
begin
  Result.X := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETX);
  Result.Y := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETY);
  DPToLP(Printer.Canvas.Handle, Result, 1); // umrechnen
end;

function GetPhysicalOffset: TPoint;
{ Nullpunkt des Druckers - Startposition relativ zur Papierkante (in Pixel) }
begin
  Result.X := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETX);
  Result.Y := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETY);
end;

function GetPrintAreaSize: TSize;
{ Größe der bedruckbaren Fläche }
begin
  Result.cx := GetDeviceCaps(Printer.Canvas.Handle, HORZRES);
  Result.cy := GetDeviceCaps(Printer.Canvas.Handle, VERTRES);
  DPToLP(Printer.Canvas.Handle, Result, 1); // umrechnen
end;

function GetPageSize: TSize;
{  Größe des Papiers }
begin
  Result.cx := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALWIDTH);
  Result.cy := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALHEIGHT);
  DPToLP(Printer.Canvas.Handle, Result, 1); // umrechnen
end;



ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
SetMapMode(Printer.Canvas.Handle, MM_LOMETRIC);
{ Ursprung auf die Papierecke verschieben }
SetViewportOrgEx(dc, GetPhysicalOffset.X, -GetPhysicalOffset.Y, nil);
{ Ab hier entsprechen die Koordinaten 0/0 der Papierecke. Die meisten Drucker können dort jedoch nicht drucken. Deshalb sollte der Abstand bei den Koordinaten mit eingerechnet werden. }

Printer.Canvas.Font.Height := 100;

Printer.Canvas.TextOut(00'Test am Nullpunk')

_________________
Ist Zeit wirklich Geld?