Cairo-Wrapper-Preview

07/10/2009 - 12:43 von Schmidt | Report spam
Hallo zusammen,

die vor einiger Zeit schonmal angekündigten neuen Widget-
Klassen "gehen voran" - leider nicht so schnell wie gedacht -
aber so nach und nach wird die Codebasis "immer runder"...

Zumindest der Cairo-Wrapper ist jetzt erstmal so weit,
dass man ihn als "nahezu vollstàndig und vorzeigbar"
betiteln kann - hier also ein entsprechendes Preview-
Release, gedacht zum Herumspielen und zum Einarbeiten
vor dem spàteren Offenlegen aller RichClient-binaries und
der neuen Widgets.

Download über: www.thecommon.net/3.html
Den RichClient-Toolset "zip-content" einfach in einen Folder
(z.B. C:\dhRichClient3\...) entpacken und mittels enthaltenem
register.bat (oder auch hàndisch) registrieren.

Die CairoWrapper-Klassen verhalten sich absolut stabil,
in meinen Tests treten keine Memory-oder Handle-Leaks
auf - die Methodenaufrufe (Signaturen) sollten auch keine
größeren Änderungen mehr erfahren - dennoch wird
die Binàrkompatibilitàt von dhCairo.dll die nàchsten Wochen/
Monate (in jedem neuen Release) wohl noch ein paar mal
gebrochen werden.
Wenn nicht wegen Änderungen an den Signaturen der
Cairo-Klassen (weniger wahrscheinlich), dann mit höherer
Wahrscheinlichkeit aufgrund von Änderungen an der
ebenfalls im dhCairo.dll-Binary enthaltenen Widget-
Engine (einer Art Windowmanager, der ohne hWnds
oder hDCs auskommt, das Cairo-Rendering benutzt
und ein àhnliches Entwickeln "im eigenen Widget-Ctl"
erlaubt wie man das von einem VB-Usercontrol-Modul
her gewohnt ist).

Auch die enthaltenen WidgetEngine-Klassen sind also
schon benutzbar (kleinere Beispiele werd ich noch posten) -
aber alleine die reiferen Cairo-Klassen bieten wahrscheinlich
erstmal genügend "Brot für eigene Drawing-Experimente".

Cairo ist eine plattformunabhàngige C-Bibliothek für
Vektorgrafik - kompiliert als StdCall-Dll und im
toolset-paket enthalten als 'cairo2_engine.dll'.
Die Wrapper-Klassen bilden jeweils einen "cairo-Typ" ab
(Surfaces, Contexts, Patterns, Matrixes, Fonts usw.) und
passen in ihren Class_Terminates auf, dass die jeweiligen Cairo-
Handles wieder korrekt freigegeben werden - ansonsten
delegieren die Klassen-Methoden u. -Properties mehr oder
weniger direkt an die von der engine-Dll exportierten Calls.
Der Wrapper bietet mit der Kapselung also Intellisense sowie
automatisches "Freeing" bzw. Cleanup, man spart Codezeilen
gegenüber "pure C" - und ist sicher vor Memory- und Handle-
leaks.

Wer sich schonmal mit GDI+ bechàftigt hat, dem wird der
Einstieg in Cairos Vektorgrafik-Konzept leichter fallen -
Erfahrungen mit dem guten alten GDI oder den VBClassic-
Drawing-Methoden sind "auch OK", aber im Detail unterscheidet
sich das Generieren von "Cairo-Render-Output" dann doch -
z.B. beim für Gradienten verwendeten "Pattern-Konzept" -
oder dass im Prinzip mit jedem Line-, Rectangle- oder Ellipse-
Aufruf erstmal nur ein 'Path' definiert (eröffnet) wird, der
dann entweder "auf dem Pfad" (entlang der "gedachten Linie")
mittels .Stroke - oder innerhalb des Pfads mittels .Fill seine
"Colorierung" erhàlt).

Cairo-Rendering kann gegen verschiedene Surface-Typen
erfolgen, der "Brot und Butter"-Typ hierbei natürlich die Pixel-
basierte "2D-Flàche" - ein weiterer wichtiger Cairo-Surface-
Typ dürfte die PDF-Oberflàche sein.

Cairo arbeitet so, dass man von einem Surface-Typ jederzeit
einen "Drawing-Context" (per Srf.CreateContext) ableiten kann,
welcher dann die verschiedenen Drawing-Methoden bereitstellt.
Das wird im Prinzip so àhnlich ja auch im GDI gehandhabt -
nur dass hier die "Pixel-Surfaces" eben als Device-Independent-
Bitmaps (DIB) oder als Device-Dependent-Bitmaps (DDB) erzeugt
werden bzw. vorliegen - und dann in einen GDI-Context (hDC)
"selektiert werden", um auf den Pixelflàchen "malen" zu können.

