Buchstaben höhe Ermitteln(TCanvas)

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
pluto
Lazarusforum e. V.
Beiträge: 7178
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)

Beitrag von pluto »

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?
MFG
Michael Springwald

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

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von wp_xyz »

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):

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);
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.

pluto
Lazarusforum e. V.
Beiträge: 7178
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)

Beitrag von pluto »

Erst mal danke für deine Antwort.
wp_xyz hat geschrieben: Canvas.Line(0, y+tm.Ascender, 100, y+tm.Ascender);
Mir fällt gerade auf, tm.Ascender ich habe immer mit tmascent gearbeitet nie mit 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.
wp_xyz hat geschrieben:Noch mehr Informationen erhält man aus dem TTextMetric-Record
tmInternalLeading und tmExternalLeading sind bei mir immer 0.
Dabei habe ich eine Schrift Art gesetzt und auch eine Schrift Größe gesetzt.
MFG
Michael Springwald

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

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von wp_xyz »

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; 

pluto
Lazarusforum e. V.
Beiträge: 7178
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)

Beitrag von pluto »

wp_xyz hat geschrieben:InternalLeading hat bei mir einen vernüftigen Wert, ExternalLeading ist 0
Bist du unter Windows?
Was für eine Schrift Namen/Größe verwendest du? Hängt das davon ab?
MFG
Michael Springwald

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von siro »

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.

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...

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

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von wp_xyz »

pluto hat geschrieben:
Fr 19. Nov 2021, 00:52
wp_xyz hat geschrieben:InternalLeading hat bei mir einen vernüftigen Wert, ExternalLeading ist 0
Bist du unter Windows?
Was für eine Schrift Namen/Größe verwendest du? Hängt das davon ab?
- Win 11.
- Fonts: default, Arial, Times New Roman, DejaVu Sans.
- Fontgröße: 32 und 10.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von kupferstecher »

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;
Müsste man testen, was rauskommt, wenn man C.Canvas.TextHeight('x'); verwendet.

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: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von Winni »

Hi!

Es ist völlig egal, welcher String bei

Canvas.TextHeight

übergeben wird:

Er gibt immer die aktuelle Canvas.Font.Height zurück.

Winni

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

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von wp_xyz »

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;
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.

pluto
Lazarusforum e. V.
Beiträge: 7178
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)

Beitrag von pluto »

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.
MFG
Michael Springwald

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: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von Winni »

Hi!

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;
Winni

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

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von wp_xyz »

Hab mir ein kleines Tool geschrieben, dass für alle installierten Fonts die Font- und Text-Metriken anzeigt.
Dateianhänge
fontinspector.png
fontinspector.png (17.78 KiB) 2012 mal betrachtet
font inspector.zip
(3.92 KiB) 127-mal heruntergeladen

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von siro »

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.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

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

Re: Buchstaben höhe Ermitteln(TCanvas)

Beitrag von theo »

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.
Gut!
Eigentlich solltest man dieses Tool gleich mit Lazarus mitliefern.
Vielleicht könnte man es auch sinnvoll zusammenführen mit
/lazarus/examples/fontenum/fontenumeration

Antworten