AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Textlänge abschneiden

Ein Thema von EWeiss · begonnen am 14. Jun 2016 · letzter Beitrag vom 19. Jun 2016
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Textlänge abschneiden

  Alt 18. Jun 2016, 15:55
Zitat:
Liefert tsTextGetWidthA für 'iiiiiiii' und 'wwwwwwww' eigentlich das gleiche Ergebnis?
Nein natürlich nicht.
Da es sich nicht um einen Monotonen Font handelt.
Aber das verstehen einige Leute hier nicht.

Arial:
I = 11
W = 25

Courier New
i= 25
W =25

Mit W bin ich also früher an die grenze von 635 gestoßen als mit I
Das führt dazu das der Umbruch viel früher stattfindet als bei I.
Der Abstand zu der Zeitanzeige ist dann logischer weise Unterschiedlich.

Zitat:
Zitat:
// Ist von der Breite so angelegt, dass mit Courier New 8 genau 80 Zeichen hineinpassen
Wie schon gesagt..
Funktioniert 100% solange es ein Monotoner Font ist.
Wenn nicht vergiss es denn dann Passen keine 80 Zeichen mehr hinein.

Man könnte das jetzt weiter verfolgen, aber mich scheinen einige Leute für so blöd zu halten
das ich nicht mal in der Lage bin einen Canvas den richtigen Font zuzuweisen.
Von daher vergesse ich das Thema jetzt hier.

Wenn Lossy im GL Forum zeit hat hineinzuschauen werde ich eine Antwort finden.
Danke für eure Hilfe.

gruss

Geändert von EWeiss (18. Jun 2016 um 16:03 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#2

AW: Textlänge abschneiden

  Alt 18. Jun 2016, 17:53
Zitat:
Liefert tsTextGetWidthA für 'iiiiiiii' und 'wwwwwwww' eigentlich das gleiche Ergebnis?
Nein natürlich nicht.
Das hatte ich egentlich auch nicht erwartet und daher verwundert es mich, dass das Ganze nur mit Monotonen Font funktioniert.
Da es sich nicht um einen Monotonen Font handelt.
Aber das verstehen einige Leute hier nicht.

Arial:
I = 11
W = 25

Courier New
i= 25
W =25

Mit W bin ich also früher an die grenze von 635 gestoßen als mit I
Das führt dazu das der Umbruch viel früher stattfindet als bei I.
Der Abstand zu der Zeitanzeige ist dann logischer weise Unterschiedlich.
Von einem Ergebnis dieser Art bin ich eigentlich ausgegangen.
Zitat:
Zitat:
// Ist von der Breite so angelegt, dass mit Courier New 8 genau 80 Zeichen hineinpassen
Wie schon gesagt..
Funktioniert 100% solange es ein Monotoner Font ist.
Wenn nicht vergiss es denn dann Passen keine 80 Zeichen mehr hinein.
Bei Arial würd' ich hier jetzt davon ausgehen, dass 57 i oder 25 W passen.
Man könnte das jetzt weiter verfolgen, aber mich scheinen einige Leute für so blöd zu halten
das ich nicht mal in der Lage bin einen Canvas den richtigen Font zuzuweisen.
Den Eindruck, dass Dich hier im Thread irgendwer für blöd hält, habe ich nicht. Das Problem, mit dem Du Dich da rumschlägst, ist von der Logik her nicht zu fassen. Eigentlich müsste Dein Vorgehen zu einem richtigen Ergebnis führen und ebenso auch die anderen Lösungsvorschläge. Irritierend ist halt, dass dem nicht so ist. Aber dass hat doch nichts mit Deiner Person zu tun.
Von daher vergesse ich das Thema jetzt hier.

Wenn Lossy im GL Forum zeit hat hineinzuschauen werde ich eine Antwort finden.
Danke für eure Hilfe.

gruss
Momentan gehe ich davon aus, dass das Problem an einer Stelle liegt, auf die Du als Programmierer keinen Zugriff hast, also irgendwo innerhalb der von Dir genutzten Bibliothek.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Textlänge abschneiden

  Alt 18. Jun 2016, 18:27
Zitat:
Bei Arial würd' ich hier jetzt davon ausgehen, dass 57 i oder 25 W passen.
Ich denke das Problem liegt an der Herangehensweise.
Man muss sich nur mal diese Aussage anschauen.

Zitat:
// Ist von der Breite so angelegt, dass mit Courier New 8 genau 80 Zeichen hineinpassen
Label2.Caption := ShortenText( Edit1.Text, 80, CalculateFixedCharWidth );
Es passen also exakt 80 Zeichen in einer breite von 560 hinein.
Somit ist gewährleistet das egal welche Zeichen es sind diese immer eine fixe breite von 7 haben (560 div 80)

Wenn ich nun davon ausgehe das bei einer fixen Weite von 560

SongName := PAnsiChar(AnsiString(Ansimidstr(string(SongName),1, 80) + '...'));

80 Zeichen reinpassen dann wird mein SongTitel genau egal welche Zeichen dieser enthält (gleiche Breite pro Char)
100% und immer kurz vor meiner Zeitanzeige gezeichnet.

Jetzt ändere mal den Font wo die Zeichen nicht mehr gleich sind.
Tja nun dann ist diese Aussage nicht mehr rechtens
Zitat:
// Ist von der Breite so angelegt, dass mit Courier New 8 genau 80 Zeichen hineinpassen
es passen dann einfach keine 80 Zeichen mehr rein.
Das würde dann unweigerlich Fehlschlagen

SongName := PAnsiChar(AnsiString(Ansimidstr(string(SongName),1, 80) + '...'));

gruss
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#4

AW: Textlänge abschneiden

  Alt 18. Jun 2016, 18:52
Eventuell noch ein anderer Ansatz:
Delphi-Quellcode:
begin
  fMaxLen := 635; // Die maximal zulässige Breite der Zeichenfolge in der Anzeige.
  fMaxStrLen := tsTextGetWidthA(SongName); // Aktuelle Breite ermitteln.
  if fMaxStrLen >= fMaxLen then begin // Ist die größer als die Maximalbreite?
    SongName := SongName + '...'; // dann ... anhängen
    fMaxStrLen := tsTextGetWidthA(SongName); // und die neue Breite ermitteln.
    repeat // Solange wiederholen
      Delete(SongName,Length(SongName) - 4,1); // viertletztes Zeichen entfernen
      fMaxStrLen := tsTextGetWidthA(SongName); // Neue Breite ermitteln.
    until fMaxStrLen <= fMaxLen; // Bis die Breite <= der Maximalbreite ist.
  end;
end;
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: Textlänge abschneiden

  Alt 18. Jun 2016, 18:57
Dank dir werde es mal testen.

gruss
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Textlänge abschneiden

  Alt 18. Jun 2016, 21:13
Mit Lossys Hilfe funktioniert es jetzt wie soll.
Nochmals Danke für seine Hilfe.

Delphi-Quellcode:
      // Only change if Title different
      if (CurrentTitle <> OldTmpTitle) then
      begin
        // Adding all the characters that are present in the text
        tsFontAddChars(@SongNameTmp[0]);

        //Get max length of String
        fMaxStrLen := tsTextGetWidthA(SongNameTmp);
        if fMaxStrLen >= 635 then
        begin
          // Since we want to '...' have in any case at the end we need these characters to only.
          CharLen := tsFontGetCharParameteri('.', TS_CHAR_ADVANCE) * 3;

          // Parse width of Glyph
          for I := 0 to High(Char) do
          begin
            // read and add width of the current character
            Char[I] := WideChar(SongNameTmp[I]);
            CharLength := tsFontGetCharParameteri(Char[I], TS_CHAR_ADVANCE);
            CharLen := CharLen + CharLength;
            // If the width is greater than the available space, then loop exit
            if CharLen >= 635 then
              break;
          end;
          // Here is through the loop and our new text is from 1 to i-1.
          SongName := PAnsiChar(Ansistring(Ansimidstr(string(SongNameTmp), 1, i-1) + '...'));
        end
        else
          SongName := BassSoInfo.SongTitle;

        CurrentTitle := OldTmpTitle;
      end;
Mit dem ganzen VCL Kram war das nicht zu bewerkstelligen.
Ist abhängig von der Bibliothek mit der Gezeichnet wird.

Zitat:
Eigentlich müsste Dein Vorgehen zu einem richtigen Ergebnis führen und ebenso auch die anderen Lösungsvorschläge. Irritierend ist halt, dass dem nicht so ist.
Nun ja das was man mir nicht glaubte VCL ist nicht OpenGL
Und das Handling mit den Fonts in VCL ist eine andere Geschichte als in OpenGL.
Aber gut funktioniert ja jetzt auf diese weise.

Meine Fehler resultierten daraus weil ich zu wenig Kenntnis über die zu Übergebenden Parameter hatte.
Delphi-Quellcode:
    // Display Song Name
     SongNameTmp := BassSoInfo.SongTitle;
     OldTitle := string(BassSoInfo.Songfile);
  
     if assigned(SongNameTmp) then
     begin
       SetLength(Char, length(SongNameTmp));
  
       // Only change if Title different
       if (OldTitle <> CurrentTitle) then
       begin
         //Get max length of String
         fMaxStrLen := tsTextGetWidthA(SongNameTmp);
         if fMaxStrLen >= 635 then
         begin
           // Parse width of Glyph
           for I := 0 to High(Char) do
           begin
             Char[I] := WideChar(SongNameTmp[I]);
             CharLength := tsFontGetCharParameteri(Char[I], TS_CHAR_GLYPHRECT_RIGHT);
             CharLen := CharLen + CharLength;
           end;
           // CharLen = length of all combine Glyph
           if CharLen >= ((CharLen - fMaxStrLen) + 635) then
           begin
             SongName := PAnsiChar(Ansistring(Ansimidstr(string(SongNameTmp), 1, 58) + '...'));
           end;
         end
         else
           SongName := BassSoInfo.SongTitle;
  
         CurrentTitle := OldTitle;
       end;

Ich hatte vergessen die Chars den Aktiven Font zuzuweisen
tsFontAddChars(@SongNameTmp[0]);

die länge des Suffix (...) nicht addiert basierend auf der verwendeten Bibliothek.
CharLen := tsFontGetCharParameteri('.', TS_CHAR_ADVANCE) * 3;

Und hier den falschen Parameter übergeben mit der Annahme das ich die weite über TS_CHAR_GLYPHRECT_RIGHT in Erfahrung bringe. Schien mir am logischsten.
CharLength := tsFontGetCharParameteri(Char[I], TS_CHAR_ADVANCE);

was mich hier gerissen hat weiß ich letztendlich auch nicht.. war wohl mehr oder weniger eine Verzweiflungstat.
if CharLen >= ((CharLen - fMaxStrLen) + 635) then

Ansonsten war die Herangehensweise gar nicht mal so verkehrt.
Vielleicht können andere Leute die mit der TextSuite Arbeiten damit jetzt was anfangen.
Die müssen sich dann nicht mehr damit rumschlagen.

Letztendlich noch ein Satz.
Wäre die exakte Anzahl von Chars bekannt, bei nicht Monotonen Fonts die in den Bereich von 5 > 635 hineinpassen, könnte man sich den ganzen Kram sparen
denn dafür würde eine einzige Zeile reichen.

SongName := PAnsiChar(Ansistring(Ansimidstr(string(SongNameTmp), 1, 'Meine bekannte Anzahl von Chars') + '...'));

gruss

Geändert von EWeiss (19. Jun 2016 um 06:48 Uhr)
  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
 
#7

AW: Textlänge abschneiden

  Alt 19. Jun 2016, 16:39
Tja, diese Lösung von Lossy ist von der Funktionsweise exakt die gleiche, die ich auch gepostet habe. Aber anyway, es gab ja jetzt eine CopyPaste Lösung ohne Mitdenken - und die gab es von mir halt nicht
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
Rollo62

Registriert seit: 15. Mär 2007
4.185 Beiträge
 
Delphi 12 Athens
 
#8

AW: Textlänge abschneiden

  Alt 18. Jun 2016, 18:21
Bin mir nicht sicher, aber ist beim Proportionalfont nicht auch die Reihenfolge der Zeichen wichtig ?

Der Font sollte doch der Typogrrafie entsprechen: z.B. im Buchdruck.

Dann wäre z.B. "o" nach "P" etwas näher rangerückt (so inder der Art).
Also kämen bei "Po" andere Werte als bei "oP", oder so ähnlich.

Könnte das eventuell dein Problem damit sein ?
Dann müsste immer der ein ganzer String analysiert werden und
nur eine charakterweise Addition müsste Unterschiede ergeben.

Das wäre vielleicht die Erklärung wenn es ein Font tut und der Andere nicht.

Das nurmal als Gedankenanregung, bin auch kein Fontspezialist.

Rollo
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 12:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz