Schriftgröße in LL_DRAWING_USEROBJ-Objekten

Hallo zusammen!

Es geht nochmal um das Problem aus diesem] Post[/url], aber da der nicht allzuviel Resonanz erzeugt hat, versuche ich’s mal neu zu formulieren. :slight_smile:

Ausgangsbasis ist eine normale VCL-Formularanwendung. Auf Form1 packe man ein TL17_ namens LL und zwei TButtons (ButtonDesign und ButtonPrint) mit folgenden Event-Handlern:

[code]procedure TForm1.ButtonDesignClick(Sender: TObject);
begin
LL.Design(0, Handle, ‘Design’, LL_PROJECT_LIST, ‘Test’, False, True);
end;

procedure TForm1.ButtonPrintClick(Sender: TObject);
begin
LL.Print(0, LL_PROJECT_LIST, ‘Test’, False, LL_PRINT_PREVIEW, LL_BOXTYPE_STDWAIT, Handle, ‘Preview’, False, ‘’);
end;

procedure TForm1.LLDefineVariables(Sender: TObject; UserData: Integer;
IsDesignMode: Boolean; var Percentage: Integer; var IsLastRecord: Boolean;
var EventResult: Integer);
begin
LL.LlDefineVariableExt(‘MyText’, ‘My sample text’, LL_TEXT);
LL.LlDefineVariableExt(‘MyGraphic’, ‘’, LL_DRAWING_USEROBJ);
end;

procedure TForm1.LLDrawUserobj(Sender: TObject; Name, Contents: string;
VarType: Integer; VarPointer: Pointer; ContentsHandle: Cardinal;
Isotropic: Boolean; Parameters: string; Canvas: TCanvas; var Rect: TRect;
PaintMode: TPaintMode);
var
s: string;
r: TRect;
SaveIndex: Integer;
begin
SaveIndex := SaveDC(Canvas.Handle);
try
r := Rect;
LPtoDP(Canvas.Handle, r, 2);
s := ‘My sample text’;
Canvas.Font.Name := ‘Arial’; // Hier gleichen Font wie im Text-Feld wählen
Canvas.Font.Size := 12;
SetMapMode(Canvas.Handle, MM_TEXT);
DPtoLP(Canvas.Handle, r, 2);
DrawText(Canvas.Handle, PChar(s), Length(s), r, DT_SINGLELINE or DT_NOCLIP);
finally
RestoreDC(Canvas.Handle, SaveIndex);
end;
end;[/code]
Wenn ich die Anwendung jetzt starte, den Design-Button drücke, mich durch den Wizard klicke und schließlich je eine MyText- und eine MyGraphic-Variable auf den Bericht packe, werden die beiden “My sample text”-Strings unterschiedlich groß dargestellt - siehe Designer-Screenshot.][/url] Wenn ich den Bericht speichere und drucken lasse, schaut’s nochmal anders aus - siehe Vorschau-Screenshot.][/url] Und bei Größenänderungen am Designer- bzw. Vorschaufenster verhalten sich Text- und Bildvariable auch unterschiedlich. Mein Ziel ist aber, das die beiden Strings in beiden Fenstern und unter allen Umständen gleich dargestellt werden.

Jetzt habe ich gedacht: Kein Problem, musst du halt den richtigen mapping mode setzen und gut isses. Aber das kriege ich nicht gebacken. Kann mir jemand auf die Sprünge helfen?

Grüße,
Uli

Du bekommst von LL einen DC mit MM_ISOTROPIC (oder ANISOTROPIC, egal). Die logischen Koordinaten sind im gewählten Einheiten (siehe LL_OPTION_UNIT). Die Schriftgröße (in pt) mußt du erst in diese Einheiten umrechnen und ggf. sogar ein Minuszeichen davor (siehe LOGFONT-Doku, weiß nicht, ob das für Delphi relevant ist). Ändern des DC-MapModes würde ich nicht machen, wenn’s nicht sein muß - aber es geht auch. Aber erst die Fontgröße im Font ändern, dann den MapMode ändern - ups. Also im Idealfall nix LPtoDP oder so, nur (Beispiel für 1/100 mm Einheiten und 12 pt Schriftgröße):

    s := 'My sample text';
    Canvas.Font.Name := 'Arial';
    Canvas.Font.Size := 12.0 / 72.0 * 25.4 * 100;
    DrawText(Canvas.Handle, PChar(s), Length(s), Rect, DT_SINGLELINE or DT_NOCLIP);

