MeasureString und DrawString - GDI auf die harte Tour



  • Die DirectWrite-Methode IDWriteFactory::CreateTextLayout erlaubt, soweit ich sehe, nur die Anwendung eines einzigen Font innerhalb des Layout (=Zeile?). In einem solchen Layout kann ich alle möglichen Parameter der Schrift verändern (Fett, kursiv, unterstrichen, Größe), aber ich habe noch keine Methode gefunden, mit der ich den Font selbst für einen Teil des Layout ändern kann. Habe ich da etwas übersehen? 😃



  • Hat sich schon erledigt ..... IDWriteTextLayout::SetFontFamilyName 😃

    Es steht ja alles in der Dokumentation ..... man muss es eben nur finden (Nachdem man es genügend intensiv gesucht hat).



  • So, jetzt bin ich ein gutes Stück weiter. Ich habe in den vergangenen Tagen intensiv mit DirectWrite experimentiert (Dank an hustbaer für den Tipp) und weiß jetzt schon, dass alle meine Anforderungen mit dieser Engine erfüllt werden.

    Für alle, die auch an der Anwendung von DirectWrite interessiert sind, hier habe ich einige Links, die mir bei meinen Experimenten erheblich weitergeholfen haben:

    Aber alle diese Quellen drücken sich um das Thema TABulation. Lediglich in der MSDN-Dokumentation wird die Existenz der Funktionen SetIncrementalTab und GetIncrementalTab sehr sparsam zugegeben. Man erfährt leider nicht, wie diese TABs in der Praxis angewendet werden können: So würde ich z.B. sehr gerne (und dringend) wissen, wie man das Text-Alignment für die verschiedenen TAB-Spalten einstellt.
    Weiß jemand, wie das funktioniert; oder kennt jemand eine Quelle, in der dieses offenbar sehr spezielle DirectWrite-Thema näher beleuchtet wird?



  • Hast Du auch einen Link zu dem Petzold-Artikel?



  • PaulB48 schrieb:

    Hast Du auch einen Link zu dem Petzold-Artikel?

    Sorry -- vergessen.

    Hier ist der Link (ich werde ihn auch im Original-Post nacheditieren):
    http://www.charlespetzold.com/blog/2014/01/Character-Formatting-Extensions-with-DirectWrite.html



  • Ich hab' da mal reingesehen, das sind klasse Quellen, die ich auch nutzen werde.



  • Mechanics schrieb:

    Du könntest vielleicht mal versuchen, dir das Buch "Windows Graphics Programming" zu besorgen. Da steht auch einiges zu dem Thema drin. Hab jetzt z.B. noch die Funktion GetCharacterPlacement gefunden, die hatte ich gar nicht mehr in Erinnerung. Bin mir nicht sicher, ob sie dir jezt weiterhilft, könnte aber sein.

    Inzwischen hatte ich mir mal die Zeit genommen, nach käuflicher Fachliteratur zu suchen, denn auch ich bin nicht zu 100% überzeugt, dass die kostenlosen Informationen aus dem WEB immer zielführend sind. Allerdings: Das Feld der Literatur zu Grafik-Programmierung, insbesondere Berechnen und Rendern von Text, ist sehr schwach vertreten. Auch Deinen Buchtipp glaube ich geortet zu haben: http://www.amazon.de/Windows-Graphics-Programming-Hewlett-Packard-Professional/dp/0130869856/ref=sr_1_4?ie=UTF8&qid=1416059685&sr=8-4&keywords=Windows+Graphics+Programming -- ist es das? Dieses Buch ist aus dem Jahr 2000 und damit - programmiertechnisch - sehr alt; der Preis von gut 200€ für ein neues Exemplar (und gebraucht für knapp unter 100€) animiert nicht gerade zum Spontankauf.

    @Mechanics: Würdest Du mir dieses Buch bei dem aktuellen Stand der Diskussion hier immer noch empfehlen?

    Hat sonst noch jemand dieses Buch und kann mir eventuell eine Kaufempfehlung geben?



  • Nein, wie gesagt, das war seinerzeit ein gutes Buch zum Thema GDI Programmierung. Da geht es eben auch nur um GDI und natürlich nicht um DirectWrite. Du musst auch bedenken, dass es zu der Zeit auch im Internet bei weitem nicht so viele Informationen gab, wie jetzt. Ich habs seinerzeit recht günstig gebraucht bekommen.



  • Ist schon wahr: Inzwischen sind die im Internet verfügbaren Informationen sehr viel umfangreicher als noch zu Beginn des Jahrtausends. Der Buchtipp war aber für den Stand der Diskussion schon sehr sinnvoll.

    Aber leider gibt es im Internet über DirectWrite, speziell bei der Verwendung von TABs, noch erheblichen Informationsbedarf. Ich habe sogar den Verdacht, dass Microsoft das Thema noch nicht zu Ende gedacht hat.



  • Ich finde, mittlerweile findet man grundsätzlich zu jedem Thema immer weniger sinnvolles, dafür immer mehr Müll... Wenn ich z.B. eine bestimmte Info zu einem Spiel suche, werd ich kaum noch fündig. Dafür kommen 50 Ergebnisseiten mit immer gleichen Reviews, die mich überhaupt nicht interessieren, wo aber evtl. die Wörter vorkommen, die ich eingegeben habe.

    Dein Problem ist eher, dass sowas kaum jemand nutzt. Gibt vielleicht paar Leute, die mal damit rumgespielt haben. Nicht genug, um Forenbeiträge und Blogs zu dem Thema zu schreiben. Deswegen hab ich in dem Buch damals auch viele Infos und Beispiele gefunden, die ich seinerzeit im Internet nicht gefunden hatte.

    Bist du sicher, dass du die Funktionen richtig geschrieben hast? Wenn ich nach GetIncrementalTab suche, finde ich gar nichts. Nicht mal diesen Thread hier 😉



  • Ist wahr, das war mein nachlässiger Schreibfehler - entschuldige.

    Die Funktion heißt GetIncrementalTabStop bzw. SetIncrementalTabStop. Wenn man das als Suchwort eingibt, bekommt man doch etliche Hits, aber die verweisen alle aud dieselbe (dürftige) Beschreibung.



  • Ich hatte eine andere Idee, ich wollte mal im Chromium Code danach suchen. Hab die Funktion aber nicht gefunden. Die ist aber wohl auch eher für Textverarbeitung und nicht für Browser interessant.
    Aber grundsätzlich findet man die mit Codesuchmaschinen schon, z.B. openhub.net. Ich frag mich aber, inwiefern die Funktion überhaupt nützlich ist. So wie ich die Doku interpretiere macht die nicht das, was du willst. Aber was willst du eigentlich genau erreichen?



  • Ich möchte Tab-Stopps in meinen Text einbauen können, ganz so, wie ich es auch bei einem normalen Texteditor kann. Nur muss ich die Formatierung nicht interaktiv eingeben, sie wird in den auszugebenden Text eingefügt.

    Ich weiß, dass es solche Formatierungsschnittstellen bereits gibt. Die mir am meisten geläufige ist RTF (Rich Text), aber die Formatierung ist für meine Zwecke zu komplex (in anderen Applikationen hatte ich sie schon erfolgreich eingesetzt).

    Ja, so sehe ich es auch: Die in DirectWrite vorgesehenen TabStopps scheinen wirklich nicht den vorgesehenen Zweck zu erfüllen, da ich dort nur einen (oder mehrere aufeinanderfolgende TabStopps???) setzen kann, und die Orientierung der Tab-Spalten (links, mittig, rechts) kann ich offensichtlich nicht setzen. Aber ich kann kaum glauben, dass Microsoft dieses Feature in der ansonsten so beeindruckenden und mächtigen Schnittstelle "vergessen" hat. Ich finde eben nur (noch) nicht die richtige Funktion.

    Das, was ich da angegangen bin, entspricht wohl eher einer Textverarbeitung. Vom Chromium Code hatte ich bisher noch nichts gehört, werde mich da aber mal aufschlauen.



  • Also, du willst Tabs wie in einer Textverarbeitung, nicht einem Texteditor? Also, sowas wie Ausrichtung, Position, Füllzeichen?
    Kann schon sein, dass es nicht geht... Ich find da grad ebenfalls auch nichts.



  • Ja, genau das ist mein Ziel. Die Füllzeichen sind mir allerdings weniger wichtig.

    Mit GDI hatte ich das alles schon einmal vollständig implementiert, nur eben die Druckerausgabe ergab - aus inzwischen bekanntem Grunde - einen anderen Umbruch. Das hatte mich ziemlich umgetrieben, und ich hatte meine Versuche mit GDI+ gestartet, mit der ich auch nicht die erwünschte Übereinstimmung zwischen Bildschirm und Drucker erzielen konnte.

    Tja, und jetzt DirectWrite.....
    Nachdem ich mir die Schnittstelle angesehen hatte, war ich von der Vollständigkeit und Klarheit der Implementation begeistert. Leider aber scheinen die TABs zu fehlen. Das ist sehr schade, denn ansonsten könnte ich meinen Code für den Textumbruch erheblich (um weit mehr als die Hälfte) reduzieren.

    Im Moment sehe ich für eine "ordentliche" Implementierung von TABs nur die Möglichkeit, die Textabstände zwischen den Tab-Blöcken in Abhängigkeit von den mit DirectWrite gemessenen Textlängen durch entsprechend breite Zwischenräume zu implementieren. Da bietet DirectWrite zum Glück eine Methode an; der Code wird dadurch allerdings wieder stark vergrößert.



  • Ich glaube ich hab' schon geschrieben dass ich davon ausgehe dass Textverarbeitungen das ganze Layouting selbst machen, oder? 😉



  • hustbaer schrieb:

    Ich glaube ich hab' schon geschrieben dass ich davon ausgehe dass Textverarbeitungen das ganze Layouting selbst machen, oder? 😉

    So, jetzt haben wir aber DirectWrite, und seit Deiner Bemerkung ist die Diskussion schon weiter fortgeschritten.
    Schon sehr gut möglich, wahrscheinlich sogar vollkommen richtig, dass die Standard-Programme für Textverarbeitung das Layouting selber machen. Aber DirectWrite benutzen die sicher nicht, und deshalb müssen sie da schon selbst ran. 😃

    DirectWrite enthält praktisch alle wichtigen Elemente einer Textlayout-Engine, nur eben die Implementierung von TABs, die über IncrementalTabStops hinausgeht (oder eine Beschreibung, wie das doch funktioniert), habe ich nicht finden können. Aber das habe ich ja schon geschrieben 😃



  • WishfulThinking schrieb:

    DirectWrite enthält praktisch alle wichtigen Elemente einer Textlayout-Engine

    Glaube ich nicht. Eine Textverarbeitung kann ja nicht nur Fließtext. Und die anderen Features führen eben dazu, dass man alles komplett selber layouten muss. Denk mal an Tabellen, Fußnoten, Text der Bilder umfließt, Spalten usw. Das kann DirectWrite nicht und es würde auch keinen Sinn machen, es da zu implementieren. Wenn man sowas aber unterstützen will, muss man sich gleich um alles kümmern.



  • So weit gehen meine Ansprüche zum Glück nicht.

    Dann werde ich mich jetzt daran machen, meine Layout-Engine auf der Basis von DirectWrite neu zu implementieren:

    • Schriftwechsel (Schriftfamilie, Größe, Stil, Textfarbe und bei DirectWrite sogar mit Stretch)
    • Zeilenabstand
    • Sonderzeichen, die nicht zu einer Standard-Schrift gehören
    • Zeilenumbruch mit optionalen Silbentrennungen
    • TABs (mit Orientierung links, mitte, rechts)
    • Horizontale Textabschnitt-Orientierung (links, rechts, mitte, verteilt), kann man wegen der fehlenden TAB implementierung nicht mit der DirectWrite-Funktion SetTextAlignment machen
    • Vertikale Textabschnitt-Orientierung (oben, mitte, unten, verteilt)

    Mit dieser Aufgabe werde ich mich jetzt zurückziehen und bedanke mich bei allen, die bei dieser Diskussion mitgemacht und auch den einen oder anderen Denkanstoß gegeben haben.


Anmelden zum Antworten