Label mit Zeilenabstand erweitern

Rund um die LCL und andere Komponenten
Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Label mit Zeilenabstand erweitern

Beitrag von theo »

ArchChem hat geschrieben:
Fr 18. Nov 2022, 16:39
Wie kann ich denn herausfinden, ob ich über den Rand gekommen bin (außer visuell)?
Hatte ich weiter oben geschrieben: Canvas.TextExtent.
ArchChem hat geschrieben:
Fr 18. Nov 2022, 16:39
theo hat geschrieben:
Fr 18. Nov 2022, 11:18
Das LCL-Level Pendant in "Graphics" ist "TextRect", wie oben schon erwähnt.
Danke! Auch dieses greift auf die Function DrawText zurück, welche ich nun irgendwie lokalisieren und verstehen müsste... In den inc-Dateien scheint keine Implementierung zu stehen.
Ja, das ist sinnlos, das diese eine Windows API Funktion ist:
https://learn.microsoft.com/en-us/windo ... r-drawtext
Normalerweise sollte man die gar nicht benutzen, sondern Canvas.TextRect.
In beiden Fällen kann man dort aber nicht eingreifen.

ArchChem
Beiträge: 82
Registriert: Mo 11. Jul 2022, 10:41

Re: Label mit Zeilenabstand erweitern

Beitrag von ArchChem »

Socke hat geschrieben:
Fr 18. Nov 2022, 17:06
Die Implementierung von WidgetSet.DrawText findest du für Windows in der Unit Win32Int, genauer in der Datei lazarus\lcl\interfaces\win32\win32winapi.inc in der Methode TWin32WidgetSet.DrawText.
Oh Mist... Das bedeutet, es gibt gar keine plattformunabhängige Implementierung? Dann ist diese Idee leider eine Sackgasse, denn ein Grund, warum ich Lazarus benutze, ist eben die Plattform- und Frameworkunabhängigkeit des LCL-Frameworks :D
theo hat geschrieben:
Fr 18. Nov 2022, 17:08
Normalerweise sollte man die gar nicht benutzen, sondern Canvas.TextRect.
Dann wäre es vielleicht eine Möglichkeit, im Vorfeld die Zeilenumbrüche manuell durchzuführen (zum Beispiel in einer TStringList) und anschließend mehrere einzeilige Canvas.TextRect-Zeichnungen durchzuführen und diese mit dem Zeilenabstand untereinander zu platzieren.
Socke hat geschrieben:
Fr 18. Nov 2022, 17:06
Mit Canvas.TextExtend kannst du die Größe ermitteln. Ausgehend von deiner Zielposition kannst du dann ausrechnen, ob dein Text zu groß ist.
Danke für den Hinweis!

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Label mit Zeilenabstand erweitern

Beitrag von theo »

ArchChem hat geschrieben:
Fr 18. Nov 2022, 17:53
Oh Mist... Das bedeutet, es gibt gar keine plattformunabhängige Implementierung? Dann ist diese Idee leider eine Sackgasse, denn ein Grund, warum ich Lazarus benutze, ist eben die Plattform- und Frameworkunabhängigkeit des LCL-Frameworks :D
Es ist nicht prinzipiell unabhängig von Frameworks, aber der Code denn du schreibst, lässt sich für viele Plattformen übersetzen.
Z.B. wurde für andere Plattformen diese Winapi Funktion einfach nachgebaut.
Siehe z.B. hier für GTK2:
https://gitlab.com/freepascal.org/lazar ... inc#LC2397

Du kannst die LCL aber so benutzen, dass du dich darum nicht kümmern musst.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Label mit Zeilenabstand erweitern

Beitrag von Winni »

Hi!

Ich hab Dir nen kleinen Text-Wrapper gebaut, der auf jedem Canvas schreibt.

Zuerst setzt Du die Textattribute für den Canvas, dann rufst Du auf:

Code: Alles auswählen

procedure RectText (C:TCanvas; StartP:TPoint; MaxWidth,dy:integer;s: string);
StartP ist der Startpunkt oben links für den Text
MaxWidth ist der maximal zur Verfügung stehende Platz auf dem Canvas in Pixel
dy ist der Zeilenabstand in Pixel (>= Font.Height)

Die zwei entscheidenden Prceduren sind unabhängig von jeder Klasse, so dass sie überall einsetzbar sind.

Screenshot und Projekt anbei

Winni
Dateianhänge
TextInRect.png
TextInRect.png (50.85 KiB) 602 mal betrachtet
RectText.zip
(381.43 KiB) 37-mal heruntergeladen

wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: Label mit Zeilenabstand erweitern

Beitrag von wp_xyz »

Im beigefügten Beispiel-Projekt findest du eine "quick-and-dirty" Implementierung eines TLabelEx, das mit Hilfe der FCL-Function ExtractWordPos(n, labelText, WordDelims, p) den LabelText an den im WordDelims enthaltenen Wortgrenzen aufspaltet, so das n-te Wort findet und in p den Index des Wortbeginns zurückliefert. Diese Wörter werden dann wieder zu einem Zeilenstring zusammengefügt. Aber vorher wird geprüft, ob der Zeilenstring länger ist als der zur Verfügung stehende Platz. Wenn ja, wird die Zeile mit DrawText ausgegeben, der Zeilenstring gelöscht und an den Anfang der nächsten Zeile zurückgesprungen, wobei als Zeilenabstand eine Property LineSpacing als Multiplikator für die normale Zeilenhöhe vorgesehen ist.

Hat sicher noch ein paar Macken z.B. bin ich nicht sicher, ob im Labeltext schon enthaltene LineEndings richtig erkannt werden. Oder die Liste der WortDelims ist sicher nicht komplett. Oder die vertikale Textausrichtung wird nicht funktionieren, oder was sonst noch an Tricks in den Flags von DrawText enthalten ist. Aber für's erste reicht es, und du kannst die Fehler ja selbst versuchen zu beseitigen, es sind ja nur ein paar Zeilen Code.

[EDIT]
Oh, winni war schneller...
Dateianhänge
TLabelEx.png
TLabelEx.png (21.05 KiB) 600 mal betrachtet
label_extra_linespacing.zip
(3.07 KiB) 37-mal heruntergeladen

ArchChem
Beiträge: 82
Registriert: Mo 11. Jul 2022, 10:41

Re: Label mit Zeilenabstand erweitern

Beitrag von ArchChem »

Vielen lieben Dank euch beiden! Eure Beispielimplementierungen sind tatsächlich sehr nützlich, um die Thematik verstehen zu können!

@Winni, deinen Textwrapper konnte ich noch nicht zum Laufen bringen, ein Klick auf den Button führt zu keiner Veränderung. Ich konnte es aber auch noch nicht debuggen.

@wp_xyz, das ist echt super, vielen Dank!

Dann werde ich mir das in den nächsten Tagen mal ausführlich zu Gemüte führen und anschließend kann es dann in Cantara implementiert werden!

Antworten