AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Druckausgabe über Printer / Problem mit einigen Schriftarten

Druckausgabe über Printer / Problem mit einigen Schriftarten

Ein Thema von stefanniehaus · begonnen am 29. Jan 2013 · letzter Beitrag vom 30. Jan 2013
Antwort Antwort
Seite 1 von 2  1 2   
stefanniehaus

Registriert seit: 3. Mär 2005
11 Beiträge
 
Delphi XE2 Professional
 
#1

Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 29. Jan 2013, 17:17
Hallo zusammen,

als langjähriger Mitleser bin ich leider jetzt auch auf ein Problem gestoßen, für das ich so spontan keine Lösung parat habe. Vielleicht kommt ihr ja auf ne Idee.

Folgende (aufs wesentliche reduzierte) Druckroutine:

Delphi-Quellcode:
procedure TForm1.btnSchreibenClick(Sender: TObject);
var
  liY : Integer; // Positionierung auf der Y-Achse in 1/10mm
const
  liSpacerMM : Integer = 5; // Platz zwischen den Zeilen -> 0,5mm
  liBlockMM : Integer = 50; // Platz zwischen den Blöcken -> 5mm
  liFontSizeMM : Integer = 40; // Schriftgrösse -> 4mm
begin

  printer.BeginDoc;

  liY := 200; // Startwert auf y-Achse: 20mm

  SetMapMode(printer.canvas.handle, MM_TEXT);
  printer.Canvas.Font.Height := MMtoPX(liFontSizeMM);
  printer.Canvas.Font.Name := 'Gill Sans MT';
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+0*(liFontSizeMM+liSpacerMM)),'MUSTERMANN');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+1*(liFontSizeMM+liSpacerMM)),'Testfall und sonstiges GmbH');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+2*(liFontSizeMM+liSpacerMM)),'Musterstraße 2');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+3*(liFontSizeMM+liSpacerMM)),'12345 Musterort');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+4*(liFontSizeMM+liSpacerMM)),'info@MustermannGmbH');

  liY := liY + 5 * (liSpacerMM+liFontSizeMM) + liBlockMM;

  SetMapMode(printer.canvas.handle, MM_LOMETRIC);
  printer.Canvas.Font.Height := liFontSizeMM;
  printer.Canvas.Font.Name := 'Gill Sans MT';
  printer.Canvas.TextOut(200,-(liY+0*(liFontSizeMM+liSpacerMM)),'MUSTERMANN');
  printer.Canvas.TextOut(200,-(liY+1*(liFontSizeMM+liSpacerMM)),'Testfall und sonstiges GmbH');
  printer.Canvas.TextOut(200,-(liY+2*(liFontSizeMM+liSpacerMM)),'Musterstraße 2');
  printer.Canvas.TextOut(200,-(liY+3*(liFontSizeMM+liSpacerMM)),'12345 Musterort');
  printer.Canvas.TextOut(200,-(liY+4*(liFontSizeMM+liSpacerMM)),'info@MustermannGmbH');

  liY := liY + 5 * (liSpacerMM+liFontSizeMM) + 2 * liBlockMM;

  SetMapMode(printer.canvas.handle, MM_TEXT);
  printer.Canvas.Font.Height := MMtoPX(liFontSizeMM);
  printer.Canvas.Font.Name := 'Arial';
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+0*(liFontSizeMM+liSpacerMM)),'MUSTERMANN');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+1*(liFontSizeMM+liSpacerMM)),'Testfall und sonstiges GmbH');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+2*(liFontSizeMM+liSpacerMM)),'Musterstraße 2');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+3*(liFontSizeMM+liSpacerMM)),'12345 Musterort');
  printer.Canvas.TextOut(MMtoPX(200),MMtoPX(liY+4*(liFontSizeMM+liSpacerMM)),'info@MustermannGmbH');

  liY := liY + 5 * (liSpacerMM+liFontSizeMM) + liBlockMM;

  SetMapMode(printer.canvas.handle, MM_LOMETRIC);
  printer.Canvas.Font.Height := liFontSizeMM;
  printer.Canvas.Font.Name := 'Arial';
  printer.Canvas.TextOut(200,-(liY+0*(liFontSizeMM+liSpacerMM)),'MUSTERMANN');
  printer.Canvas.TextOut(200,-(liY+1*(liFontSizeMM+liSpacerMM)),'Testfall und sonstiges GmbH');
  printer.Canvas.TextOut(200,-(liY+2*(liFontSizeMM+liSpacerMM)),'Musterstraße 2');
  printer.Canvas.TextOut(200,-(liY+3*(liFontSizeMM+liSpacerMM)),'12345 Musterort');
  printer.Canvas.TextOut(200,-(liY+4*(liFontSizeMM+liSpacerMM)),'info@MustermannGmbH');

  printer.EndDoc;
