fpttf wie benutzen?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

fpttf wie benutzen?

Beitrag von thosch »

Hallo,


Im Ordner c:\lazarus\fpc\<version>\source\packages\fcl-pdf\src\ befinden sich neben PDF Dingen True Type Font Units.

Ich studiere jetzt seit Sonntag den Quelltext, habe aber noch nicht herausgefunden, wie ich damit einen geladenen True Type Font auch anzeigen kann.

Ich habe folgenden Ansatz:

Code: Alles auswählen

program fpttftest;

{mode objfpc}{$H+}

uses
  fpttf,
  fpttfsubsetter,
  fpttfencodings,
  fpfonttextmapping,
  fpparsettf;
  
{$I fontmetrics_stpdf.inc}  

type
  TFontManager = class
  private
    FontSubs: TFontSubSetter;            //Die Klasse aus der Unit fpttfsubsetter.pp
    FontFile: TFontFileInfo;                   //Die Klasse aus der Unit fpparsettf um die Fontdatei zu laden und auszulesen
    MappingL: TTextMappingList;       //Um die Glyphs in eine Liste zu bringen. Glyphindex stimmt nicht mit Zeichenindex überein, deshalb muss da eine Zuordnung 
  public                                               //aufgebaut werden
    constructor Create(AFontFileName: String);
    destructor Destroy; override;
    procedure printtextxy(X,Y: Integer; Text: String; Color: longword);
  end;

constructor Create(AFontFileName: String);
begin
  FontFile: TFontFileInfo.Create;
  FontFile.Filename := AFontFilename;
  MappingL := TTextMappingList.Create;
  FontSubs := TFontSubSetter.Create(FontFile, MappingL);
end;

destructor Destroy;
begin
  FontSubs.Free;
  inherited Destroy;
end;

procedure printtextxy(
     X,Y: Integer; 
     Text: String;           //Auszugebender Text unter Benutzung des Fonts, der Text gibt mit seinen Zeichencodes den Char Index, den ich brauche um den richtigen Glyphen 
                                   //aus der TextmappingList auszuwählen, so verstehe ich den Sinn dieser Textmappinglist.
     Color: longword   //Textfarbe
     );
begin
   //Welche Daten aus den ttf Headren muss ich wie verwenden um die Zeichen darzustellen. Zur Ausgabe soll eine PutPixel Routine dienen, aber die braucht die richtigen Daten aus 
   //den Headern. Freetype nutzt Glpyps, die in Bitmaps umgewandelt werden, aber wie macht fpttf das? 
end;

var
  FontManager: TFontManager;
  
procedure LoadFont(AFileName: String);
begin
  FontManager := TFontManager.Create(AFilename);
end;  

begin
  LoadFont(Filename);
  
  prinntextxy(50,50,'Mein TrueType Font!', colgreen);

end.
Aus den Quelltexten lese ich heraus, dass die TextmappingList beim Einlesen des Font aufgebaut wird. In der Unit fpparsettf gibt es einen Record TGlyphHeader, der aber in keinem der Quellcodes benutzt wird.

Wie also bekomme ich die richtigen Daten zur Anzeige der Fontzeichen?

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: fpttf wie benutzen?

Beitrag von six1 »

Im Projektfile unter Uses einfügen:

Code: Alles auswählen

  {$IFDEF Windows}
  , jwawinGDI  // for binding  Font ONLY WIN!
  {$ENDIF}
vor Application.createform und .run einfügen:

Code: Alles auswählen

var
   sFontFile : String;
begin
  {$IFDEF Windows}
  sFontFile := '[Deine TTF Datei mit absolutem oder relativem Pfad].ttf';
  If FileExists(sFontFile) Then
     AddFontResourceEx(PChar(sFontFile), FR_PRIVATE, nil);
  {$ENDIF}
Font Name einer Komponente zuweisen; fertig.

Hatte ich hier mal im Forum gefunden, leider finde ich es im Moment nicht auf Anhieb, wer das veröffentlicht hatte...

EDIT: Hab's gefunden:
viewtopic.php?p=88366#p88366
Gruß, Michael

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: fpttf wie benutzen?

Beitrag von thosch »

Ja ok, danke so weit, damit gibt Windows also dann automatisch die Schriftzeichen genau dieses Font's aus, wenn ich das richtig verstanden habe.

Aber wie geht das für andere Betriebssysteme dann?

Das ist der Grund warum ich noch eine Variante suche, die überall funktioniert und deshalb sicherheitshalber ohne externe hinzu zu linkende Bibliotheken auskommen sollte.

