Buchstaben höhe Ermitteln(TCanvas)
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Buchstaben höhe Ermitteln(TCanvas)
Für ein Projekt bräuchte ich die Buchstabenhöhe nicht die Texthöhe.
Ich habe es zunächst, wie üblich mit "Canvas.TextExtent" versucht. Wie der Name schon vermuten lässt,
gibt er nur die Texthöhe zurück. Genau wie GetTextExtentPoint und GetTextExtentPoint32.
Ich habe auch schon extra für Pango gesucht, aber ich habe nichts gefunden.
Ich würde gerne ein Virtuelles Raster pro Zeile erstellen, um eine BaseLine zu ermitteln.
Dazu würde ich die höhe von "x" nehmen(grob beschrieben).
Kennt einer von euch eine Methode um die Buchstaben Höhe zu ermitteln?
Ich habe es zunächst, wie üblich mit "Canvas.TextExtent" versucht. Wie der Name schon vermuten lässt,
gibt er nur die Texthöhe zurück. Genau wie GetTextExtentPoint und GetTextExtentPoint32.
Ich habe auch schon extra für Pango gesucht, aber ich habe nichts gefunden.
Ich würde gerne ein Virtuelles Raster pro Zeile erstellen, um eine BaseLine zu ermitteln.
Dazu würde ich die höhe von "x" nehmen(grob beschrieben).
Kennt einer von euch eine Methode um die Buchstaben Höhe zu ermitteln?
MFG
Michael Springwald
Michael Springwald
Re: Buchstaben höhe Ermitteln(TCanvas)
An die BaseLine kommst du mit Hilfe der TLCLTextmetric, die man als Canvas.Methode GetTextmetrics abfragen kann (https://lazarus-ccr.sourceforge.io/docs ... trics.html):
Noch mehr Informationen erhält man aus dem TTextMetric-Record (https://lazarus-ccr.sourceforge.io/docs ... trica.html), den man durch die ähnliche LCLIntf-Funktion GetTextMetrics abfragen kann (https://lazarus-ccr.sourceforge.io/docs ... trics.html).
Die Bestimmung der individuellen Zeichenhöhe habe ich aktuell nicht parat.
Code: Alles auswählen
var
tm: TLCLTextMetric; // = record Ascender, Descender, Height: Integer; end;
...
Canvas.GetTextMetrics(tm);
Canvas.TextOut(x, y, 'xyz');
// Linie auf Höhe der Basis
Canvas.Line(0, y+tm.Ascender, 100, y+tm.Ascender);
Die Bestimmung der individuellen Zeichenhöhe habe ich aktuell nicht parat.
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Buchstaben höhe Ermitteln(TCanvas)
Erst mal danke für deine Antwort.
ich habe immer die Struktur TTextMetric genutzt aber nicht "TLCLTextMetric", schaue ich mir gleich mal an.
Jedenfalls in engen grenzen. Die Zeilen Höhe soll immer gleich hoch sein im Prinzip.
Wenn die Standard Schrift Größe sagen wir: 12 ist, möchte ich das die Schrift Größe so um 6 bis 8 Pixel verändert werden kann.
Wobei der Text an der BaseLine der Zeile ausgerichtet werden soll.
Der Hintergrund: Bisher habe ich immer eine komplexe Zeilen/Spalten Struktur verwendet um das höchste Element einer Zeile zu bestimmen,
nun möchte ich eine andere Idee, die nicht von mir ist ausprobieren.
Seine Idee(grob, ich werde noch mal genauer nach fragen), war: 3 mal die höhe von klein x zu nehmen.
Mir ist gerade eingefallen: Vielleicht hilft eine Beispiel Anwendung:
https://github.com/plutoLaz/LazEditor/tree/main/pr1
(Das Github repository baue ich seit ein paar Tagen auf, dazu mache ich noch ein extra Thread auf)
Ich hoffe du/ihr könnt mir folgen.
Dabei habe ich eine Schrift Art gesetzt und auch eine Schrift Größe gesetzt.
Mir fällt gerade auf, tm.Ascender ich habe immer mit tmascent gearbeitet nie mit Ascender....wp_xyz hat geschrieben: Canvas.Line(0, y+tm.Ascender, 100, y+tm.Ascender);
ich habe immer die Struktur TTextMetric genutzt aber nicht "TLCLTextMetric", schaue ich mir gleich mal an.
Jedenfalls in engen grenzen. Die Zeilen Höhe soll immer gleich hoch sein im Prinzip.
Wenn die Standard Schrift Größe sagen wir: 12 ist, möchte ich das die Schrift Größe so um 6 bis 8 Pixel verändert werden kann.
Wobei der Text an der BaseLine der Zeile ausgerichtet werden soll.
Der Hintergrund: Bisher habe ich immer eine komplexe Zeilen/Spalten Struktur verwendet um das höchste Element einer Zeile zu bestimmen,
nun möchte ich eine andere Idee, die nicht von mir ist ausprobieren.
Seine Idee(grob, ich werde noch mal genauer nach fragen), war: 3 mal die höhe von klein x zu nehmen.
Mir ist gerade eingefallen: Vielleicht hilft eine Beispiel Anwendung:
https://github.com/plutoLaz/LazEditor/tree/main/pr1
(Das Github repository baue ich seit ein paar Tagen auf, dazu mache ich noch ein extra Thread auf)
Ich hoffe du/ihr könnt mir folgen.
tmInternalLeading und tmExternalLeading sind bei mir immer 0.wp_xyz hat geschrieben:Noch mehr Informationen erhält man aus dem TTextMetric-Record
Dabei habe ich eine Schrift Art gesetzt und auch eine Schrift Größe gesetzt.
MFG
Michael Springwald
Michael Springwald
Re: Buchstaben höhe Ermitteln(TCanvas)
InternalLeading hat bei mir einen vernüftigen Wert, ExternalLeading ist 0
Code: Alles auswählen
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
x, y: Integer;
tm: TTextMetric;
begin
x := 4;
y := 4;
with Paintbox1 do
begin
Canvas.Brush.Color := clWhite;
Canvas.FillRect(0, 0, Width, Height);
Canvas.Font.Assign(Font);
GetTextMetrics(Canvas.Handle, tm);
Canvas.TextOut(x, y, 'xX');
Canvas.Pen.Color := clSilver;
Canvas.Line(x, y + tm.tmAscent, x+Width-8, y + tm.tmAscent);
Canvas.Line(x, y + tm.tmInternalLeading, x+Width-8, y + tm.tmInternalLeading);
end;
end;
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Buchstaben höhe Ermitteln(TCanvas)
Bist du unter Windows?wp_xyz hat geschrieben:InternalLeading hat bei mir einen vernüftigen Wert, ExternalLeading ist 0
Was für eine Schrift Namen/Größe verwendest du? Hängt das davon ab?
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 758
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: Buchstaben höhe Ermitteln(TCanvas)
Ich habe auch mal ein ähnliches Problem gehabt.
Meine Lösung war, ich schreibe den entsprechenden Buchstaben in eine (etwas grössere) BitMap.
Dann suche ich nach den äussersten gesetzen Pixeln.
So habe ich die pixelgenaue Breite und Höhe, oder auch den linken Abstand zum Rand usw.
Eine "unschöne" Lösung, die aber für meinen Fall brauchbare, pixelgenaue Lösungen ergab.
Info:
Als ich mich dann mal mit den TrueType Fonts beschäftige, musste ich feststellen, das nicht alle Fonts "korrekt" definiert/scaliert sind.
Meine Lösung war, ich schreibe den entsprechenden Buchstaben in eine (etwas grössere) BitMap.
Dann suche ich nach den äussersten gesetzen Pixeln.
So habe ich die pixelgenaue Breite und Höhe, oder auch den linken Abstand zum Rand usw.
Eine "unschöne" Lösung, die aber für meinen Fall brauchbare, pixelgenaue Lösungen ergab.
Code: Alles auswählen
function FindBmpLeft(AsciiNo:Integer):Integer;
var x,y:Integer;
begin
result:=0;
if not Assigned(bmp) then exit;
with bmp do begin
for x:=0 to width-1 do begin
for y:=0 to height-1 do begin
if Canvas.Pixels[x,y] <> clWhite then begin
result:=x;
exit;
end;
end;
end;
end;
end;
Info:
Als ich mich dann mal mit den TrueType Fonts beschäftige, musste ich feststellen, das nicht alle Fonts "korrekt" definiert/scaliert sind.

Zuletzt geändert von siro am Fr 19. Nov 2021, 11:02, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Re: Buchstaben höhe Ermitteln(TCanvas)
- Win 11.pluto hat geschrieben: Fr 19. Nov 2021, 00:52Bist du unter Windows?wp_xyz hat geschrieben:InternalLeading hat bei mir einen vernüftigen Wert, ExternalLeading ist 0
Was für eine Schrift Namen/Größe verwendest du? Hängt das davon ab?
- Fonts: default, Arial, Times New Roman, DejaVu Sans.
- Fontgröße: 32 und 10.
- kupferstecher
- Beiträge: 431
- Registriert: Do 17. Nov 2016, 11:52
Re: Buchstaben höhe Ermitteln(TCanvas)
So hab ich das mal gemacht, glaube war nach einem Vorschlag aus dem englischen Forum.
Müsste man testen, was rauskommt, wenn man C.Canvas.TextHeight('x'); verwendet.
Code: Alles auswählen
Function GetTextHeight(AFont: TFont): Integer;
var C: TBitMap;
begin
Result:= -1;
C := TBitmap.Create;
try
C.Canvas.Font.Assign(AFont);
Result:= C.Canvas.TextHeight('TextHeight');
finally
C.Free;
end;
end;
- 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: Buchstaben höhe Ermitteln(TCanvas)
Hi!
Es ist völlig egal, welcher String bei
Canvas.TextHeight
übergeben wird:
Er gibt immer die aktuelle Canvas.Font.Height zurück.
Winni
Es ist völlig egal, welcher String bei
Canvas.TextHeight
übergeben wird:
Er gibt immer die aktuelle Canvas.Font.Height zurück.
Winni
Re: Buchstaben höhe Ermitteln(TCanvas)
Nein, Canvas.TextHeight nimmt auch den Freiraum über dem Zeichen mit dazu. Am nähesten kommt man an die eigentliche Zeichenhöhe zumindest der Großbuchstaben ran, indem man den Wert von TextMetric.InternalLeading von oben subtrahiert - das ist der Platz über dem Zeichen, der für sowas wie die Ä-Punkte reserviert wird. Aber wie pluto geschrieben hat, ist InternalLeading manchmal null, und das geht dann natürlich nicht mehr.kupferstecher hat geschrieben: Fr 19. Nov 2021, 11:37 So hab ich das mal gemacht, glaube war nach einem Vorschlag aus dem englischen Forum.Code: Alles auswählen
Function GetTextHeight(AFont: TFont): Integer; var C: TBitMap; begin Result:= -1; C := TBitmap.Create; try C.Canvas.Font.Assign(AFont); Result:= C.Canvas.TextHeight('TextHeight'); finally C.Free; end; end;
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Buchstaben höhe Ermitteln(TCanvas)
OK, dann müsste ich nur noch klären warum "TextMetric.InternalLeading" bei mir 0 ist.
Ich hatte gehofft ist gebe eine Pango Funktion oder ähnliches um die Buchstabenhöhe zuermitteln.
Danke für Eure Antworten.
Ich hatte gehofft ist gebe eine Pango Funktion oder ähnliches um die Buchstabenhöhe zuermitteln.
Danke für Eure Antworten.
MFG
Michael Springwald
Michael Springwald
- 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: Buchstaben höhe Ermitteln(TCanvas)
Hi!
Wenn garnix hilft dann Brut Force:
Winni
Wenn garnix hilft dann Brut Force:
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
const MyFontHeight = 12;
var topline,w,x,y : Integer;
bmp: Tbitmap;
begin
bmp := TBitmap.create;
bmp.SetSize(MyFontHeight,100);
bmp.Canvas.Font.Height := MyFontHeight;
bmp.Canvas.TextOut (0,0,'a');
w := bmp.Canvas.TextWidth ('a');
topline := MyFontHeight;
for x := 0 to w-1 do
begin
for y := 0 to MyFontHeight-1 do
begin
if bmp.canvas.Pixels[x,y] <> clWhite then
begin
if Topline > y then Topline := y-1;
break;
end;
end;
end;// x
showMessage ('Zeilen Null bis '+IntToStr(Topline)+' sind weiß'+LineEnding +
'Zeilen ab '+IntToStr(Topline+1)+' werden benutzt');
bmp.free;
end;
Re: Buchstaben höhe Ermitteln(TCanvas)
Hab mir ein kleines Tool geschrieben, dass für alle installierten Fonts die Font- und Text-Metriken anzeigt.
- Dateianhänge
-
- fontinspector.png (17.78 KiB) 4501 mal betrachtet
-
font inspector.zip
- (3.92 KiB) 178-mal heruntergeladen
-
- Beiträge: 758
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: Buchstaben höhe Ermitteln(TCanvas)
S U P E R ! wp_xyz
So kann man das sehr schön inspizieren und hat eine Zugehörigkeit der verschiedenen Parameter.
Ein unverzichtbares Tool zum Verständnis.
So kann man das sehr schön inspizieren und hat eine Zugehörigkeit der verschiedenen Parameter.
Ein unverzichtbares Tool zum Verständnis.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Re: Buchstaben höhe Ermitteln(TCanvas)
Gut!wp_xyz hat geschrieben: Fr 19. Nov 2021, 16:01 Hab mir ein kleines Tool geschrieben, dass für alle installierten Fonts die Font- und Text-Metriken anzeigt.
Eigentlich solltest man dieses Tool gleich mit Lazarus mitliefern.
Vielleicht könnte man es auch sinnvoll zusammenführen mit
/lazarus/examples/fontenum/fontenumeration