end;

function TForm1.MMtoPX(inMM:Integer) : Integer;
begin
  result := Round(inMM * printer.Canvas.Font.PixelsPerInch / 254)
end;

function TForm1.PXtoMM(inPX:Integer) : Integer;
begin
  result := Round(inPX *254 / printer.Canvas.Font.PixelsPerInch)
end;
Was wird gemacht?
Es wird 4x derselbe Adressblock gedruckt; alles in ein und dasselbe Dokument.
- Block1: Schriftart "Gill Sans MT" - MapMode MM_TEXT - FontHeight 4mm (umgerechnet in Pixel)
- Block2: Schriftart "Gill Sans MT" - MapMode MM_LOMETRIC - FontHeight 4mm
- Block3: Schriftart "Arial" - MapMode MM_TEXT - FontHeight 4mm (umgerechnet in Pixel)
- Block4: Schriftart "Arial" - MapMode MM_LOMETRIC - FontHeight 4mm

Das Ergebnis findet ihr im Anhang.
Obwohl ich zwischen Block 1 und Block 2 eigentlich nur SetMapMode aufgerufen und die Schriftgröße auf den analogen mm-Wert umgestellt habe, ist der 2. Textblock zusammen geschoben.
Die Höhe scheint gleich zu sein, nur die Breite hat sich verändert.

Als Gegenbeispiel dienen Block 3 und 4. Hier das identische vorgehen mit der Schriftart Arial; dort wird jedoch nichts zusammen geschoben.

Es scheint also mit der Schriftart zusammen zu hängen (ist mit mehreren nachvollziehbar) und evtl. auch mit dem ausgewählten Drucker (hier: PDF-Printer; bei einem anderen Drucker auf demselben PC waren Block 1 und Block 2 beide zusammengeschoben, Block 3 und 4 hingegen nicht).

Kann sich das jemand erklären?
Kann man das Problem irgendwie umgehen ohne dass man die Schriftart wechselt?
Angehängte Dateien
Dateityp: pdf Ergebnis.pdf (19,0 KB, 46x aufgerufen)
  Mit Zitat antworten Zitat
MeierZwoo

Registriert seit: 3. Dez 2012
106 Beiträge
 
#2

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 03:02
Es scheint also mit der Schriftart zusammen zu hängen (ist mit mehreren nachvollziehbar) und evtl. auch mit dem ausgewählten Drucker (hier: PDF-Printer; bei einem anderen Drucker auf demselben PC waren Block 1 und Block 2 beide zusammengeschoben, Block 3 und 4 hingegen nicht).
Die Ergebnisse des Canvas-Objekts sind Endgeräte-Abhängig. Abhängig davon, ob z.B. eine Schrift auf dem Endgerät verfügbar ist, wird diese Schrift im Canvas erzeugt oder es dem Endgerät überlassen. Da Arial (ersatweise Helv.) auf ansich JEDEM Endgerät verfügbar ist, wird diese Schriftausgabe auch erst dort passend erzeugt, während z.B. die Gill xxx von Canvas als Image erzeugt werden muß und auch als Image (Buchstabenweise) zum Endgerät gesendet wird.