Was nett ist bei Cairos Surface-Konzept ist, dass man die
genau gleichen Zeichenbefehle (denselben VB-Code letztlich)
gegen unterschiedliche Surface-Typen anwenden kann.
Das bedeutet, dass man z.B. dieselbe Drawing-Routine für
eine Pixel-Surface basierte Print-Preview-Implementierung
(Rendering gegen den "Screen") genauso auch gegen eine
Cairo-PDF-Surface anwenden kann - das erlaubt dann
eine wirklich "transparent arbeitende" PDF-Generierung,
ohne die sonst üblichen "Umwege" über PDF-Printer-Driver
oder àhnliches.

Hier mal eine erste Demo, welche genau dieses Szenario
abbildet: www.datenhaus.de/Downloads/CairoDemo.zip

Woran ich in den letzten Wochen gearbeitet habe - und was
in obiger Demo ebenfalls enthalten ist, ist der Wrapper-Support
in Bezug auf Image-, Icon- und Resource-Loading.

Der Wrapper làdt die üblichen VB-bekannten Image-Typen
(*.jpg, *.gif, *.bmp) und nun dank Cairo auch das *.png-format.
Darüber hinaus versteht und làdt er sàmtliche Icon-Formate -
egal ob als ResourceIcons or FileIcons (z.B. das neue Vista-
Icon-Format, welches PNG-content enthalten kann, wird
ebenso unterstützt, wie die XP-Icon-Formate mit Alphachannel).

Der CairoWrapper stellt für diese Zwecke auch eine App-globale
ImageList bereit, welche beim Start der Applikation befüllt werden
kann. Hier lassen sich also die verschiedenen Bild-Resourcen,
die eine Anwendung so benötigt, "einmalig abheften".
Hierbei wird z.B. auch das direkte Adden von Resource-Icons aus
System-Dlls unterstützt, z.B. aus "explorer.exe" oder "shell32.dll"
man benötigt nur die korrekte IconID, um solch einen Ladevorgang
mit einer Zeile Code abzuwickeln.
Die IconIDs der shell32.dll werden (zusammen mit den entspr.
Images) z.B. hier gelistet:
http://www.glennslayden.com/shell32_icons.htm

Alle Lese- und Schreiboperationen der verschiedenen Image-
erfolgen (ohne das Filesystem zu benutzen).

Die unterstützten FileTypen für die Leserichtung sind ja weiter
oben schonmal erwàhnt worden - in Schreibrichtung unterstützt
Cairo das emittieren von Pixel-Surface-Content als Png- und
das ebenfalls schon erwàhnte PDF-Format über einen eigenen
Surface-Typ.
Wie gesagt, ist auch hier der Output entweder in einem File
erzeugbar, oder direkt als ByteArray.

Die Stretch- und Scaling-Qualitàten von Cairo (down-
oder upstretching) für z.B. verschiedene Icon-Größen
sind ziemlich gut, der Alphachannel wird entsprechend
berücksichtigt und "mitgestretcht".
Z.B. làsst sich die Qualitàt eines 32x32Icons, gerendert
in "Original-Größe" kaum von der desselben Icons,
diesmal geladen als 48x48 großes Original, aber eben-
falls gerendert als 32x32-Output - unterscheiden.

Die obige Demo bildet genau solche Szenarien ab (Image-
und Icon-Loading aus verschiedenen Quellen - Rendering
in versch. Größen, sowie das Erzeugen von Png-Output
und PDF-Output.

Werd sehen, dass ich weitere Demos "nachschiebe", die sich
mehr auf die Vektor-Grafik konzentrieren (antialiased Rendering
von Linien, Winkeln, Bezier-Kurven usw.) - aber für einen
ersten Einstieg in die Wrapper-Klassen reicht das Gezeigte
wahrscheinlich erstmal hin, zumal der wohl interessanteste
Aspekt von Cairo (auch gegenüber GDI+), das "transparent"
arbeitende (bezogen auf den Drawing-Code) Erzeugen von
PDF-Output schonmal als Minimal-Beispiel mit enthalten ist.

Bitte einfach fragen, wenn irgendetwas unklar sein sollte.

Olaf
 

Lesen sie die antworten

#1 Sascha Trowitzsch
08/10/2009 - 00:47 | Warnen spam
Hi Olaf,

Mann, mann, mann! Das ist ja wieder irre! Es haut mich um!
Ich hab's jetzt gerade mal ne halbe Stunde getestet: sieht super durchdacht
aus.
Ich schmeiß meinen ganzen GDI+-Code weg...
Mir schwirrt schon der Kopf vor Einsatzmöglichkeiten.
PDF und SVG sind Killer-Features!

Aber darf man noch Anregungen einbringen?
Ich bin ein Fan von GDI+-Splines. Könnte man noch so eine Methode in
cCairoContext einbauen? (Koordinaten-Array, Tension-Parameter)
Und geil wàre natürlich auch ein SVG-Parser für den Import. ;-) Müsste ja
nicht die ganze Referenz umfassen, sondern nur die Sachen, die die
Context-Klasse unterstützt.
Ein EMF-Import wàre auch nicht schlecht. (Wobei ich mir das u.U. auch in
Form eines externen Konverters selbst zutraute.)

Thanx alot!!!
(Nun werde ich die nàchsten Tage wieder nicht richtig zum Arbeiten kommen...
;-) )

Gruß, Sascha

Schmidt wrote:
Hallo zusammen,

die vor einiger Zeit schonmal angekündigten neuen Widget-
Klassen "gehen voran" - leider nicht so schnell wie gedacht -
aber so nach und nach wird die Codebasis "immer runder"...

Zumindest der Cairo-Wrapper ist jetzt erstmal so weit,
dass man ihn als "nahezu vollstàndig und vorzeigbar"
betiteln kann - hier also ein entsprechendes Preview-
Release, gedacht zum Herumspielen und zum Einarbeiten
vor dem spàteren Offenlegen aller RichClient-binaries und
der neuen Widgets.

Download über: www.thecommon.net/3.html
Den RichClient-Toolset "zip-content" einfach in einen Folder
(z.B. C:\dhRichClient3\...) entpacken und mittels enthaltenem
register.bat (oder auch hàndisch) registrieren.

Die CairoWrapper-Klassen verhalten sich absolut stabil,
in meinen Tests treten keine Memory-oder Handle-Leaks
auf - die Methodenaufrufe (Signaturen) sollten auch keine
größeren Änderungen mehr erfahren - dennoch wird
die Binàrkompatibilitàt von dhCairo.dll die nàchsten Wochen/
Monate (in jedem neuen Release) wohl noch ein paar mal
gebrochen werden.
Wenn nicht wegen Änderungen an den Signaturen der
Cairo-Klassen (weniger wahrscheinlich), dann mit höherer
Wahrscheinlichkeit aufgrund von Änderungen an der
ebenfalls im dhCairo.dll-Binary enthaltenen Widget-
Engine (einer Art Windowmanager, der ohne hWnds
oder hDCs auskommt, das Cairo-Rendering benutzt
und ein àhnliches Entwickeln "im eigenen Widget-Ctl"
erlaubt wie man das von einem VB-Usercontrol-Modul
her gewohnt ist).

Auch die enthaltenen WidgetEngine-Klassen sind also
schon benutzbar (kleinere Beispiele werd ich noch posten) -
aber alleine die reiferen Cairo-Klassen bieten wahrscheinlich
erstmal genügend "Brot für eigene Drawing-Experimente".

Cairo ist eine plattformunabhàngige C-Bibliothek für
Vektorgrafik - kompiliert als StdCall-Dll und im
toolset-paket enthalten als 'cairo2_engine.dll'.
Die Wrapper-Klassen bilden jeweils einen "cairo-Typ" ab
(Surfaces, Contexts, Patterns, Matrixes, Fonts usw.) und
passen in ihren Class_Terminates auf, dass die jeweiligen Cairo-
Handles wieder korrekt freigegeben werden - ansonsten
delegieren die Klassen-Methoden u. -Properties mehr oder
weniger direkt an die von der engine-Dll exportierten Calls.
Der Wrapper bietet mit der Kapselung also Intellisense sowie
automatisches "Freeing" bzw. Cleanup, man spart Codezeilen
gegenüber "pure C" - und ist sicher vor Memory- und Handle-
leaks.

Wer sich schonmal mit GDI+ bechàftigt hat, dem wird der
Einstieg in Cairos Vektorgrafik-Konzept leichter fallen -
Erfahrungen mit dem guten alten GDI oder den VBClassic-
Drawing-Methoden sind "auch OK", aber im Detail unterscheidet
sich das Generieren von "Cairo-Render-Output" dann doch -
z.B. beim für Gradienten verwendeten "Pattern-Konzept" -
oder dass im Prinzip mit jedem Line-, Rectangle- oder Ellipse-
Aufruf erstmal nur ein 'Path' definiert (eröffnet) wird, der
dann entweder "auf dem Pfad" (entlang der "gedachten Linie")
mittels .Stroke - oder innerhalb des Pfads mittels .Fill seine
"Colorierung" erhàlt).

Cairo-Rendering kann gegen verschiedene Surface-Typen
erfolgen, der "Brot und Butter"-Typ hierbei natürlich die Pixel-
basierte "2D-Flàche" - ein weiterer wichtiger Cairo-Surface-
Typ dürfte die PDF-Oberflàche sein.

