Delphi-PRAXiS
Seite 2 von 2     12   

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)

EWeiss 18. Jun 2016 18:27

AW: Textlänge abschneiden
 
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

Delphi-Quellcode:
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

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


gruss

nahpets 18. Jun 2016 18:52

AW: Textlänge abschneiden
 
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;

EWeiss 18. Jun 2016 18:57

AW: Textlänge abschneiden
 
Dank dir werde es mal testen.

gruss

EWeiss 18. Jun 2016 21:13

AW: Textlänge abschneiden
 
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
Delphi-Quellcode:
tsFontAddChars(@SongNameTmp[0]);


die länge des Suffix (...) nicht addiert basierend auf der verwendeten Bibliothek.
Delphi-Quellcode:
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.
Delphi-Quellcode:
CharLength := tsFontGetCharParameteri(Char[I], TS_CHAR_ADVANCE);


was mich hier gerissen hat weiß ich letztendlich auch nicht.. war wohl mehr oder weniger eine Verzweiflungstat.
Delphi-Quellcode:
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.

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


gruss

Sir Rufo 19. Jun 2016 16:39

AW: Textlänge abschneiden
 
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 :stupid:

EWeiss 19. Jun 2016 19:23

AW: Textlänge abschneiden
 
Zitat:

Zitat von Sir Rufo (Beitrag 1340555)
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 :stupid:

Ja nur deine Funktioniert nicht. :stupid:

Weil du einfach nicht verstehst das der Font in OpenGL von der Breite her niemals der gleiche wie unter VCL ist.
Hier wird auch nicht in VCL sondern unter OpenGL mit einer extra dafür ausgerichteten Bibliothek gezeichnet.
Und nein wenn du weiter runter gehst ca. auf Seite 2 wirst du sehen bzw. erkennen das bis auf die Parameter
der Code von mir vorher schon geschrieben war.

Du hättest sofort auf Anhieb erkannt das ich TS_CHAR_ADVANCE anstelle von TS_CHAR_GLYPHRECT_RIGHT hätte verwenden müssen?
Von der Logik her war dies für mich der richtige weg TS_CHAR_GLYPHRECT_RIGHT.

Und nochmal vergiss es einfach zu versuchen OpenGL mit VCL zu kombinieren.
Abhängig natürlich von der aktuellen Sachlage.

Zu deiner Unterstellung:
Vergleich einfach mal die Zeiten oder gehe mal auf DelphiGL dann siehst du wer was hier Copy/Paste hat.
Ich zumindest nicht.

Mein Post:
17. Jun 2016, 21:00 Hier und bei DelphiGL wer hat jetzt Copy paste?
Lossys Post:
18. Jun 2016, 18:07

Das Problem war nur ich habe mich von dir breit schlagen lassen es mit der VCL Methode zu versuchen. :stupid:
Zitat:

Hört sich ja fast so an, als ob OpenGL = Quanten-Physik ist.
Ja wenn man versucht VCL (Font Angelegenheiten) in GL umzusetzen die eine extra Bibliothek verwendet um die Fonts zu zeichnen.
Ich habe versucht dir das mehrmals Klar zu machen...
Aber nein manche Leute wollen ihren Standpunkt mit allen Mitteln durchsetzen.
Kein Ahnung warum du jetzt sickig bist. Dein Stolz verletzt?

Versteh mich nicht falsch ich habe mich über deine Hilfe gefreut, aber jetzt mit solchen Unterstellungen zu kommen,
nur weil ich deinen nicht funktionierenden Code nicht verwende, ist unterste Schublade.

Und ja deinen ganzen code kann ich mit einer einzelnen Zeile ersetzen und komme auf das gleiche Ergebnis.

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

Das das so (zeichne mal einfach so den Text) nicht geht is hoffentlich jedem klar.
Klar geht das und ist auch der Grund warum es mit VCL nicht funktioniert.
Denn die TextSuite tut nichts anderes.

EDIT:
Ich habe sogar noch mit meinem Code selber verglichen was ich vergessen bzw. wo meine Fehler waren.
Ich verstehe deine Probleme einfach nicht.

Habe jetzt allen hier bewiesen das deine Unterstellung Nonsens ist, somit ist es gut für mich.
Jetzt können wir wieder Freunde sein.


gruss