Deshalb wollte ich das mit den fpttf Units machen. Außeredem zeigt mir fpttf und Co. wie der ttf Font vorher eingelesen wird.

Freetype 1 funktioniert hier leider nicht, da dibt es Fehler beim Laden der Glyphs und Initialisieren der Instanzvariablen. Freetype 2 benutzt externe Bibliotheken.

Da setze ich nun meine Hoffnung auf fpttf aus dem im Eingangsbeitrag benannten Ordner.

Damit werden die ttf Daten in Datenstrukturen eingelesen.

Freetype 1 konvertiert dann das Glyph in eine Bitmap, die dann ausgegeben wird.

Aber hier mit fpttf müsste ich dazu auf andere Daten zugreifen als Freetype 1 weil der Codeaufbau anders ist als dort. Und Freetype 1 benutzt die fpttf Units nirgends.

Freetype 1 macht es so:

Code: Alles auswählen

var Bit: TT_Raster_Map;

    Bit.rows  := round(metrics.bbox.ymax / (1 shl 6));
    Bit.cols  := round(metrics.bbox.xmax / (1 shl 6));
    Bit.width := round(metrics.bbox.xmax / (1 shl 6));
    Bit.flow  := TT_Flow_Down;
    Bit.size  := Bit.cols*Bit.rows;
     GetMem( Bit.buffer, Bit.size );
   fillchar( Bit.buffer^, Bit.size, 0 );

// TT_Get_Outline_Pixmap( outline, Bit );

TT_Get_Glyph_Pixmap( glyph, Bit, 0, 0);

 allocimage(img,bit.width,bit.rows);

 for y:=0 to bit.rows-1 do
  for x:=0 to bit.width-1 do begin
    
	b:= pbyte(pointer(bit.buffer)+y * bit.width + x)^;
    col:=rgba(b*64,b*64,255,255);
    putpixel(img,x,y,col);
  end;

Aber Bit hat in seinen Feldern überall den Wert Null stehen und da kann natürlich nichts ausgegeben werden.

Gibt es denn nicht noch eine andere Variante um Truetype Fonts auszugeben? Ich meine eine Systemunabhängige.

Wie könnte ich denn die benötigten Daten für die Glyphausgabe aus dem fpttf Code bekommen um dann das/die Zeichen genau so auszugeben?

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

Re: fpttf wie benutzen?

Beitrag von wp_xyz »

thosch hat geschrieben:
Do 1. Apr 2021, 22:15
Wie also bekomme ich die richtigen Daten zur Anzeige der Fontzeichen?
Heißt das, dass du wissen willst, wie du einen True-Type-Font selbst und unabhängig vom Betriebssystem auf einem Canvas zeichnen kannst? Dazu gibt es ein Beispiel im Ordner examples/lazfreetype deiner Lazarus-Installtion. Beachte: Das Programm ist etwas bescheuert und verlangt drei Front-Dateien (mit Pfad und Extension) auf der Kommandozeile.
Zuletzt geändert von wp_xyz am Fr 2. Apr 2021, 12:21, insgesamt 1-mal geändert.

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: fpttf wie benutzen?

Beitrag von thosch »

wp_xyz hat geschrieben: Heißt das, dass du wissen willst, ...

Ja, genau das heißt es!

Danke deshalb für den Hinweis, ich guck mir das Beispiel an.

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: fpttf wie benutzen?

Beitrag von thosch »

Das Beispiel läuft gut, aber setzt zu viele Windows lastige Units voraus quer durch die Lazarusinstallation durch. Das liegt an den in den Freetype Units wiederum vorausgesetzten Units, das verzweigt sich dann echt weit.

Gibt es da wirklich keine echt systemunabhängige Lösung?

Die ohne externe Bibliotheken auskommt?

Deshalb dachte ich ja an die Units aus fcl-pdf, die ttf Units davon.

Das oben genannte Programmbeispiel setzt noch viele andere leider Windows lastige Units voraus, da alles was Windows benutzt aber für die Fonts nicht gebraucht wird, raus zu werfen ist ordentlich viel Arbeit, eine Notlösung dann.

Gibt es wirklich keine Möglichkeit ohne Systemabhängige Teile?

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: fpttf wie benutzen?

Beitrag von PascalDragon »