Cairo arbeitet so, dass man von einem Surface-Typ jederzeit
einen "Drawing-Context" (per Srf.CreateContext) ableiten kann,
welcher dann die verschiedenen Drawing-Methoden bereitstellt.
Das wird im Prinzip so àhnlich ja auch im GDI gehandhabt -
nur dass hier die "Pixel-Surfaces" eben als Device-Independent-
Bitmaps (DIB) oder als Device-Dependent-Bitmaps (DDB) erzeugt
werden bzw. vorliegen - und dann in einen GDI-Context (hDC)
"selektiert werden", um auf den Pixelflàchen "malen" zu können.

Was nett ist bei Cairos Surface-Konzept ist, dass man die
genau gleichen Zeichenbefehle (denselben VB-Code letztlich)
gegen unterschiedliche Surface-Typen anwenden kann.
Das bedeutet, dass man z.B. dieselbe Drawing-Routine für
eine Pixel-Surface basierte Print-Preview-Implementierung
(Rendering gegen den "Screen") genauso auch gegen eine
Cairo-PDF-Surface anwenden kann - das erlaubt dann
eine wirklich "transparent arbeitende" PDF-Generierung,
ohne die sonst üblichen "Umwege" über PDF-Printer-Driver
oder àhnliches.

Hier mal eine erste Demo, welche genau dieses Szenario
abbildet: www.datenhaus.de/Downloads/CairoDemo.zip

Woran ich in den letzten Wochen gearbeitet habe - und was
in obiger Demo ebenfalls enthalten ist, ist der Wrapper-Support
in Bezug auf Image-, Icon- und Resource-Loading.

Der Wrapper làdt die üblichen VB-bekannten Image-Typen
(*.jpg, *.gif, *.bmp) und nun dank Cairo auch das *.png-format.
Darüber hinaus versteht und làdt er sàmtliche Icon-Formate -
egal ob als ResourceIcons or FileIcons (z.B. das neue Vista-
Icon-Format, welches PNG-content enthalten kann, wird
ebenso unterstützt, wie die XP-Icon-Formate mit Alphachannel).

Der CairoWrapper stellt für diese Zwecke auch eine App-globale
ImageList bereit, welche beim Start der Applikation befüllt werden
kann. Hier lassen sich also die verschiedenen Bild-Resourcen,
die eine Anwendung so benötigt, "einmalig abheften".
Hierbei wird z.B. auch das direkte Adden von Resource-Icons aus
System-Dlls unterstützt, z.B. aus "explorer.exe" oder "shell32.dll"
man benötigt nur die korrekte IconID, um solch einen Ladevorgang
mit einer Zeile Code abzuwickeln.
Die IconIDs der shell32.dll werden (zusammen mit den entspr.
Images) z.B. hier gelistet:
http://www.glennslayden.com/shell32_icons.htm

Alle Lese- und Schreiboperationen der verschiedenen Image-
erfolgen (ohne das Filesystem zu benutzen).

Die unterstützten FileTypen für die Leserichtung sind ja weiter
oben schonmal erwàhnt worden - in Schreibrichtung unterstützt
Cairo das emittieren von Pixel-Surface-Content als Png- und
das ebenfalls schon erwàhnte PDF-Format über einen eigenen
Surface-Typ.
Wie gesagt, ist auch hier der Output entweder in einem File
erzeugbar, oder direkt als ByteArray.

Die Stretch- und Scaling-Qualitàten von Cairo (down-
oder upstretching) für z.B. verschiedene Icon-Größen
sind ziemlich gut, der Alphachannel wird entsprechend
berücksichtigt und "mitgestretcht".
Z.B. làsst sich die Qualitàt eines 32x32Icons, gerendert
in "Original-Größe" kaum von der desselben Icons,
diesmal geladen als 48x48 großes Original, aber eben-
falls gerendert als 32x32-Output - unterscheiden.

Die obige Demo bildet genau solche Szenarien ab (Image-
und Icon-Loading aus verschiedenen Quellen - Rendering
in versch. Größen, sowie das Erzeugen von Png-Output
und PDF-Output.

Werd sehen, dass ich weitere Demos "nachschiebe", die sich
mehr auf die Vektor-Grafik konzentrieren (antialiased Rendering
von Linien, Winkeln, Bezier-Kurven usw.) - aber für einen
ersten Einstieg in die Wrapper-Klassen reicht das Gezeigte
wahrscheinlich erstmal hin, zumal der wohl interessanteste
Aspekt von Cairo (auch gegenüber GDI+), das "transparent"
arbeitende (bezogen auf den Drawing-Code) Erzeugen von
PDF-Output schonmal als Minimal-Beispiel mit enthalten ist.

Bitte einfach fragen, wenn irgendetwas unklar sein sollte.

Olaf

Ähnliche fragen