TextOut mit erweitertem WordWrap?



  • Ich habe gerade eine Liste vor mir liegen, mit technischen Bezeichnungen, welche manchmal wirklich lang sein können. Ich möchte demnächst das mittels Canvas.TextOut in einer Tabelle darstellen und wollte mich schon mal erkundigen, ob jemand eventuell eine Funktion kennt die folgendes Problem löst:

    Ich habe zum Beispiel nur 200px in der Breite Platz, ein Wort ist aber extrem lang, daher geht nicht nur ein Leerzeichen oder Komma/Punkt als Umbruch, sondern auch das Wort muss gegebenenfalls einfach umgebrochen werden.

    Vorgabe: "Laaaaaaaaaaaaaaaaaaaaaaaaaanger sinnfreier Satz"
    Ziel:
    "Laaaaaaaaaaaaaaaaaaaaaaa
    aaanger sinnfreier Satz"

    Wenn ich es mir einfach machen will, nehme ich einen Font wo jeder Buchstabe die gleiche Breite hat und teile einfach den String nach einer festen Zeichenanzahl. Aktuell würde ich es aber gern mit normalen Text machen wollen und mich über Hilfe freuen.



  • Hallo

    Mir ist keine extra Funktion zur Worttrennung bekannt. Immerhin kannst du ja Worte nicht beliebig auftrennen, wenn es grammatikalisch korrekt bleiben soll.
    Du kannst aber die Funktion TCanvas::TextWidth benutzen, um selber die benötigte Breite eines Strings beim Schreiben mit dem aktuellen Font zu ermitteln. Damit kannst du anstatt blind Zeile für Zeile eben Wort für Wort prüfen.

    bis bald
    akari



  • Guck dir mal die Win32 API Funktion DrawText an, da kannst du über die Flags Zeilenumbrüche etc. steuern.



  • Hallo

    DrawText trennt nicht Wörter, die selbst schon zu lang sind. Das Problem der extrem langen Fachwörter von Stevo ist damit allein noch nicht gelöst.

    bis bald
    akari



  • akari schrieb:

    Hallo

    DrawText trennt nicht Wörter, die selbst schon zu lang sind. Das Problem der extrem langen Fachwörter von Stevo ist damit allein noch nicht gelöst.

    bis bald
    akari

    Jau, stimmt.
    Wieviele Fachwörter hast du denn, für die das Problem auftritt? Vielleicht kannst du ja statisch bestimmen, wie ein Wort getrennt wird, in dem du für jedes Fachwort eine statische Silbenzerlegung hinterlegst.

    Primitiver Ansatz:

    std::map<std::string, std::string> m;
    
    m["Donaudampfschifffahrtsgesellschaftskapitän"] = "Donau.dampf.schiff.fahrts.ge.sell.schafts.ka.pi.tän";
    

    Als erstes musst du deinen auszugebenden Satz in einzelne Worte zerlegen und prüfen, ob das aktuelle Wort noch in die Zeile passt. Wenn das der Fall ist machst du mit dem nächsten Wort weiter. Solltest du auf ein Wort treffen, das nicht mehr in die Zeile passt guckst du in deiner map nach, ob es eine Zerlegungsvorschrift für das Wort gibt. Wenn es keine Vorschrift gibt fängst du eine neue Zeile an, ansonsten versuchst du möglichst viele Silben anzuhängen und fängst für die restlichen Silben in eine neue Zeile an. Das machst du mit allen Worten deiner Ausgabe.



  • Hi,

    if würde jeweils gucken, ob der Sting insgesamt zu lang ist. Wenn ja, dann binär suchen wo getrennt werden muss. Und dann die Teilstrings getrennt ausgeben.
    Am besten, Du löeitest von label oder ähnlichem eine neue Komponente ab, die das entsprechend kann.

    Gruß Mümmel


Log in to reply