Delphi-PRAXiS
Seite 3 von 6     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Textlänge abschneiden (https://www.delphipraxis.net/189448-textlaenge-abschneiden.html)

Sir Rufo 17. Jun 2016 22:38

AW: Textlänge abschneiden
 
Zitat:

Zitat von EWeiss (Beitrag 1340496)
Ich werde nie auch nur halbwegs an die korrekte breite jedes einzelnen Chars herankommen.

Hört sich ja fast so an, als ob OpenGL = Quanten-Physik ist.

Wenn man die Breite nicht bestimmen kann, dann kann man das auch nicht zeichnen, weil der Bildschirm hat einfach nur Pixel und die müssen mit Farbe gefüllt werden :stupid:

Ausserdem machst du das doch genau hier:
Delphi-Quellcode:
// Parse width of Glyph
  for I := 0 to High(Char) do
  begin
    Char[I] := WideChar(SongNameTmp[I]);
    // .......... vvvvvvvvvvvvvvvvvvvvvvv
    CharLength := tsFontGetCharParameteri(Char[I], TS_CHAR_GLYPHRECT_RIGHT);

    CharLen := CharLen + CharLength;
  end;
Irgendwann läufst du aus dem Maximalbereich heraus und musst jetzt den Text soweit kürzen, dass aber auch der Suffix noch dargestellt werden kann.

Nehmen wir mal eine feste Breite von 20 (das Verfahren ist genau wie bei der varaiblen Laufweite, nur einfacher darzustellen) und als Suffix
Delphi-Quellcode:
... (more)
:

OriginalgekürztKommentar
1234567890123456789012345678901234567890Original passt, da brauchen wir nichts zu kürzen
1234567890123456789011234567890... (more)hier müssen wir kürzen

Beim Kürzen des Textes muss man also wieder ein paar Zeichen zurück gehen ... oder sich diesen speziellen Zustand einfach merken.

Du musst also nichts anderes machen als
  1. Die Breite des Suffixs zu bestimmen
    Delphi-Quellcode:
      lSuffixLength := 0;
      for lChar in ShortenSuffix do
        begin
          lSuffixLength := lSuffixLength + CharMeasurement( lChar ); // <- das könnte auch eine OpenGL-Zeichenbreiteermittlungsfunktion sein
        end;
  2. Jetzt den Text Zeichen für Zeichen durcharbeiten
    Delphi-Quellcode:
      Result := '';
      lText := TrimRight( Text );
      lTextLength := 0;
      lShortendWithSuffixFound := False;

      for lChar in lText do
        begin
          lCharLength := CharMeasurement( lChar ); // <- das könnte auch eine OpenGL-Zeichenbreiteermittlungsfunktion sein
  3. dabei aber den Zeitpunkt abpassen, wenn die bisher ermittelte Textlänge mit der Suffixlänge und dem aktuellen Zeichen über die Maximallänge hinausgeht. Denn den Text solltest du dir für den Fall der Fälle merken, wenn du den Text kürzen musst. Das ist bei dir aktuell diese ominöse 58
    Delphi-Quellcode:
          if not lShortendWithSuffixFound and ( lTextLength + lCharLength + lSuffixLength > MaxLength )
          then
            begin
              lShortenedWithSuffix := Result + ShortenSuffix;
              lShortendWithSuffixFound := True;
            end;
  4. Wenn man dann über die Maximallänge kommt gibt man einfach diesen eben gemerkten Text zurück
    Delphi-Quellcode:
          if lTextLength + lCharLength > MaxLength
          then
            begin
              Result := lShortenedWithSuffix; // <- das ist das gesuchte Ergebnis
              Exit;
            end;
  5. ansonsten einfach mal zusammenzählen und zum nächsten Zeichen
    Delphi-Quellcode:
          Result := Result + lChar;
          Inc( lTextLength, lCharLength );
        end;

EWeiss 17. Jun 2016 22:49

AW: Textlänge abschneiden
 
Zitat:

Hört sich ja fast so an, als ob OpenGL = Quanten-Physik ist.
LOL..

Ach so jetzt verstehe ich was du meinst es geht hier nicht im speziellen um GDI
sondern ich könnte/sollte diese Parse Funktion zu GL konvertieren bsp. mit meinen
Möglichkeiten die breite eines Zeichen zu bestimmen.

Anschließend deine Funktionen durchgehen um zu verstehen wie ich den String in der länge entsprechend anpassen kann.

Jo das kann ich mal versuchen.

Danke für deine Ausführung..
Hoffe das ich richtig liege :)

gruss

Sir Rufo 17. Jun 2016 22:56

AW: Textlänge abschneiden
 
Ja, darum habe ich die
Delphi-Quellcode:
ShortenText
extra so ausgelegt, dass die Bestimmung der Zeichenbreite per Callback-Funktion übergeben werden kann. Dadurch wird der Code allgemeingültig und ist eben nicht auf GDI beschränkt.

Das Bestimmen der Zeichenbreite ist eine andere Problematik als das Bestimmen des gekürzten Textes. So etwas vermische ich nicht so gerne, sonst muss ich immer so viel Tippen :stupid:

EWeiss 17. Jun 2016 22:59

AW: Textlänge abschneiden
 
Zitat:

Zitat von Sir Rufo (Beitrag 1340499)
Ja, darum habe ich die
Delphi-Quellcode:
ShortenText
extra so ausgelegt, dass die Bestimmung der Zeichenbreite per Callback-Funktion übergeben werden kann. Dadurch wird der Code allgemeingültig und ist eben nicht auf GDI beschränkt.

Das Bestimmen der Zeichenbreite ist eine andere Problematik als das Bestimmen des gekürzten Textes. So etwas vermische ich nicht so gerne, sonst muss ich immer so viel Tippen :stupid:

Ok ;)

Danke nochmals..
Kam irgendwie nicht so richtig bei mir an.

gruss

nahpets 17. Jun 2016 23:03

AW: Textlänge abschneiden
 
Ich versuchs mal mit 'ner anderen Beschreibung:

Du hast oben in Post #14 eine Routine, mit der die Textlänge bestimmt werden kann.

Die Maximallänge scheint 635 zu sein.

Zuerst ermittelst du die Länge von'...' und ziehst diese von 635 ab.
Das ist erstmal die neue Maximallänge.

Nun ermittelst Du in einer Schleife die Länge des Textes und wenn er länger als die neue Maximallänge ist, entfernst Du das letzte Zeichen und prüfst erneut.
Das wird solange wiederholt, bis die ermittelte Länge kleiner oder gleich der neuen Maximallänge ist.
An den bis dahin gekürzten String hängst Du nun noch die ... dran, dann müsste es (so hoffe ich) passen.

EWeiss 17. Jun 2016 23:12

AW: Textlänge abschneiden
 
Zitat:

Zitat von nahpets (Beitrag 1340501)
Ich versuchs mal mit 'ner anderen Beschreibung:

Du hast oben in Post #14 eine Routine, mit der die Textlänge bestimmt werden kann.

Die Maximallänge scheint 635 zu sein.

Zuerst ermittelst du die Länge von'...' und ziehst diese von 635 ab.
Das ist erstmal die neue Maximallänge.

Nun ermittelst Du in einer Schleife die Länge des Textes und wenn er länger als die neue Maximallänge ist, entfernst Du das letzte Zeichen und prüfst erneut.
Das wird solange wiederholt, bis die ermittelte Länge kleiner oder gleich der neuen Maximallänge ist.
An den bis dahin gekürzten String hängst Du nun noch die ... dran, dann müsste es (so hoffe ich) passen.

Ok Danke..
Ich baue gerade das Projekt von Sir Rufo um für D2010
Danach teste ich mal deine Variante.

gruss

Sir Rufo 17. Jun 2016 23:16

AW: Textlänge abschneiden
 
@nahpets

Nicht ganz.
  1. Länge des Texts bestimmen
  2. Ist die Länge kleiner als die Maximallänge, dann fertig - sonst
  3. Die Länge des Suffix bestimmen
  4. Beim Text schrittweise immer das letzte Zeichen entfernen bis die Länge kleiner als (Maximallänge - Suffixlänge) ist

@EWeiss

Beide Wege machen im Prinzip das Gleiche. Man müsste nur schauen, wer schneller ist.

Optimieren (Geschwindigkeit) kann man beide Verfahren noch.

Bei meiner Funktion kann man über eine Lookup-Tabelle die Anzahl der echten Abfragen stark reduzieren (wenn jedes Zeichen auch immer gleich breit bleibt).

Bei der Text-Funktion kann man die Zeichenanzahl erst mal per Schätzung bestimmen um dann nur noch wenige Zeichen zu entfernen.

Die Hauptfrage ist, was ist für OpenGL schneller: Einen ganzen Text mehrmals zu messen oder jeweils ein Zeichen

EWeiss 17. Jun 2016 23:24

AW: Textlänge abschneiden
 
@Sir Rufo

Habe dein Projekt jetzt mal umgelegt nach D2010
Ging nicht auf Anhieb lSuffixLength musste ein globale Variable sein.

Werde jetzt mal nach GL umlegen.
Über die PaintBox sieht es schon mal gut aus.

gruss

Sir Rufo 17. Jun 2016 23:29

AW: Textlänge abschneiden
 
Zitat:

Zitat von EWeiss (Beitrag 1340504)
@Sir Rufo

Habe dein Projekt jetzt mal umgelegt nach D2010
Ging nicht auf Anhieb lSuffixLength musste ein globale Variable sein.

Das wundert mich doch sehr. Kannst du den Code mal zeigen?

EWeiss 17. Jun 2016 23:36

AW: Textlänge abschneiden
 
Zitat:

Zitat von Sir Rufo (Beitrag 1340505)
Zitat:

Zitat von EWeiss (Beitrag 1340504)
@Sir Rufo

Habe dein Projekt jetzt mal umgelegt nach D2010
Ging nicht auf Anhieb lSuffixLength musste ein globale Variable sein.

Das wundert mich doch sehr. Kannst du den Code mal zeigen?

Klar! Hänge ihn an.
Der Compiler hat gemeckert das lSuffixLength nicht initialisiert war.. also (33339483884) so ne zahl.

Delphi-Quellcode:
raise EArgumentNilException.Create( 'CharMeasurement' );


Musste ich ausblenden gibt es scheinbar in D2010 nicht.

Delphi-Quellcode:
raise EArgumentOutOfRangeException.Create( 'SuffixLength > MaxLength' );


kommt immer sobald ich einen Char eingebe habe es deaktiviert.


opps zurück hab vergessen den anderen Kram noch auszublenden war mein Fehler.
Delphi-Quellcode:
//   if not Assigned( CharMeasurement )
//   then
//     raise EArgumentNilException.Create( 'CharMeasurement' );
//   if MaxLength < 0
//   then
//     raise EArgumentOutOfRangeException.Create( 'MaxLength'
Korrigierte Version hochgeladen D2010

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:37 Uhr.
Seite 3 von 6     123 45     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz