Gdiplus: Gdi- und Gdiplus-Kommandos in ein Metafile mischbar?



  • Hallo,

    alle Gdiplus-Kommandos können folgendermaßen in eine Metadatei geschrieben werden:

    myMetafile = new Metafile(L"MyDiskFile.emf", hdc);
    myGraphics = new Graphics(myMetafile);
       // ... Gdiplus-Befehle
    delete myGraphics;
    delete myMetafile;
    

    So sieht man es überall im SDK. Als Beispiel nicht finden kann man etwa:

    myMetafile = new Metafile(hdc, Rect(x0, y0, dx, dy), MetafileFrameUnitGdi, EmfTypeEmfPlusDual, L"Test-Metafile");
    myGraphics = new Graphics(myMetafile);
       // ... Gdiplus-Befehle
    delete myGraphics;
    
    hEnhMetaFile=myMetafile->GetHENHMETAFILE();
       // ... hier mit GetEnhMetaFileBits() einen EnhMetaHeader erstellen und in einen stream oder Datei speichern
    DeleteEnhMetaFile(hEnhMetaFile);
    delete myMetafile;
    

    Soweit, so gut.
    Was aber machen, wenn außer den Gdiplus-Befehlen auch Gdi-Befehle, die sich auf hdc beziehen, ausgegeben werden müssen.
    Prinzipiell sagt Microsoft, dass eine EMF+-Datei sowohl Gdi- als auch Gdiplus-Befehle enthalten kann (durchmischt).
    Ich frage mich aber, wie kann eine solche Datei bzw. Metadatenbereich überhaupt erzeugt werden?

    Meine Tests haben ergeben:

    1. Die auf hdc basierenden Gdi-Befehle werden nicht ins myMetafile-Objekt rübergeschafft, auch dann nicht, wenn hdc mittels
    CreateEnhMetaFile() erzeugt wird (klassischer Weg, um Gdi-Metafile zu erzeugen).

    2. Umgekehrt denken die Gdiplus-Befehle nicht daran, über myGraphics und myMetafile rückwärts in das hdc zu gelangen, um dann z.B. mit
    CloseEnhMetaFile() und GetEnhMetaFileBits zusammen mit den dort erzeugten Gdi-Befehlen weiter verarbeitet zu werden.

    Ich habe keinen Metafile-Konstruktor oder -Methode gefunden, der hier eine Brücke zwischen Gdi und Gdiplus schlägt.

    Hat dazu jemand eine Idee?



  • Hmm, das ist eigentlich eine interessante Frage. Ich meine fast, es geht nicht. Es gibt so einen Dual Modus oder so, da werden in die EMF+ Datei zusätzlich zu den GDI+ Anweisungen noch entsprechende GDI Anweisungen geschrieben, damit man die Datei auch mit Gdi aufmachen kann. Das könnte man vielleicht auch dazu missbrauchen, GDI und GDI+ zu mischen. Dazu müsste man aber evtl. die Datei selber und nicht über entsprechende API aufbauen. Wenn man die Datei selber aufbaut, kann man das Format bestimmt austricksen, allerdings wäre das recht aufwändig.



  • Hallo Mechanics,

    danke für die mentale Beteiligung 🙂

    Nach einigen Tagen muss ich leider sagen, dass ich auch selbst noch keine Lösung gefunden habe.

    Der Grund meines Problems liegt darin, dass ich transparente Texte ausgeben muss, die auch Postscript-basierte Glyphendefinitionen enthalten können (nicht nur TrueType-Konturen). Die Transparenz erfordert also Gdiplus und das Postscript die Gdi, weil Gdiplus absolut keine OpenTypes mit Postscript verarbeiten kann. Deshalb also auch Gdi-Textausgaben. Und da haben wir die Mischung für Metafile-Streams (z.B. für OLE und Zwischenablage notwendig)!
    Allerdings wäre das Problem der fehlenden Transparenz dann noch nicht gelöst.

    Stattdessen gebe ich die Postscript-Glyphen jetzt als Flächen über Gdiplus::DrawPath() aus. Das ClearType wird da natürlich nicht mehr unterstützt, aber damit kann ich leben.



  • Wegen Transparenz gibt es in GDI eine AlphaBlend Funktion. Ich weiß jetzt allerdings nicht, ob man sie auch ins Metafile schreiben kann und ob sie dir weiterhilft.



  • Richtig, der Text müsste dann aber vorher über einen Speicherkontext in eine Bitmap geschrieben werden und diese dann innerhalb der Gdiplus ins Ziel kopiert werden.

    Das hdc-Ziel ist allerdings kompliziert. Es handelt sich um das zoom- und scrollbare Fenster eines CAD-Systems. D.h. die Schrifthöhe kann auch schnell mal 10.000 Pixel hoch werden. Man müsste also die Größe der Zwischenbitmap als Überlapp von dem Textrechteck und dem gerade sichtbaren Clippingbereich des Zielfensters berechnen, um eine zu große Ausdehnung zu verhindern.

    Es funktioniert jetzt aber mit dem GraphicsPath wunderbar.
    Danke.


Anmelden zum Antworten