thosch hat geschrieben:
So 4. Apr 2021, 13:23
Das Beispiel läuft gut, aber setzt zu viele Windows lastige Units voraus quer durch die Lazarusinstallation durch. Das liegt an den in den Freetype Units wiederum vorausgesetzten Units, das verzweigt sich dann echt weit.
Ich sehe da keine "Windows lastigen" Units. LazFreeType und FreeType nutzen nur allgemein verfügbare Units.
thosch hat geschrieben:
So 4. Apr 2021, 13:23
Gibt es da wirklich keine echt systemunabhängige Lösung?
LazFreeType und FreeType sind systemunabhängig.
thosch hat geschrieben:
So 4. Apr 2021, 13:23
Die ohne externe Bibliotheken auskommt?
LazFreeType und FreeType kommen ohne externe Bibliotheken aus. Das was verwendet wird, wird von der FPC RTL eh vorausgesetzt.
FPC Compiler Entwickler

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: fpttf wie benutzen?

Beitrag von thosch »

Da ergibt sich die Frage ob die Units der FPC RTL die dann noch verwendet werden wirklich ohne Windows auskommen.

EasyLazFreeType nutzt zum Beispiel LazUTF8 und LazUTF8 verwendet schon mal die Windows Unit.

Ich könnte versuchen mal die Windows Unit auszukommentieren und alles was dann die Übersetzung behindert und dann gucken ob mein TruetypeFont noch korrekt geladen und angezeigt wird.

Wenn das funktioniert, könnte ich das so machen dass ich die Windowsspezifischen Teile auskommentiere wenn ich meine TrueType Fonts in anderen Systemen nutzen will.

LazUTF8 nutzt allerdings eine Unit cwstring, bei der ich nicht sicher bin, ob es die in allen Systemen die von FPC unterstützt werden, auch gibt.

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

Re: fpttf wie benutzen?

Beitrag von wp_xyz »

Natürlich geht das ohne Windows. Wo findest du denn in den LazFreeType-Units und in LazUTF8 ein "uses Windows"? Der beigefügte Screenshot stammt von LMDE 4 Linux.
Dateianhänge
LazFreeType_LMDE.png
LazFreeType_LMDE.png (23.73 KiB) 2214 mal betrachtet

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: fpttf wie benutzen?

Beitrag von thosch »

Ok, Du machst das in Linux, dort soll das später auch funktionieren.

Direkt in den EasyFreetype Units ist kein Windows Bezug, in der Windows Version von lazutf8.pas sieht die Uses Klausel so aus:

Code: Alles auswählen

uses
  {$ifdef unix}
  // WideCompare* functions on Unix requires this. Must be used although it pulls in clib.
  cwstring,
  {$endif}
  {$IFDEF UTF8_RTL}
  FPCAdds,
  {$ENDIF}
  {$ifdef windows}  
  Windows, //Hier wird Windows eingebunden und
  {$endif}   //dann wahrscheinlich auch verwendet
   Classes, SysUtils, strutils;
Nun ist ja zum Beispiel in den if Anweisungen der bedingten Compilierung zwar Windows und Linus (Unix) dabei aber nicht Android.

Was also wenn ich das für Android auch haben will?

Das geht dann nur wenn die Windows Teile hier zur Darstellung der Fonts nicht benutzt werden oder nur Windows Typen verwendet werden aber keine Funktionen. Für diesen Fall habe ich eine private Lösung geschaffen. Wenn aber Windows Funktionen aufgerufen werden bei der Bearbeitung der Truetype Fonts, wird es schwierig.
Wenn keine systemspezifischen Teile, weder aus Unix noch aus Windows für mein Anliegen aufgerufen werden geht es auch. Dann kann ich die systemspezifischen Teile hier auskommentieren. Aber ist das so?

Warum müssen in Linus die WideCompare Funktionen verwendet werden?

Ist das auch unter Windows der Grund für die Einbindung von Windows und wenn ja wie wäre das zu umgehen? Warum WideCompare?

Und was bedeutet links oben im Beispiel die Angabe X ms + Y ms? Wobei die Variablen X und Y hier für die beiden Zahlen stehen die sich verändern wenn ich die Schrift verschiebe oder in der Größe verändere.

Nun werde ich erst mal die GUI von der TTF Logik trennen.

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

Re: fpttf wie benutzen?

Beitrag von wp_xyz »

LazUTF8 ist eine viel allgemeinere Unit als für FreeType benötigt wird. Wenn das Windows-Define aktiv ist, wird z.B. die Funktion GetFormatSettingsUTF8 zur Verfügung gestellt, die die FormatSettings nach UTF8 konvertiert - das hat nix mit FreeType zu tun. Dass das FreeType-Demo unter Linux und, wie ich gerade ausprobiert habe, unter macOS läuft, zeigt, dass da keine Windows-Funktion in die Quere kommt.

Mit Android kenne ich mich nicht aus, aber meines Wissens wird das durch den Fall "IFDEF Unix" abgedeckt.

cwstrings braucht FPC intern für Stringkonvertierung, hat direkt nix mit FreeType zu tun.

X ms + Yms? Keine Ahnung. Eine Ausgabe des Demo-Programms, vielleicht eine Geschwindigkeitsmessung. Ich habe nicht vor, für dich jetzt dieses Programm bis ins Detail zu analysieren. Die Frage war, ob man LazFreeType auch auf Nicht-Windows-Systemen verwenden kann, und die Antwort heißt: Ja.

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: fpttf wie benutzen?

Beitrag von thosch »

wp_xyz hat geschrieben: LazUTF8 ist eine viel allgemeinere Unit als für FreeType benötigt wird. Wenn das Windows-Define aktiv ist, wird z.B. die Funktion GetFormatSettingsUTF8 zur Verfügung gestellt, die die FormatSettings nach UTF8 konvertiert - das hat nix mit FreeType zu tun. Dass das FreeType-Demo unter Linux und, wie ich gerade ausprobiert habe, unter macOS läuft, zeigt, dass da keine Windows-Funktion in die Quere kommt.
Perfekt, dann sollte das auch überall funktionieren. Schon klar dass Units auch Code enthalten der von meinem Konkreten Projekt gerade nicht aufgerufen wird. In einem anderen Projekt dagegen schon, deshalb hat man ja solche Units mit allgemein verwendbarem Code und intelligentem Linken, der Code der im Projekt nicht benötigt wird, wird vom Compiler gar nicht erst in die EXE übernommen (smart linking). So muss ich mir also keine Sorgen machen.
wp_xyz hat geschrieben: Mit Android kenne ich mich nicht aus, aber meines Wissens wird das durch den Fall "IFDEF Unix" abgedeckt.
Solltr dann auch mit Android funktionieren, nicht nur weil Unix mit ifdef unix mit abgedeckt ist, sondern weil gar keine Systemspzifischen Codeteile verwendet werden
wp_xyz hat geschrieben: cwstrings braucht FPC intern für Stringkonvertierung, hat direkt nix mit FreeType zu tun.
OK, verstehe.
wp_xyz hat geschrieben: X ms + Yms? Keine Ahnung. Eine Ausgabe des Demo-Programms, vielleicht eine Geschwindigkeitsmessung. Ich habe nicht vor, für dich jetzt dieses Programm bis ins Detail zu analysieren. Die Frage war, ob man LazFreeType auch auf Nicht-Windows-Systemen verwenden kann, und die Antwort heißt: Ja.
Du musst jetzt auch nicht das Programm für mich analysieren, das kriege ich schon selber hin und ich will ja auch was dabei lernen und das geht nur, wenn ich mich damit selber beschäftige. :) Meine Frage ob das ohne Systemspezifische Dinge läuft ist ja nun hiermit auch beantwortet. Klasse das geht also so wie ich das haben will. Somit ist das genau das was ich gesucht habe. Klar enthalten die Units auch Code der im konkreten Projekt, das ich gerade realisieren will, nicht gebraucht wird, dafür in einem anderen, aber wissen muss ich das. Gut, dass der Systemspezifische Code hier also nicht benutzt wird. Dann kann ich das für meinen Zweck so verwenden. Wunderbar, genau was ich gesucht habe. :)

Danke nochmals für die Mühe und die Hilfe. :)

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: fpttf wie benutzen?

Beitrag von PascalDragon »

thosch hat geschrieben:
So 4. Apr 2021, 16:10
Da ergibt sich die Frage ob die Units der FPC RTL die dann noch verwendet werden wirklich ohne Windows auskommen.
Es kann dir doch egal sein, ob die RTL unter Windows Windows-spezifische Units verwendet. Unter anderen Betriebssystemen werden die entsprechenden Units für das jeweile Betriebssystem verwendet. Die API, die durch die RTL bereitgestellte API ist plattformunabhängig. Was im Hintergrund abläuft ist für dich in 99% der Fälle nicht wichtig.
thosch hat geschrieben:
So 4. Apr 2021, 19:24
Was also wenn ich das für Android auch haben will?
Android ist ein Unix-like, das heißt das UNIX-Define ist da ebenfalls aktiv.
thosch hat geschrieben:
So 4. Apr 2021, 19:24
Warum müssen in Linus die WideCompare Funktionen verwendet werden?
Weil hier eben Unicode verglichen wird und dafür sind die Wide*-Funktionen eben da.
FPC Compiler Entwickler

Antworten