Kann man das Problem irgendwie umgehen ohne dass man die Schriftart wechselt?
Ich persönlich sehe da garkein Problem, weil die Verwendung von MM_LOMETRIC nur bei ganz speziellen Endgeräten sinnvoll ist (Mir ist in 25 Jahren noch keins untergekommen, evtl. Stift/Gravur/3D-Plotter?). MM_LOMETRIC benutzt als Logik-Einheit 0,1 mm statt Pixel. Dazu muß dann Canvas aber die exakten Relationen des Endgerätes kennen (und entspr. umrechnen). Also sollte man die Verwendung MM_TEXT vs. MM_LOMETRIC (oder eines anderen Settings) von dem aktuell verwendeten Endgeräte-Treiber abhängig machen und nur umschalten, wenn dies das Endgerät explizit benötigt.

In Deinem Fall berechnet Canvas bei Gill xxx den einzelnen Buchstaben selber noch korrekt, unterschlägt aber die Spationierungswerte (oder setzt die auf eine logische Einheit - was kaum zu erkennen ist) bzw. das Endgerät kann mit der auf den Buchstaben folgenden Spationierung in mm nichts anfangen.

Anmerkung zu PDF-Erzeugenen Tools: Die sind als Kontrolle kaum verwendbar, weil die die Schriften teils merkwürden verzerren. Nur die Startpunkte sind korrekt, die Versalhöhen weichen oft ab, die Laufweiten schriftabhängig teils auch.
  Mit Zitat antworten Zitat
stefanniehaus

Registriert seit: 3. Mär 2005
11 Beiträge
 
Delphi XE2 Professional
 
#3

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 07:17
Vielen Dank schon mal für deine Ausführungen.

Im Anwendungsfall geht es um die dynamische Erzeugung von Rechnungen. Dynamisch in dem Sinne, alsdass es eine frei definierbare Layout-Datei gibt, die dann verarbeitet wird.
Entsprechend sind mm-Angaben gegeben.
Die komplette Druckroutine ist schon etwas älter und kann leider nicht mal eben so "auf links" gezogen werden.
Das Problem trat bisher nur nicht auf, da i.d.R. Arial oder Times New Roman verwendet wurden.

Meinst du mit Endgerät den jeweiligen PC oder den Drucker?
Vor dem Druck wird sicher gestellt, dass die verwendete Schriftart auf dem PC installiert ist.
Oder muss der Drucker diese Schriftart explizit unterstützen? Und wenn er dies nicht tut, kann man solche Ergebnisse nicht direkt beeinflussen?


edit: Im PDF-Dokument ist die Schrift kann ich die Schrift kopieren und woanders einfügen. Kann es dann noch ein Image sein? Mit ist klar, dass ein PDF-Drucker nicht Maß aller Dinge sein kann. Ich hätte das Dokument auch ausdrucken und zur Veranschaulichung wieder einscannen können. Das Problem wäre dasselbe.
edit2: Bim Druck beispielsweise über Word gibt es das Problem mit der Schriftart bei selbem Drucker nicht.

Geändert von stefanniehaus (30. Jan 2013 um 07:24 Uhr)
  Mit Zitat antworten Zitat
MeierZwoo

Registriert seit: 3. Dez 2012
106 Beiträge
 
#4

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 07:40
Drucklayouts sind normal immer in mm .. weil das Endgerät ja nicht bekannt sein muß, und dessen Auflösung (dpi) auch nicht - wohl aber das Ausgabe-Format bekannt ist (z.B. DIN A4) - und das hat als Maß eben mm.

Nur besteht keinerlei Grund, nur weil das Endformat mm hat, auch die logische Einheit auf mm zu setzen. Die logische Einheit ist normal immer Pixel (ausgenommen bei Plottern etc.). Aber sowohl Bildschirme wie auch Drucker sind pixelorientiert - die mm des Layouts werden dann entspr. der dpi Werte in x-Richtung wie in y-Richtung (können verschieden sein) umgerechnet.