(Font mit 12 pt: 12/72=Größe in inch, 1 inch=25.40 mm, dann noch in inch/100 umrechnen)

Beachte, daß, wenn Du die METRIC nicht selbst setzt, LL in englischen Systemen auf inch umschaltet - d.h. entweder METRIC setzen oder Metrik hier on-the-fly abfragen und alle in LL definierten Metriken unterstützen bei der Umrechnung.

Paulchen

Hallo Paulchen!

Spitze, das funktioniert schon mal im Testprojekt.

[quote=Paul Schmidt]Die Schriftgröße (in pt) mußt du erst in diese Einheiten umrechnen und ggf. sogar ein Minuszeichen davor (siehe LOGFONT-Doku, weiß nicht, ob das für Delphi relevant ist).

[code] s := 'My sample text'; Canvas.Font.Name := 'Arial'; Canvas.Font.Size := 12.0 / 72.0 * 25.4 * 100; DrawText(Canvas.Handle, PChar(s), Length(s), Rect, DT_SINGLELINE or DT_NOCLIP); [/code]

(Font mit 12 pt: 12/72=Größe in inch, 1 inch=25.40 mm, dann noch in inch/100 umrechnen)
[/quote]
Font.HeightFont.SizeIch setze jetzt ][/url] anstelle von :

][/url]  s := 'My sample text';
  Canvas.Font.Name := 'Arial';
  Canvas.Font.Height := -MulDiv(12, 2540, 72);
  DrawText(Canvas.Handle, PChar(s), Length(s), Rect, DT_SINGLELINE or DT_NOCLIP);

Alternativ geht auch:

  Canvas.Font.Size := MulDiv(12, 2540, Canvas.Font.PixelsPerInch);

Wir machen außer dem Text auch noch ein paar “technische Zeichnungen”, die AFAICT MM_LOMETRIC voraussetzen. Aber mit deinen Hilfestellungen kann ich da sicher was kombinieren. Ich habe am Anfang meiner LL_DRAWING_USEROBJ-Karriere auch festgestellt, dass LL mimosenhaft auf SetMapMode reagiert. Aber mit einem SaveDC/RestoreDC drumherum habe ich keine Probleme mehr bemerkt. Hast du da noch was Konkretes im Sinn?

Das heb ich mir für später auf. :slight_smile: Momentan haben wir fix UnitSystem = usHiMetric a.k.a. LL_OPTION_UNITS = LL_UNITS_MM_DIV_100.

Vielen Dank,
Uli

“Ich habe am Anfang meiner LL_DRAWING_USEROBJ-Karriere auch festgestellt, dass LL mimosenhaft auf SetMapMode reagiert.”. Na klar erwartet LL, daß man den DC so hinterläßt wie man ihn vorgefunden hat - das gehört sich (nicht nur hier) so… :wink:

Probleme gibt’s nur, wenn man LPtoDP vergißt, oder zu früh/spät benutzt, oder eben Parameter setzt, die (ggf. bei Delphi über Abstraktion) erst später benutzt werden, wenn der MapMode geändert wurde. Solang man das beherrscht, kann ich mir nichts vorstellen, das Probleme macht (außer der Verwendung von GDI+ z.B.).

Schon klar. Ich hab halt anfangs gedacht, dass

OldMM := SetMapMode(MM_DenIchBrauche); // ... SetMapMode(OldMM);
den Ursprungszustand wiederherstellt. Tut’s aber nicht. Vermutlich gehen dabei irgendwelche Viewport-Koordinaten o.ä. hopps.

“Beherrschen” ist ein dehnbarer Begriff. :slight_smile:

Da ich die Textausgabe innerhalb der Zeichnungen in MM_TEXT erledige, habe ich mich von LOGFONT] structure[/url] inspirieren lassen:

[quote]For the MM_TEXT mapping mode, you can use the following formula to specify a height for a font with a specified point size:

lfHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);

und setze jetzt am Anfang meiner Zeichenroutine (vor SetMapMode)

Canvas.Font.Height := -MulDiv(PointSize, GetDeviceCaps(Canvas.Handle, LOGPIXELSY), 72);

Dann funktioniert’s auch mit SetMapMode.