Sir Rufo 19. Jun 2016 20:54

AW: Textlänge abschneiden
 
Da mein Code einfach nur Integer Werte zusammenzählt und anhand der Aufsummierungen derselbigen Entscheidungen trifft, müssen wohl die von OpenGL zurückgelieferten Integer Werte total anders von der Bedeutung sein. So OpenGL-Spezial-Integer Werte.

Schon krass dieses OpenGL - sowas kann ich natürlich nicht berücksichtigen.

Vielleicht kann mir das ja der Kryptochef erklären, werde den mal anschreiben :mrgreen:

EWeiss 19. Jun 2016 20:57

AW: Textlänge abschneiden
 
Zitat:

Zitat von Sir Rufo (Beitrag 1340576)
Da mein Code einfach nur Integer Werte zusammenzählt und anhand der Aufsummierungen derselbigen Entscheidungen trifft, müssen wohl die von OpenGL zurückgelieferten Integer Werte total anders von der Bedeutung sein. So OpenGL-Spezial-Integer Werte.

Schon krass dieses OpenGL - sowas kann ich natürlich nicht berücksichtigen.

Vielleicht kann mir das ja der Kryptochef erklären, werde den mal anschreiben :mrgreen:

Mir ging es um die Unterstellung die du hier gemacht hast..
Dazu habe ich alles gesagt.

Diese Antwort... nun ja! Ich verkneife mir darauf zu Antworten.
Äußere dich doch mal zu den von dir gemachten Unterstellungen das hätte mir mehr gebracht.

gruss

Fritzew 19. Jun 2016 21:33

AW: Textlänge abschneiden
 
Also ich verstehe das nicht.

Lösung Sir Rufo:
Delphi-Quellcode:
type
  TCharMeasureWidthDelegate = function( const C: Char ): Integer of object;

function ShortenText( const Text: string; const MaxLength: Integer; const CharMeasurement: TCharMeasureWidthDelegate; const ShortenSuffix: string = '...' ): string;
snip...

So jetzt eine function

Delphi-Quellcode:
function TmyView.CalculateCharWith( const C: Char ): Integer;
begin
  Result := tsFontGetCharParameteri(C, TS_CHAR_ADVANCE);
end;
und das ganze Aufrufen mit

Delphi-Quellcode:
lDrawText := ShortenText( Edit1.Text, PaintBox1.ClientWidth, myView.CalculateCharWith );
fertig.

Also in meinen Augen ist die Lösung von Sir Rufo super weil komplett unabhängig
und vor allem auch testbar.

EWeiss 19. Jun 2016 21:36

AW: Textlänge abschneiden
 
Zitat:

Also in meinen Augen ist die Lösung von Sir Rufo super weil komplett unabhängig
Nö weil nicht OpenGL konform und mit meiner Bibliothek die ich verwende um die Glyphen zu zeichnen nicht vereinbar ist.
Schön und gut für VCL das war's dann.

Zudem warum soll ich 5 Seiten Quelltext verwenden wenn ich das gleiche mit 10 Zeilen erledigt habe.
Außerdem versuche ich zu vermeiden mein Programm mit Copy/Paste zu verwirklichen und nein brauche auch keine fertigen Lösungen
zumal diese hier eh nicht funktioniert.

gruss

Fritzew 19. Jun 2016 21:49

AW: Textlänge abschneiden
 
Wenn Du mir zeigst wo die Lösung was mit Opengl oder Vcl oder GDI oder was immer zu tun hat dann glaube ich Dir sogar

Ansonsten muss ich jetzt ehrlich sagen, Du hast Dein eigenes Problem nicht verstanden,
weil die Lösung funktioniert
aber lassen wir es Du hast recht.....

EWeiss 19. Jun 2016 21:52

AW: Textlänge abschneiden
 
Zitat:

aber lassen wir es Du hast recht.....
Richtig schließlich sehe ich das Ergebnis das ist Aussagekräftig genug.

Zitat:

Du hast Dein eigenes Problem nicht verstanden, weil die Lösung funktioniert
Du erkennst den Unterschied nicht ob man nun einen Font selbst zeichnet was die TextSuite tut
oder ob man den VCL Font verwendet.

Zitat:

weil die Lösung funktioniert
Nochmal.. Nein
Dazu müsste ich den Quelltext erst anpassen damit er funktioniert.
Dazu habe ich einfach keinen Bock. So einfach ist das.
Jetzt schon mal gar nicht mehr nach den Unterstellungen.

gruss

Fritzew 19. Jun 2016 22:00

AW: Textlänge abschneiden
 
Wer es nicht versteht lass ich mal im Raum stehen
aber wo ist die Antwort darauf was die Lösung von Sir Ruf mit der Bibliothek zu tun hat? Das schöne daran ist ja gerade das
sie unabhängig ist.
Auch Gruss

EWeiss 19. Jun 2016 22:07

AW: Textlänge abschneiden
 
Zitat:

Zitat von Fritzew (Beitrag 1340584)
Wer es nicht versteht lass ich mal im Raum stehen
aber wo ist die Antwort darauf was die Lösung von Sir Ruf mit der Bibliothek zu tun hat? Das schöne daran ist ja gerade das
sie unabhängig ist.
Auch Gruss

LOL was nutzt das wenn sie nicht funktioniert.
Also so unabhängig dann doch nicht.

Addiere ich in der TextSuite zu meinen Glyphen einen Schatten dann noch einen Rahmen und so weiter wie kommt dann den seine Lösung an die Exakte
Weite des gesamten Text wenn ich nun noch den Abstand der Glyphen untereinander verändere? Gar nicht.
Kann nichts dafür das ihr das nicht kapiert.

Für mich ist das Thema Abgeschlossen da es keine bessere und kürzere Lösung für mich gibt.
Ihr könnt ja weiter debattieren.

gruss

Fritzew 19. Jun 2016 22:18

AW: Textlänge abschneiden
 
Also ganz Ehrlich wenn das so ist ok,
ich sage trotzdem das die function gut ist, weil genau das mit Ihr geht,
übergebe der eine function die all das berücksichtigt was Du willst und es geht,
Du kapiert es nicht
die Function kann ich aufrufen mit


Delphi-Quellcode:
ShortenText( 'BlaBla', 300, berechneAllesmitSchattenundGlibber)
oder mit

Delphi-Quellcode:
ShortenText( 'BlaBla', 300, berechneAllesmitAbstandvomBHmeinerFrau)
es funktioniert

EWeiss 19. Jun 2016 22:23

AW: Textlänge abschneiden
 
Zitat:

Du kapiert es nicht die Function kann ich aufrufen mit.
JA?

Nur zur Veranschaulichung.
Und was machst du wenn ich den Text in einem Block zeichne Pixel für Pixel.
Dann gibt es keine Länge vom String mehr welche seine Funktion ermitteln könnte.
TextSuite hingegen kennt sie schon.

So ist es auch mit den anderen Dingen Abstand zwischen den Glyphen und so weiter...
Ohne seine Funktion speziell für die Bedürfnisse, zusammenspiel mit der Bibliothek anzupassen.. Vergess es einfach.

Du machst dich langsam lächerlich.

Arbeite erst mal mit der TextSuite an einem realen Projekt dann reden wir weiter.

Delphi-Quellcode:
ShortenText( 'BlaBla', 300, woissedennnurdiestrumpflängemeinerOma)

Ich habe nun genug mit dir gespielt lass es gut sein.

Zitat:

Also ganz Ehrlich wenn das so ist ok,
Du widersprichst dir doch selbst.

Zum Schluss noch ein Zitat von Lossy selbst.
Zitat:

Hier solltest du grundsätzlich die TextBreite etc. nur mit der Bibliothek erfragen mit der du die Texte auch zeichnest. Alles andere kann nicht funktionieren. Bzw. Birgt einfach zu viele Risiken.
Dem stimme ich voll zu.


gruss

Neutral General 19. Jun 2016 23:45

AW: Textlänge abschneiden
 
Sir Rufos Funktion funktioniert grundlegend mit allem. Da gibts gar keine Diskussion - das ist durch das Delegate grundlegend gegeben.

Ob du nun eine entsprechende Delegate-Funktion für OpenGL und die TextSuite schreiben kannst bzw. willst ist vollkommen unerheblich. Möglich ist es auf jeden Fall - egal wer oder was auf welche Art den Text in welcher Font auch immer zeichnet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:40 Uhr.
Seite 2 von 2     12   

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