Mit ENDgerät ist immer das Gerät gemeint, auf dem endgültig die Ausgabe erfolgt: Ein Drucker, der Bildschirm, eine eMail, ein FAX ... der ERZEUGER kann nicht ENDgerät sein.

Ein Drucker "unterstützt" keine Schriften - er hat diese installiert, sie werden vorm Druck untergeladen oder er hat diese Schrift nicht. Aber Canvas weiß, welche Schriften der Drucker (aktuell) installiert hat und unterscheidet dann, ob der Drucker entspr. Commands bekommt, diese Schrift zu benutzen oder ob Canvas die Schrift selber "malt" und das Ergebnis per Image zum Drucker schickt.

Eine benutzte Schrift sollte schon auf dem PC, auf dem Canvas läuft, installiert sein - alternativ wird eben eine Ersatzschrift verwendet - bei Windows mit Vorliebe Courier <schauder> obwohl die API anderes behauptet.

Es gibt übrigens keinen Grund, für Rechnungen Exoten-Schriften zu benutzen, bei denen man dann nicht sicher sein kann, ob sie zur Laufzeit vorhanden sind. Vorallem kann man keinem Benutzer zumuten, die passende Schrift ohne exakte Angabe selber nachzuinstallieren - da die Schriftnamen im Font-Verzeichnis nicht mit dem internen Schriftnamen übereinstimmen müssen.

Geändert von MeierZwoo (30. Jan 2013 um 07:54 Uhr)
  Mit Zitat antworten Zitat
stefanniehaus

Registriert seit: 3. Mär 2005
11 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 07:50
Wie gesagt ist sicher gestellt, dass die benötigte Schrift vorhanden ist.
Die Wahl einer anderen Schriftart ist im aktuellen Fall auch keine Option.

Das Problem kann man soweit also nicht lösen? Umrechnung der mm-Angaben in px hilft ja offensichtlich auch nicht immer.

Geändert von stefanniehaus (30. Jan 2013 um 07:56 Uhr)
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#6

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 08:14
Das Druckergebnis hängt auch vom BS und vom Drucker ab (Stichwort: GDI, OPENGL).

Der Fehler liegt eindeutig bei der Schrift Gill Sans MT - mit Tahoma sieht es gut aus.
Miniaturansicht angehängter Grafiken
drucktest-3.jpg  

Geändert von hathor (30. Jan 2013 um 08:56 Uhr)
  Mit Zitat antworten Zitat
MeierZwoo

Registriert seit: 3. Dez 2012
106 Beiträge
 
#7

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 08:19
Wie gesagt ist sicher gestellt, dass die benötigte Schrift vorhanden ist.
Das wage ich zu bezweifeln, oder administrierst Du das Programm mit täglicher Wartung dein Leben lang?

Das Problem kann man soweit also nicht lösen? Umrechnung der mm-Angaben in px hilft ja offensichtlich auch nicht immer.
Das Problem ist doch gelöst, wenn Du dieses unselige MM_LOMETRIC wegläßt, was niemand braucht. Die logische Einheit mm von MM_LOMETRIC hat nichts, aber auch garnichts mit der Umrechnung mm/Pixel bzw. dem Maßsystem des Endformates zu tun! Zumal das Endgerät zwar mm im Ausgabeformat hat, aber im Gegensatz zu MM_LOMETRIC, das gleiche Einheiten in x und y setzt, das Endgerät in x und y verschiedene dpi haben kann. Aber diese Werte kennt canvas, weil sie per Treiber ermittelt werden (DeviceCaps des Printers).

Es wird immer von mm auf Pixel umgerechnet, weil jeder Drucker mm-Formate als Ausgabemedium hat und Canvas immer Pixelorientiert ist - alle Canvas-Methoden erwarten Pixel als Werte.

Geändert von MeierZwoo (30. Jan 2013 um 08:42 Uhr)
  Mit Zitat antworten Zitat
stefanniehaus

Registriert seit: 3. Mär 2005
11 Beiträge
 
Delphi XE2 Professional
 
#8

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 08:32
Ich nehme mal an, dass Printer : TPrinter; eine GLOBALE Varable ist, denn sie ist in der Procedure nicht deklariert.
Besser ist es, sie LOKAL zu deklarieren, um auszuschliessen, dass andere evtl. langsame, parallele Threads die Variable ändern.
Das Druckergebnis hängt auch vom BS und vom Drucker ab (Stichwort: GDI, OPENGL)
Ein TPrinter-Objekt wird automatisch erzeugt, wenn es nil ist.
Ich habe aber auch schon lokal ein TPrinter-Objekt erzeugt, was keine Veränderung mit sich gebracht hat.
  Mit Zitat antworten Zitat
stefanniehaus

Registriert seit: 3. Mär 2005
11 Beiträge
 
Delphi XE2 Professional
 
#9

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 08:45
Das wage ich zu bezweifeln, oder administrierst Du das Programm mit täglicher Wartung dein Leben lang?
Es wird vorher geprüft ob die Schriftart auf dem System vorhanden ist. Ist sie das nicht, wird nicht gedruckt.

Das Problem ist doch gelöst, wenn Du dieses unselige MM_LOMETRIC wegläßt, was niemand braucht. Die logische Einheit mm von MM_LOMETRIC hat nichts, aber auch garnichts mit der Umrechnung mm/Pixel bzw. dem Maßsystem des Endformates zu tun! Zumal das Endgerät zwar mm im Ausgabeformat hat, aber im Gegensatz zu MM_LOMETRIC, das gleiche Einheiten in x und y setzt, das Endgerät in x und y verschiedene dpi haben kann. Aber diese Werte kennt canvas, weil sie per Treiber ermittelt werden (DeviceCaps des Printers).

Es wird immer von mm auf Pixel umgerechnet, weil jeder Drucker mm-Formate als Ausgabemedium hat und Canvas immer Pixelorientiert ist - alle Canvas-Proceduren erwarten Pixel als Werte.
Das Problem ist nicht gelöst, da - wie oben beschrieben - auch ohne Verwendung von SetMapMode und mit Verwendung von Pixel-Angaben es zur Stauchung kommen kann, je nach Drucker (im o.g. Beispiel: Keine Stauchung beim PDF-Drucker, Stauchung bei einem HP-Drucker (jeweils bei ohne MM_LOMETRIC))
Bei Arial beispielsweise kommt es in keinem Fall zur Stauchung.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#10

AW: Druckausgabe über Printer / Problem mit einigen Schriftarten

  Alt 30. Jan 2013, 16:01
Das Problem ist nicht gelöst, da - wie oben beschrieben - auch ohne Verwendung von SetMapMode und mit Verwendung von Pixel-Angaben es zur Stauchung kommen kann, je nach Drucker (im o.g. Beispiel: Keine Stauchung beim PDF-Drucker, Stauchung bei einem HP-Drucker (jeweils bei ohne MM_LOMETRIC))
Bei Arial beispielsweise kommt es in keinem Fall zur Stauchung.
Die patzige Antwort lautet "Dann besorg Dir einen ordentlichen Font"
Leider ist das was als fontx auf dem Markt ist nicht immer das gleiche und schon garnicht das selbe. Letztendlich ist das Ergebnis auf Papier nur durch das Zusammenspiel von Druckertreiber,Font und Druckerhardware zu erreichen. Wobei es theoretisch die Möglichkeit gibt, daß der PC ein vollständiges Druckbild malt, oder auf der anderen Seite, daß der Drucker ein paar Steuerbefehle und Ascii-Text erhält.

Wenn Du keine ordentliche Doku für die eingesetzte Hardware/Software hast, dann hilft nur Trial n Error.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz