AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Textlänge abschneiden

Ein Thema von EWeiss · begonnen am 14. Jun 2016 · letzter Beitrag vom 19. Jun 2016
Antwort Antwort
Seite 3 von 6     123 45     Letzte »    
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#21

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 22:38
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

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 ... (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;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (17. Jun 2016 um 22:58 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#22

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 22:49
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
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#23

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 22:56
Ja, darum habe ich die 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
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#24

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 22:59
Ja, darum habe ich die 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
Ok

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

gruss
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#25

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 23:03
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.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#26

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 23:12
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
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#27

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 23:16
@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
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (17. Jun 2016 um 23:26 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#28

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 23:24
@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
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#29

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 23:29
@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?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#30

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 23:36
@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.

raise EArgumentNilException.Create( 'CharMeasurement' );

Musste ich ausblenden gibt es scheinbar in D2010 nicht.

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

Geändert von EWeiss (11. Jul 2019 um 16:02 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 6     123 45     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:57 Uhr.
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