Entwicklung eines GKS Ger atetreibers auf der Basis des Mac OS X Core Graphics Frameworks
←
→
Transkription von Seiteninhalten
Wenn Ihr Browser die Seite nicht korrekt rendert, bitte, lesen Sie den Inhalt der Seite unten
Fachhochschule Aachen Standort Jülich Fachbereich 9 Medizintechnik und Technomathematik Entwicklung eines GKS Gerätetreibers auf der Basis des Mac OS X Core Graphics Frameworks Bachelorarbeit des Studienganges Scientific Programming Jülich, August 2009 Marvin Goblet Institut für Festkörperforschung Netzwerke und Numerik Diese Arbeit wurde betreut von: Prof. Dr. rer. nat. Jobst Hoffmann Fachhochschule Aachen Josef Heinen Institut für Festkörperforschung
Erklärung Diese Bachelorarbeit ist von mir selbständig abgefertigt und verfasst. Es sind keine anderen als die angegebenen Quellen und Hilfsmittel benutzt worden. Unterschrift Diese Arbeit wurde betreut von: Prof. Dr. rer. nat. Jobst Hoffmann Fachhochschule Aachen Josef Heinen Institut für Festkörperforschung
Am Institut für Festkörperforschung des Forschungszentrums Jülich ist schon seit Jahren eine standardisierte Grafikbibliothek im Einsatz, die auf einer Implementierung des grafischen Kernsystems (GKS) basiert. Zahlreiche Anwendungen aus dem Bereich der Instrumentierungs- und Simulationssoftware wurden auf der Basis dieser Bibliothek entwickelt, die sowohl von höheren Programmiersprachen als auch gängigen Interpre- tern angesprochen werden kann. Die Anforderungen an die Grafiksoftware im technisch- wissenschaftlichen Bereich sind in den letzten Jahren gestiegen, insbesondere der Bereich der technischen Präsentationsgrafik hat an Bedeutung gewonnen. Ziel dieser Arbeit ist es, die o.g. Bibliothek um moderne Visualisierungstechniken zu erweitern. Auf der Basis der Quartz-Anwendungsschnittstelle des Mac OS Betriebssys- tems sind erweiterte Funktionen implementiert, die den gewachsenen Ansprüchen an die Ausgabequalität gerecht werden. Dazu zählen Transparenz- und Schatteneffekte sowie affine Transformationen (Rotation, Scherung) und Spiegelungen. Hierzu ist ein logischer Gerätetreiber für GKS zu entwickeln, der als eigenständige Anwendung zweidimensio- nale Grafiken mit erweiterten Ausgabefunktionen auf der Basis von Quartz und PDF erzeugen kann.
Inhaltsverzeichnis 1 Einführung 9 1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.2 Ziel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2 Grafisches Kernsystem (GKS) 11 2.1 Grundkonzept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.2 Implementierung des GKS . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3 Entwicklung des GKS Mac-Treibers 17 3.1 Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.1.1 Application Frameworks . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.2 Quartz 2D Framework . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.3 Objective C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.2 GKS auf dem Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.3 Realisierung des Mac Treibers . . . . . . . . . . . . . . . . . . . . . . . . 23 3.4 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.4.1 GKSQuartzCreateWindow . . . . . . . . . . . . . . . . . . . . . . 29 3.4.2 GKSQuartzCloseWindow . . . . . . . . . . . . . . . . . . . . . . . 30 3.4.3 GKSQuartzDraw . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.4.4 clear ws . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.4.5 cellarray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.4.6 fillarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.4.7 polyline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.4.8 polymarker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.4.9 text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.4.10 draw marker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.4.11 draw pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.4.12 gks set transparency . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.4.13 gks set shadow . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.4.14 init colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.4.15 init norm xform . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.4.16 seg xform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.4.17 seg xform rel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.4.18 set clip rect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.4.19 set color rep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.4.20 set fill color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 7
3.4.21 set norm xform . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.4.22 set stroke color . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.4.23 Inline-Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4 Zusammenfassung und Ausblick 39 Literaturverzeichnis 39 Index 41 Abbildungsverzeichnis 42 Quellcode 43 8
1 Einführung 1.1 Motivation Computergenerierte Diagramme und Bilder dienen am Institut für Festkörperforschung einerseits zur anschaulichen Darstellungen von Simulationsergebnissen und Messdaten, andererseits sind sie aber auch unabdingbar für die Erstellung professioneller Präsen- tationen. Die Qualitätsansprüche an drucktechnisch erzeugte oder Web-basierte Doku- mente sind in den letzten Jahren stark angestiegen. Vor diesem Hintergrund wurden auch die Grafik-Bibliotheken am Institut für Festkörper- forschung (IFF) modernisiert, um den gewachsenen Ansprüchen gerecht zu werden. Durch den Einsatz standardisierter GKS-basierter Software konnten so viele Programme ohne großen Aufwand aufgewertet werden. Neben plattformunabhängigen Treibern für allgemeine Ausgabeformate ( PDF, Post- Script, SVG) stellt das GKS auch Treiber für systemnahe Grafiksubsysteme der jeweili- gen Betriebssysteme bereit. Diese logische Trennung hat den Vorteil, dass bei einer Wei- terentwicklung eines Betriebssytems nur der zuständige Treiber angepasst werden muss. Der im IFF für das Betriebssystem Mac OS X entwickelte Treiber verwendet derzeit noch Funktionen des Quickdraw-Frameworks, die in den kommenden Versionen (Version 10.6 und höher) nicht mehr unterstützt werden. Dieser Umstand, als auch die Einführung neuer leistungsfähiger Funktionen, legen die Anpassung/Erweiterung des bestehenden Treibers nahe. 1.2 Ziel Das Ziel dieser Arbeit besteht darin, die Funktionen des Mac-Treibers den gestellten Anforderungen anzupassen. Dazu werden die Funktionen des veralteten Quickdraw- Frameworks durch die Funktionen des Core Graphics Frameworks ausgetauscht. Zusätzlich sollen neue Funktionen für Transparenz- und Schatteneffekte sowie affine Transformationen von Objekten implementiert werden. Ein wesentlicher Teil der Arbeit besteht darin, den Treiber möglichst effizient in die Struktur des Mac OS X Betriebssystems zu integrieren. Hierbei sind verschiedene Sze- narien (Plugin- Client/Server-Technik) zu untersuchen und ein Konzept auszuarbeiten, welches eine optimale Anbindung des GKS an die zur Verfügung stehenden grafischen Subsysteme erlaubt. Die Abbildung 1.1 zeigt das Abstraktions-Schema des GKS. 9
Fortran C/C++ Python Ruby App App App App Grafisches Kernsystem (GKS) X11 Win32 PDF Postscript Quartz ... Abbildung 1.1: Abstraktions-Schema des GKS 10 | Kapitel 1. Einführung
2 Grafisches Kernsystem (GKS) 2.1 Grundkonzept Das grafische Kernsystem wurde Anfang der 80er Jahre entworfen um eine einheitliche Basis für Computer gestützte Grafiken zu schaffen und 1985 wurde es als ISO 7942 Stan- dard veröffentlicht. Die GKS-Norm ist eine Sammlung von Definitionen, die eine abstrakte Schicht zwischen den Anwendungsprogrammen und den Treibern der grafischen Ausgabegeräte bildet. Die Programme, die das GKS als Basis zur Ausgabe der Ergebnisse verwenden, können auf jedem beliebigen System Grafiken erzeugen, für das das GKS einen Treiber bereit stellt. Es gibt also nicht nur ein grafisches Kernsystem, sondern jede Implementierung, die sich an die Spezifikationen hält, kann als GKS eingesetzt werden. Die Grundlagen jeder GKS-Implementierung sind die Input- bzw. Output Primitives. Primitives sind ato- mare Elemente, die als Grundlage für sämtliche komplexe Grafiken dienen. Die Output Primitives sind: Polyline Polylines bestehen aus mehreren verbundenen Linien. Polymarker Polymarker sind vordefinierte Symbole wie Sterne, Kreise oder Vierecke. Text Die Text Primitive beschreibt eine Textausgabe in verschiedenen Alphabeten mit Sonderzeichen wie z. B. mathematischen Symbolen. Fill Area Eine Fill Area ist ein Bereich, der farbig und/oder mit einem beliebigen Mus- ter oder einer Schraffur ausgefüllt ist. Cell Array Das Cell Array ist ein rechteckiger Bereich bestehend aus Zellen mit Far- belementen zur Darstellung Raster-ähnlich vorliegender Bilder. Generalized Drawing Primitives Die Generalized Drawing Primitives sind GKS-Imple- mentierungs-spezifische Zeichenfunktionen, z. B. zum Zeichnen von B-Splines, Krei- sen oder Ellipsen. 11
Polyline Polymarker Text GKS Term Generalized Fill Area Cell Array Drawing Primitives Abbildung 2.1: Output Primitives des GKS Die Input Primitives dienen zur interaktiven Steuerung der grafischen Ausgabe. Da nicht jede Umgebung den vollen Umfang der GKS-Norm ausnutzen kann oder gar- nicht erst braucht, sind neun Konfigurationen (GKS-Levels) definiert worden. Es gibt drei Output- und drei Input-Level, die beliebig kombiniert werden können. Die Ouput- Level sind von 0 bis 2 und die Input-Level von a bis c durchnummeriert. Jedes Level ist eine Erweiterung des vorangegangenen Levels, wobei 2c den vollen Umfang beschreibt. Output Level 0: Minimale Output Kontrolle. Es können alle Output Primitives mit beliebigen Farbdarstellungen verwendet werden. Es darf nur eine Workstation vor- handen sein. Output Level 1: Zusätzlich zu Level 0 ist die Update-Kontrolle einer Workstation ge- geben. Es dürfen mehrere Workstations betrieben werden. Zudem ist eine einfache Segmentkontrolle gegeben. Segmente sind zusammenhängende Teile einer Grafik, die vom Programm angesprochen und nachträglich bearbeitet werden können. Output Level 2: In Level 2 können die Segmente auch vervielfältigt und nachträglich in die Workstation eingefügt werden. Input Level a: Beim Level a gibt es keine Input Funktionen. Input Level b: Bei Level b sind Request Inputs möglich. Beim Request Input wartet das GKS, bis der Input, z. B. eine Texteingabe getätigt wurde, und verarbeitet den Input direkt. Input Level c: Beim Level c gibt es zusätzlich die Sample und die Event Inputs. Beim Sample Input fragt das GKS selbstständig ein Input Device, z. B. die Postition eines Mauszeigers, ab und verarbeitet die Werte. Die Event gesteuerte Eingabe läuft parallel zum Ablauf eines Programms. Das GKS verarbeitet den Input zu einem gegebenen Zeitpunkt. 12 | Kapitel 2. Grafisches Kernsystem (GKS)
Ein wichtiges Konzept des GKS ist die Abstraktion der Ausgabegeräte. Ein Ausgabe- gerät wird allgemein als Workstation bezeichnet. Eine Workstation kann ein Drucker oder ein Bildschirm sein oder rein virtuelles Medium wie eine Bilddatei oder ein Fenster, das auf einem Bildschirm dargestellt wird. Zu jeder Art von Workstation, die an einem System angeschlossen oder installiert ist, benötigt das GKS einen eigenständigen Trei- ber, der die Eigenschaften der Workstation kennt. Mit der Abstraktion der Workstation muss auch die grafische Ausgabe normiert werden. Die Anwendungsprogramme kennen im Normalfall die Ausgabeflächen der Workstations nicht. Zudem sind die Ausgabeflächen nicht einheitlich. Eine Bilddatei z. B. wird in Pi- xeln angegeben, deren Anzahl beliebig variieren kann. Die Ausgabe auf einem Drucker hängt vom gewählten Format des Papiers ab. Das GKS muss dafür sorgen, dass die Daten richtig ausgegeben werden. Dazu rechnet das GKS die so genannten world coordinates der Anwendung in die normalized device coordinates(ndc) um. Das Anwendungspro- gramm muss dem GKS dazu einen Bereich innerhalb der world coordinates angeben, in dem sich die Daten befinden. Der Bereich wird Window genannt. Der normalisierte Be- reich der Workstation ist ein Quadrat mit der Kantenlänge 1, auch NDC-Space genannt. Damit das Window in den NDC-Space übertragen werden kann, muss ein Bereich, ein sogenannter Viewport, im NDC-Space definiert werden. Der Viewport ist das Abbild des Windows im NDC-Space. Eine Anwendung kann beliebig viele Viewports erzeugen, die sich gegenseitig überlagern können. Entscheidend für die Ausgabe ist jedoch nur der Bereich des NDC-Spaces, der als Workstation Window gekennzeichnet ist. Das Workstation Window wird in den Work- station Viewport gelegt, der sich in der Ausgabefläche der Workstation befindet. In einem zweiten Transformationsschrit werden die normalisierten Koordinaten hierbei in die Gerätekoordinaten der jeweiligen Workstation umgerechnet. In Abbildung 2.2 ist der Ablauf der Transformierung dargestellt. Application GKS Workstation Window (1,1) NDC - Space Viewport world Workstation coordinates Window Workstation Viewport normalized device coordinates (0,0) device coordinates Abbildung 2.2: Die Transformation der Grafiken im GKS 2.1. Grundkonzept | 13
2.2 Implementierung des GKS GKS Da die ersten kommerziellen GKS-Implementierungen viel Speicherplatz benötigten und zudem nicht schnell genug arbeiteten, wurde im IFF schon Mitte der 80-er Jahre mit der Entwicklung eines eigenen GKS-Systems [Jos96] begonnen. Die Software wurde von Anfang an für den Einsatz in Realtime-Umgebungen konzipiert und wurde zur Basis für zahlreiche Anwendungen in und außerhalb des Forschungszentrums, z.B. • Graphics Language Interpreter (GLI) • SIGHT (Simple Interactive Graphics Handling Tool) • Psh (Portable Shell) • GRSOFT • Live-Displays für verschiedene Instrumentierungssysteme • Auswertesoftware für Neutronenstreu-Experimente Aufgrund der Plattformunabhängigkeit ist das GKS für verschiedenste Systeme verfügbar: • Linux / UNIX • Windows • Mac OS X Zu den wichtigsten Ausgabeformaten gehören: PS PostScript PDF Portable Data Format SVG Scalable Vector Graphics Xfig Ausgabeformat des Vektorgrafik-Zeichenprogramm Xfig WMF Windows Metafile, ein Dateiformat für Vektorgrafiken Bildformate BMP, PNG, JPEG, TIFF Metafile-Formate GKSM (GKS-Metafile), CGM (Computer Graphics Metafile) 14 | Kapitel 2. Grafisches Kernsystem (GKS)
Die GKS-Implementierung des IFF beinhaltet Sprach-Anbindungen für: • C / C++ • Fortran • (Free-)Pascal • Python • Ruby • Perl Aufgrund der o.g. Eigenschaften ist die Software somit universell einsetzbar. Für system- spezifische Ausgabeformate bietet das GKS einen Plugin-Mechanismus, um externe Gerätetreiber anzudocken. Diese Technik wurde auch im Rahmen dieser Bachelorar- beit genutzt. GR Im wissenschaftlichen Bereich wurden schon immer große Anforderungen an Hard- und Software gestellt. Aus dem Grunde wurde zum GKS das Graphic-System, kurz GR, entwickelt. Die GR-Bibliothek basiert auf einer im IFF entwickelten GKS-Bibliothek. Abbildung 2.3 zeigt, wie das GR mit dem GKS zusammenhängt. Fortran C/C++ Python Ruby App App App App Graphic Library (GR) Grafisches Kernsystem (GKS) X11 Win32 PDF Postscript Quartz ... Abbildung 2.3: Modell des GR-Systems des IFF 2.2. Implementierung des GKS | 15
Das GR ergänzt das GKS um einige wichtige Funktionen, wie: • logarithmische Transformationen • 3D-Transformationen • Umdrehen (flip) der Achsen • erweiterte Textfunktionen (Hoch-/Tiefstellen, griechische Zeichen, Sonderzeichen, Formeldarstellung) • erweiterte Druckfunktionalität Mit dem neuen Mac-Treiber sind hinzu gekommen: • Schatteneffekte • Transparenz • affine Transformationen wie z. B. Skalierung und Drehung 16 | Kapitel 2. Grafisches Kernsystem (GKS)
3 Entwicklung des GKS Mac-Treibers Die Aufgabe eines GKS-Treibers besteht darin, den Anwendungsprogrammen die Funk- tionen eines bestimmten Betriebssystems bereit zu stellen. Der GKS-Treiber muss die Daten, die die Anwendungsprogramme dem GKS übergeben, entsprechend aufbereiten und anschließend die Funktionen des Mac Betriebssystems nutzen. Das Mac Betriebssystem stellt zwei Sprachen zur Verfügung, die sich für die Erstel- lung eines GKS-Treibers eignen. Die erste von beiden ist C, die andere basiert auf der C-Syntax und heißt Objective-C[And03]. Beide Sprachen bieten vollen Zugriff auf die grafischen Komponenten des Mac Betriebssystems. Für die Entwicklung eines GKS-Treibers ist es wichtig, die Möglichkeiten zu kennen, die das Betriebssystem zu bieten hat. 3.1 Mac OS X Das Betriebssystem Mac OS X [App09b] ist ein modulares System, dass sich anhand eines Schichtenmodells beschreiben lässt. Die oberste Schicht beschreibt die Funktiona- litäten mit denen der normale Benutzer interagiert. Dashboard und Spotlight sind Funk- tionen, die dem Benutzer das Arbeiten mit dem Mac erleichtern sollen. Aqua und Acces- sibility sind Konzepte, die das Layout und das Verhalten der Programme beschreiben. Die zweite Schicht bietet dem Entwickler umfassende Bibliotheken an, die in Gruppen, Abbildung 3.1: Schichtenmodell des Betriebssystems Mac OS X so genannten Frameworks, zusammengefasst sind. Zur Erstellung einer Fensteranwen- dung im Aqua look and feel stehen drei verschiedene Frameworks bereit. Das ist einmal das in C geschriebene Carbon und zum zweiten Cocoa, das auf Objective-C basiert. 17
Das dritte Framework ist eine Implementierung der Sprache Java von der Firma Sun Mi- crosystems. Cocoa und Carbon verwenden für Multimedia Anwendungen die Frameworks aus der dritten Schicht. Java hingegen besitzt eigene interne Multimedia Systeme, kann aber auch auf die Grafikframeworks des Betriebssystems zugreifen. 3.1.1 Application Frameworks Carbon Das Framework Carbon wurde entwickelt, um Anwendungen, die für das Mac OS 8 oder OS 9 geschrieben wurden, in das neue Mac OS X zu integrieren. Die in C imple- mentierten Schnittstellen ermöglichen zudem auch die Portierung von Programmen, die für andere Betriebssysteme geschrieben wurden, vorausgesetzt die verwendete Program- miersprache ist mit C kompatibel. Cocoa Das native Framework für die Erzeugung und Entwicklung von Fensteranwendungen auf dem Mac OS X ist Cocoa. Es gliedert sich in zwei Teilbereiche auf. Das Foundation Framework stellt alle grundlegenden Mechanismen zur Handhabung von Datentypen, Speichermanagement, Prozess-threading oder Netzwerk Kommunika- tion bereit. DasApplication Kit ist für die höher liegenden Kontrollelemente der grafischen Benut- zungsschnittstelle (GUI ) verantwortlich. Beide Teilbereiche lassen sich unabhängig von- einander verwenden. Sowohl Cocoa als auch Carbon setzen beide auf dem Core Foundation Framework auf, das sich auf der Kernelebene namens Darwin befindet. Sie verwenden somit intern zum großen Teil dieselben Routinen. Es stellt sich daher nicht die Frage welches Framework besser ist, sondern ob man lieber prozedural in C oder objektorientiert in Objective-C entwickelt, wobei sich die Sprachen sowie die Frameworks auch kombinieren lassen. 3.1.2 Quartz 2D Framework Cocoa und Carbon verwenden für Multimedia Anwendungen die Frameworks der drit- ten Schicht. Die Schnittstelle, mit der zwei dimensionale Grafiken dargestellt werden können, ist das Core Graphics Framework, auch Quartz 2D genannt. Quartz 2D ist die Grundlage für jede zweidimensionale grafische Ausgabe in einer Work- station auf dem Mac OS X Betriebssystem. Die am häufigsten verwendete Workstation, im Sinne des GKS, ist der Bildschirm. Der Bildschirm, oder auch main screen, stellt die Fenster dar, die für die Darstellung grafi- scher Daten verwendet werden können. Bevor die Daten in einer Workstation angezeigt werden, erstellt Quartz 2D intern die Grafik in einem unabhängigen Koordinatensystem. Quartz 2D transformiert zur Aus- gabe das Koordinatensystem in das Koordinatensystem der Workstation. Dazu erzeugt Quartz 2D eine Datenstruktur, die die Grafikinformationen der Workstation verwaltet. 18 | Kapitel 3. Entwicklung des GKS Mac-Treibers
Diese Struktur ist ein sogenanter CGContext. Durch die Abstraktion des Koordinatensystems lassen sich affine Transformationen wie Rotationen oder Skalierungen einzelner Objekte einer Grafik einfach bewerkstelligen. Eine Rotation z. B. wird erzeugt, indem Quartz 2D der Grafikumgebung anweist, das Koordinatensystem um den Nullpunkt zu drehen und dann das Objekt zu zeichnen. Die Änderung des Koordiantensystems hat immer nur Auswirkung auf die noch zu zeich- nenden Objekte, nicht aber auf die, die schon gezeichnet wurden. Listing 3.1 zeigt ein Beispiel dazu. Die Abbildung 3.2 ist das Ergebnis des Beispiels. Listing 3.1: Drawing a rotated and scaled rectangle([Dav06], page 92 ) 1 CGRect ourRect = { { 0 . , 0 . } , { 7 2 . , 7 2 . } } ; // Draw t h e u n r o t a t e d c o o r d i n a t e a x e s . 3 drawCoordinateAxes ( c o n t e x t ) ; // F i l l t h e u n s c a l e d r e c t a n g l e . 5 CGContextFillRect ( c o n t e x t , ourRect ) ; // Rotate t h e c o o r d i n a t e system by 30 d e g r e e s . 7 CGContextRotateCTM ( c o n t e x t , M PI / 6 ) ; // S c a l e t h e c o o r d i n a t e system by 0 . 5 i n x and 2 . 0 i n y . 9 CGContextScaleCTM ( c o n t e x t , 0 . 5 , 2 . 0 ) ; CGContextSetRGBStrokeColor ( c o n t e x t , 0 . 6 9 , 0 . 4 8 6 , 0 . 7 2 2 , 1 . 0 ) ; 11 CGContextSetRGBFillColor ( c o n t e x t , 0 . 6 9 , 0 . 4 8 6 , 0 . 7 2 2 , 0 . 7 ) ; // Draw t h e c o o r d i n a t e a x e s a f t e r t h e t r a n s f o r m a t i o n s . 13 drawCoordinateAxes ( c o n t e x t ) ; // F i l l t h e r o t a t e d and s c a l e d r e c t a n g l e . 15 CGContextFillRect ( c o n t e x t , ourRect ) ; Abbildung 3.2: Grafik des Listings 3.1 3.1. Mac OS X | 19
Das zu zeichnende Objekt, hier ein Rechteck, wird mit den Angaben zum Aufpunkt und den Längen der orthogonalen Richtungsvektoren angegeben. Der context enthält die In- formationen über den Workstation Viewport der aktuellen Workstation. Das Rechteck wird hier einmal im originalen und einmal im gedrehten und skalierten Koordinatensys- tem gezeichnet. Zudem werden zur besseren Darstellung die Farben der Linien und der Füllflächen geändert. Die Farben werden im RGBA-Farbraum angegeben. Die Werte der einzelnen Farben liegen im Intervall von 0 bis 1. Die Funktion drawCoordinateAxes() befindet sich in abgewandelter Form im Buch Programming with Quartz [Dav06] auf Seite 615. 3.1.3 Objective C Unter Cocoa Programmierung versteht man im Allgemeinen Programmieren in Objective- C unter Verwendung des Cocoa-Frameworks. Objective-C ist eine objektorientierte Er- weiterung der Sprache C. Objektorientierte Sprachen setzen auf das Konzept des späten Bindens. Das bedeutet, dass erst bei der Verwendung eines Datenobjekts, also zur Laufzeit des Programms, die Klassenzugehörigkeit ermittelt wird. Das ist insbesondere bei der Vererbung von Metho- den nötig. Bei der Vererbung bestimmt das dynamic dispatch[Sco94] welche Methode verwendet werden soll. Bei objektorientierten Sprachen werden die Aufrufe von Funktionen durch das Versen- den von messages an die Datenobjekte realisiert. Das bedeutet, wenn eine Methode eines Objektes verwendet werden soll, wird eine entsprechende Nachricht an das Objekt gesen- det. Wenn die Klasse des Objektes die Methode implementiert, wird der Programmcode ausgeführt. Damit die Typsicherheit zur Compilezeit sichergestellt werden kann, bindet z. B. C++ an jedes Objekt eine virtuelle Tabelle, die sicherstellt, das ein Objekt auf die message antworten“ kann. Die Klassenzugehörigkeit steht somit vorher fest. Lediglich das dyna- ” mic dispatching wird wegen der Vererbung beibehalten. Objective-C hingegen bestimmt den Typ eines Datenobjektes erst zur Laufzeit. Die Idee dahinter ist, sich mehr Gedanken über das Laufzeitverhalten eines Programms zu ma- chen, als sich zu überlegen welchen Typ ein Objekt zur Compilezeit hat. Die Sprache ist dadurch sehr variabel. Es ist sogar möglich, zur Laufzeit eine message zusammen ” zu bauen“ und diese anschließend an ein Objekt zu senden. Wenn das Objekt keine passende Methode hat, kann die message einfach weiter geleitet werden. Wie es in C-basierten Sprachen üblich ist, werden die Definitionen der Klassen in hea- der files festgehalten. Die header files sind die Schnittstellen der einzelnen Programm- teile. Mit ihnen können externe Bibliotheken, z. B. Frameworks, eingebunden werden. Objective-C selbst besitzt nur wenige eigene Standardbibliotheken, es werden stattdes- sen Frameworks wie z. B. Cocoa von Apple Inc. verwendet. Die Entwicklungsumgebung von Mac OS X unterstützt zudem noch die Interpreterspra- chen Python und Ruby, die ebenfalls zur Programmierung von Cocoa-Programmen ge- eignet sind. Realisiert wird die Kommunikation mit Hilfe der so genannten Brücken 20 | Kapitel 3. Entwicklung des GKS Mac-Treibers
(bridges) PyObjC und RubyCocoa. Die bridges bieten den Interpretersprachen den Zu- griff auf das Cocoa Framework. Die Programmierung kann komplett in der gewählten Interpreterspache geschehen. 3.2 GKS auf dem Mac OS X Damit das GKS auf einem Mac Betriebssystem verwendet werden kann, ist ein Treiber nötig, der Funktionen des GKS mit dem Quartz 2D Framework verbindet. Der Mac- Treiber ist in jetzt zwei Komponenten realisiert. Der erste Teil ist das Quartz 2D-Plugin des GKS. Das Plugin enthält die Funktion, mit der das GKS die Anweisungen an den Mac-Treiber sendet. Der Mac-Treiber hingegen ist ein eigenständiges Programm, das in der Lage ist von jedem beliebigen Programm angesprochen zu werden und deren grafische Ausgabe zu übernehmen, vorausgesetzt das Anwendungsprogramm verwendet die passende Kommu- nikationsstruktur. GKSTerm GKS Window 1 server GKS Functions server connection Quartz Plugin r Buffe client connection window table Window 2 GKS Functions Window n GKS Functions Abbildung 3.3: Struktur des GKS Mac-Treibers Die Kommunikation zwischen dem GKS und dem Mac-Treiber beruht auf dem distri- buted object-Prinzip. Ein Programm kann zur Laufzeit eine oder mehrere Klassen mit einem name server verbinden. Die Methoden dieser Klassen können von jedem anderen Programm verwendet werden, das sich mit dem name server verbindet. Die Listings 3.2 und 3.3 zeigen, wie die Verbindung aufgebaut wird. Listing 3.2: distributed object client connection 1 i d s e r v e r = [ NSConnection rootProxyForConnectionWithRegisteredName :@”GKSQuartz” h o s t : n i l ] ; 3 [ s e r v e r s e t P r o t o c o l F o r P r o x y : @ p r o t o c o l ( GKSProto ) ] ; 3.2. GKS auf dem Mac OS X | 21
Listing 3.3: distributed object server connection 1 i d doConnection = [ NSConnection d e f a u l t C o n n e c t i o n ] ; [ doConnection s e t R o o t O b j e c t : s e l f ] ; 3 [ doConnection r e g i s t e r N a m e :@”GKSQuartz ” ] ; Das Quartz 2D-Plugin sammelt die Anweisungen in einem Buffer (Display-Liste) bis der Befehl update workstation auftritt, erst dann wird der gesamte Buffer an den Treiber gesendet. Der Treiber empfängt den Buffer und leitet ihn an das entsprechende Fenster weiter. Bei der ersten Verbindung wird vorher für das Anwendungsprogramm ein Fens- ter eingerichtet, das zur Ausgabe der Daten dient. Die Fenster werden in der window table vermerkt und die zugehörige Identifikationsnummer dem GKS mitgeteilt, damit die Anwendungen die zugeteilten Fenster ansprechen können. Das erstellte Fenster besteht aus einem Rahmen mit Titelzeile und einer Ausgabefläche. Das Fenster wird in der GKS-Terminologie als Workstation bezeichnet. Die Ausgabe- fläche bildet den maximalen Rahmen, den der Workstation Viewport annehmen kann. Die Ausmaße der Ausgabefläche bilden die device coordiantes. Da jedes Anwendungspro- gramm sein eigenes Koordinatensystem besitzt, rechnet das GKS die world coordinates der Anwendung in normalized device coordinates um. Die normalized device coordinates bilden eine normierte Fläche der Länge eins (NDC-Space). Die normalisierten Koordi- naten der Grafiken werden dann zur Ausgabe in die device coordiantes der Workstation umgerechnet. Die Umrechnungsfaktoren, sowie die Abmessungen der Workstation und des Workstation Viewports werden in einer Statusliste (ws state list) gespeichert. Das angesprochene Fenster interpretiert die Daten im Buffer und leitet sie an die ent- sprechenden Zeichenfunktionen weiter. Die grafischen Funktionen arbeiten immer nach demselben Prinzip. • Zuerst wird der CGContext des aktuellen Ausgabefensters bestimmt. • Dann werden die Koordinaten umgerechnet. Dazu werden Makros verwendet, die die world coordinates in device coordinates transformieren. • Anschließend wird die Farbe des Objekts gesetzt. Das GKS bietet vordefinierte Farbschemen, die über eine Funktion abgerufen werden. • Der neue Mac-Treiber kann dank des Quartz2D-Frameworks jeder Farbe nun auch eine Transparenzabstufung zuteilen, zudem werden die Farbeinstellungen von Li- nien und Füllflächen separat behandelt. • Die Objekte werden dann in das CGContext des Fensters gezeichnet und direkt angezeigt. Bei jedem Aufruf von update workstation wird die gesamte Ausgabe neu gezeichnet. Das hat die Bewandtnis, dass das NSView -Objekt, das Objekt was Cocoa für die Ausgabe in einem Fenster zur Verfügung stellt, eine Callback Funktion besitzt, die beim Neuzeich- nen des Fensters aufgerufen wird. Die Callback Funktion sorgt dafür, dass z. B. nach einem Verschieben des Fensters die Ausgabe noch vorhanden ist. 22 | Kapitel 3. Entwicklung des GKS Mac-Treibers
Die Erweiterungen des Mac-Treibers konnten direkt mit Quartz 2D realisiert werden. Die Transparenz wird über einen Alphawert bei der Farbdarstellung (RGBA) erzeugt. Mit gks set transparency wird der Alpha-Wert global gesetzt. Die Schatten werden als graue Fläche hinter die Grafik projiziert. Mit der Funktion gks set shadow können die Schatteneffekte eingestellt werden. Die Transformationen können in Quartz 2D über verschiedene Wege erzeugt werden. Entweder kann die current transformation matrix (CTM) einfach über Funktionen an- gepasst werden, wie es in Listing 3.1 vorgestellt wurde. Oder es wird eine eigene 3 × 2 Matrix definiert, mit denen die Koordinaten von links multipliziert werden. Im Mac Treiber soll die zweite Variante implementiert werden, dazu muss das GKS aber noch angepasst werden. 3.3 Realisierung des Mac Treibers Mit der Weiterentwicklung des Mac OS X Betriebssystems wurde das Quickdraw Fra- mework durch das Quartz 2D Framework als Standard für die Erzeugung von grafischen Elementen endgültig abgelöst. Diese Umstellung hatte zur Konsequenz, dass der bisheri- ge GKS Treiber, der für die Erzeugung der Grafik unter dem Mac OS X Betriebssystem verantwortlich war, angepasst werden musste. In den zur Verfügung stehenden Application Frameworks des Mac OS X wird aus- schließlich ein objektorientierter Ansatz verfolgt. Wie bei fast allen grafischen Bedieno- berflächen, muss die Kontrolle des Programms an eine übergeordnete Funktion (event loop) übergeben werden, die auf Ereignisse wie z. B. Mausbewegungen und Tastaturein- gaben reagieren kann. Da aber die GKS Software im Wesentlichen in ablauforientierten Programmen zum Einsatz kommt (Eingabe - Verarbeitung - Ausgabe), ergab sich nun hier ein strukturelles Problem. Das Konzept des Treibers musste dabei neu überdacht und verändert werden. In der vorherigen Version war der Treiber als Plugin direkt mit dem GKS und damit mit den Anwendungsprogrammen verbunden. Hierbei wurden unter Mac OS X sogenannte dynamic link libraries verwendet, die mit UNIX shared objects oder Windows DLLs vergleichbar sind und das dynamische Binden von Code erlauben. Die Anwendungen erzeugten bei jedem Aufruf ihr eigenes grafisches Fenster, das nur von der jeweiligen Anwendung verwendet werden konnte. Diese Technik ist mit dem neuen Mac OS X Sys- tem nicht mehr möglich. Wegen der erwähnten Ereignissteuerung ist eine Zweiteilung des System notwendig. Deshalb wurde der neue Treiber auf einer Client-Server Archi- tektur aufgebaut. Das GKS-Plugin, hier als Quartzplugin bezeichnet, ist als Client weiterhin mit dem GKS verbunden. Das Plugin ist, wie das gesamte GKS, in C geschrieben und bedient sich zur Speicherung der Grafikbefehle C-spezifischer Datenstrukturen. Die gesamte Grafik wird hierbei in einer Display Liste (displayList) abgelegt, die in Form eines dynamischen By- tearrays implementiert ist. Das Quartzplugin ist somit nur noch für den Empfang und die Zwischenspeicherung der 3.3. Realisierung des Mac Treibers | 23
Daten einer Anwendung zuständig. Das Quartzplugin verarbeitet nur noch die Befehle: • open workstation • close workstation • update workstation • clear workstation Bei open workstation weist das Quartzplugin dem eigentlichen Treiber an, ein Ausgabe- fenster für die Anwendung anzulegen. Bei close workstation wird dem Treiber mitgeteilt, dass Fenster wieder zu schließen. Die restlichen Befehle werden mit den entsprechenden Daten in der displayList abgelegt. Die displayList ist ein C Struct, das ein dynamisches Bytearray beinhaltet, das zur Datenspeicherung verwendet wird. Bei update workstation wird dann die displayList an den Treiber gesendet. Beim clear workstation wird einfach der Pointer auf das Bytearray zurückgesetzt und neu initialisiert. Die Kommunikation zwischen dem Plugin und dem Treiber wurde, wie in den Listings 3.2 und 3.3 dargestellt, über ein distributed object realisiert. Das Framework Cocoa stellt diese Kommunikationsart für die Interprozess-Kommunikation zur Verfügung. Das Quartzplugin registriert sich beim Start über eine NSConnection beim Betriebssys- tem internen Nameserver unter dem Namen GKSQuartz. Damit wird eine Verbindung erzeugt, die eine Kommunikation mit dem neuen GKS Treiber erlaubt. In einem Proto- koll, einer speziellen Art von header Dateien, die in Objective-C eingeführt wurden, sind die Funktionen des Mac Treibers, die über die Interprozess-Kommunikation angespro- chen werden können, dem nameserver bekannt gegeben. Jedes Programm, dass nach Listing 3.2 sich mit dem Nameserver verbindet, kann nach Einbindung des Protokolls die Methoden des Mac Treibers verwenden, als wären sie im Programm implementiert. Das Quartzplugin muss an dieser Stelle auf ein Objective-C zurück greifen, damit es die Verbindung aufbauen kann. Der Mac Treiber registriert drei Funktionen im Protokoll: • GKSQuartzCreateWindow • GKSQuartzCloseWindow • GKSQuartzDraw Mit GKSQuartzCreateWindow wird ein Fenster im Treiber erzeugt. Der neue Treiber arbeitet als Server für alle Programme, die über die distributed object Verbindung ein Ausgabefenster erzeugt haben. Alle Fenster werden in einem Array abge- legt und können über den Index angesprochen werden. Der Index wird als Rückgabewert an das Quartzplugin übergeben. Der Treiber benutzt für die Erzeugung der Fenster das NSWindow -Objekt aus dem Cocoa Framework. In das NSWindow -Objekt wird ein GKS- View -Objekt eingebunden. Die GKSView -Klasse ist von der NSView -Klasse abgeleitet, 24 | Kapitel 3. Entwicklung des GKS Mac-Treibers
die als grafische Ausgabeschicht in einem NSWindow -Objekt verwendet wird. Mit der Funktion GKSQuartzDraw wird die displayList des Quartzplugins als NSData- Objekt an den Treiber übergeben. Die displayList muss in ein Objekt verpackt werden, da Objective-C bei der Versendung von C Pointern über eine distributed object Kommu- nikation nicht auf den gesamten Speicherbereich zugreifen kann. Die Verwendung eines NSData-Objektes ist dafür am Besten geeignet, da die Daten einfach als Bytes kopiert werden. Die displayList liegt nach dem versenden im Plugin und als Kopie im Mac Trei- ber. Nachdem die displayList an den Treiber gesendet wurde, arbeitet der Mac Treiber par- allel zum Plugin. Das bedeutet, noch während der Mac Treiber mit der Verarbeitung der displayList beschäftigt ist, kann das Quartzplugin bereits neue Daten vom Anwen- dungsprogamm aufnehmen und in die displayList speichern. Beendet wird die Ausgabe mit dem Befehl close workstation. Das Quartzplugin weist den Treiber mit der Funktion GKSQuartzCloseWindow an, das Fenster zu schließen. Wenn das Anwendungsprogramm erneut Grafiken zeichnen möchte, muss zuerst wieder mit open workstaion ein neues Fenster angelegt werden. Die alte displayList ist aber nicht mehr vorhanden. Der Mac Treiber, hier als GKSTerm bezeichnet, ist als eigenständiges Cocoa-Programm entwickelt worden. Ein Programm, dass in Objective-C geschrieben wurde und das Co- coa Framework als Window Toolkit verwendet, besitzt bereits eine Event gesteuerte main loop, die für eine Fensteranwendung benötigt wird. Siehe dazu Listing 3.4. Listing 3.4: Erzeugung einer Event loop mit Cocoa 1 #import 3 i n t main ( i n t argc , c o n s t c h a r ∗ argv [ ] ) { 5 r e t u r n NSApplicationMain ( argc , ( c o n s t c h a r ∗ ∗ ) argv ) ; } Die Funktion NSApplicationMain sorgt dafür, dass das aufgerufene Programm als Fens- teranwendung ausgeführt wird. Das GKSTerm ist als Grafikserver konzipiert, der für an- dere Programme die Ausgaben auf dem Mac übernimmt. Damit der Treiber von anderen Programmen angesprochen werden kann, wird beim Start des Treibers eine NSConnec- tion zu dem internen Nameserver des Betriebssystems aufgebaut. Listing 3.3 zeigt den Aufbau der Verbindung. Das GKSTerm wird unter dem Namen GKSQuartz“ im Nameserver registriert. Die ” Client-Anwendungen, z. B. das Quartzplugin, können die Funktionen des GKSTerm über den Nameserver ansprechen und benutzen. Üblicherweise werden die Funktionen, die als Schnittstelle verwendet werden sollen, in einer Protokolldatei festgelegt. Die Protokoll- datei wird bei den Client-Anwendungen als header file eingebunden und beim Aufbau der Verbindung angegeben. Die Schnittstellen sind, wie bereits erwähnt: 3.3. Realisierung des Mac Treibers | 25
• GKSQuartzCreateWindow • GKSQuartzCloseWindow • GKSQuartzDraw Mit der Funktion GKSQuartzCreateWindow kann ein Anwendungsprogramm ein Fens- ter im GKSTerm anlegen. Die Fenster werden in einem Array abgelegt und der Index wird dem Plugin mitgeteilt. Ein Fenster wird durch ein NSWindow -Objekt erzeugt. Die NSWindow -Klasse ist im Cocoa Framework definiert und dient als Grundlage für jede Fensteranwendung im Mac OS X Betriebssystem. Damit in einem Fenster Grafiken erzeugt werden können, muss ein NSView -Objekt in das Fenster eingebunden werden. Im GKSTerm wurde ein GKS- View implementiert, das von der NSView -Klasse abgeleitet ist. Im GKSView sind alle Funktionen implementiert, die zur Verarbeitung der displayList benötigt werden. Bei der Erzeugung eines Fensters wird also ein GKSView instanziiert und dem Fenster zugewie- sen. Das GKSTerm ist ab dem Zeitpunkt nur noch für die Weiterleitung der displayList verantwortlich. Die Verarbeitung der Daten übernimmt das Fenster, bzw. das GKSView. Der Aufbau wird in der Abbildung 3.3 veranschaulicht. Wenn ein Anwendungsprogramm seine displayList an das GKSTerm schickt, sucht sich das GKSTerm anhand des Fensterindizes das zugehöhrige Fenster mit dem entsprechen- dem GKSView. Die displayList wird dann dem GKSView übergeben. Im GKSView sind alle grafischen Funktionen des alten Mac Treibers enthalten. Das GKSView kann die fünf Output Primitives: • text • polyline • polymarker • fill area • cell array verarbeiten, sowie transparente Farbeffekte erzeugen. Dazu können zu jedem Grafikob- jekt ein Schatten definiert werden. Genauere Erläuterungen der Funktionen sind im Abschnitt 3.4 zu finden. Zur Darstellung der Daten wird die displayList im GKSView kopiert. Die displayList ist somit im Quartzplugin und im GKSTerm vorhanden. Das hat zwei Gründe. Zum einen kann das GKSTerm, bzw. das entsprechende GKSView parallel zum Anwen- dungsprogramm arbeiten. Das Anwendungsprogramm muss also nicht auf die Ausgabe warten, sondern kann direkt die nächsten Daten an das Quartzplugin schicken. Zum anderen benötigt das GKSView zur Darstellung der Grafik immer die komplette 26 | Kapitel 3. Entwicklung des GKS Mac-Treibers
displayList. Das liegt an der Struktur einer Fensteranwendung. Jede Fensteranwendung wird durch eine Endlosschleife am Leben erhalten“. Ohne die ” Endlosschleife würde die Anwendung, wie jedes andere Programm, nur einmal durchlau- fen und sich dann beenden. Zudem wird durch die Endlosschleife das Eventhandling ermöglicht, dass, wie zu Anfang des Kapitels beschrieben, bei einer Fensteranwendung nötig ist. Das Verschieben eines Fensters auf dem Monitor zum Beispiel ist ein Event, auf das ein Fenster reagieren muss. Im Prinzip weist man dem Fenster bei einer Verschiebung oder Skalierung an, sich an der neuen Position oder in der neuen Größe neu darzustellen. Aus diesem Grund ist eine Zweiteilung des Mac Treibers nötig gewesen. Jede Implementierung einer NSView besitzt für das Eventhandling eine Callback Funk- tion. Diese Funktion muss dafür sorgen, dass die gesamte Ausgabe zu jeder Zeit neu gezeichnet werden kann. Die displayList wird aus diesem Grund bei jeder Änderung in einer Schleife komplett neu abgearbeitet. Die Abarbeitung der displayList läuft schematich ab. Jeder Eintrag beginnt mit der Anzahl der Bytes, die der Eintrag in der displayList belegt. displayList Anzahl Funktion Bytes ID Position 0 22 48 set color rep 22 49 set window 22 50 set viewport 42 15 Fill Area 1610 12 Poly Line 106 14 Text 360119 16 Cell Array Position 361943 ... 0 Abbildung 3.4: Aufbau einer displayList Das zweite Byte des Eintrags bestimmt die Funktion-ID der GKS-Funktion, die zur Bearbeitung der Daten verwendet werden soll. Anhand der Parameterliste der GKS- Funktion werden die restlichen Bytes des Eintrags aufgeteilt und an die Funktion über- geben. Die Postition des nächsten Eintrags wird über die Länge des vorherigen Eintrags be- stimmt. Die Schleife läuft solange, bis alle Daten in der displayList verarbeitet sind. Das Ende ist mit einer 0 kodiert. 3.3. Realisierung des Mac Treibers | 27
Die Ausgabe wird beendet, wenn mit dem Befehlt GKSQuartzCloseWindow das Fenster mit der zugehörigen GKSView geschlossen und die displayList gelöscht wurde. Abbildung 3.5 zeigt einen exemplarischen Ablauf der Verarbeitung. Server Plugin GKSTerm QuartzPlugin open workstation GKSQuartzCreateWindow NSWindow alloc window setContentView: GKSView return window_num activate workstion set color rep set window displayList set viewport fill area polyline update workstation GKSQuartzDraw: displayList : window_num GKSView with window_num copy displaList displayListCopy GKSView set_color_rep set color rep GKSView set_num_xform set window GKSView set_num_xform set viewport text GKSView fillarea fill area displayList cell array GKSView polyline polyline update workstation GKSQuartzDraw: displayList : window_num GKSView with window_num copy displaList GKSView set_color_rep set color rep GKSView set_num_xform set window GKSView set_num_xform set viewport GKSView fillarea fill area GKSView polyline polyline GKSView text text GKSView cellarray cell array deactivate workstation close workstation GKSView with window_num GKSQuartzCloseWindow : window_num GKSView close Window with window_num Window close Abbildung 3.5: Exemplarisches Ablaufdiagramm 28 | Kapitel 3. Entwicklung des GKS Mac-Treibers
3.4 Funktionen Im Folgenden werden die Funktionen näher erläutert, die im Mac-Treiber implementiert sind. Die Tabelle 3.1 zeigt Übersicht über die Funktionen, die ein GKS Treiber imple- mentieren muss. Die Funktionen 3.4.1 bis 3.4.4 sind im Quartz 2D Plugin realisiert. Die Funktionen 3.4.5 bis 3.4.23 gehören zum Mac Treiber GKSTerm“. Alle Funktionen, die ” nicht in der Tabelle 3.1 aufgelistet sind, haben keine Funktion-ID und gehören nicht zum Funktionsumfang des GKS. Es sind Hilfsfunktionen die von den GKS Funktionen verwendet werden. Bis auf die Funktionen gks set shadow und gks set transparency waren alle Funktionen im alten Mac Treiber implementiert und wurden in den neuen Treiber migriert. Tabelle 3.1: Implementierte Funktionen des Mac-Treibers Funktion-ID Bezeichnung Funktion 2 open workstation GKSQuartzCreateWindow 3 close workstation GKSQuartzCloseWindow 4 activate workstation (inline) 5 deactivate workstation (inline) 6 clear workstation clear ws 8 update workstation GKSQuartzDraw 12 polyline polyline 13 polymarker polymarker 14 text text 15 fill area fillarea 16 cell array cellarray 48 set color representation set color rep 49 set window (inline) 50 set viewport (inline) 53 set clipping indicator set clip rect Erweiterte GKS Funktionen 202 set shadow gks set shadow 203 set transparency gks set transparency 3.4.1 GKSQuartzCreateWindow Funktion-ID: 2 Übergabeparameter: keine Rückgabewert: num windows ; Integer Die Funktion gks quartz create window ist eine der drei Funktionen, die zur Kommu- nikation mit dem Quartz 2D-Plugin dienen. Sie ist die erste Funktion, die aufgeru- 3.4. Funktionen | 29
fen werden muss. Die Funktion erzeugt im Mac-Treiber für das Anwendungsprogramm ein Ausgabefenster. Als Rückgabewert wird die Identifikationsnummer an das Plugin übergeben. Mit der Identifikationsnummer kann das Plugin das zugehörige Fenster an- sprechen. Im Anschluss werden die Initialisierungsfunktionen init colors (Sektion 3.4.14) und init norm xform (Sektion 3.4.15) aufgerufen. Im Quartz 2D-Plugin wird der Buffer und die ws state list angelegt. 3.4.2 GKSQuartzCloseWindow Funktion-ID: 3 Übergabeparameter: win ; Integer Rückgabewert: keine Mit der Funktion gks quartz close window wird das Ausgabefenster geschlossen. Wenn das Anwendungsprogramm erneut zeichnen möchte, muss mit gks quartz create window (Sektion 3.4.1) erst ein neues Fenster angelegt werden. Diese Funktion ist wie gks quartz create window und gks quartz draw (Sektion 3.4.3) eine Funktion, die einen Befehl an den Mac-Treiber sendet. 3.4.3 GKSQuartzDraw Funktion-ID: 8 Übergabeparameter: 1. win; Integer 2. displayList; NSData Rückgabewert: keine Mit dieser Funktion wird der Buffer (displayList) an das Fenster mit der Nummer win gesendet. Im Ausgabefenster wird der Buffer ausgelesen und die Zeichenfunktionen auf- gerufen. 3.4.4 clear ws Funktion-ID: 6 Übergabeparameter: keine Rückgabewert: keine In dieser Funktion wird der Inhalt des Puffers (Display-Liste) für das aktuelle Fensters gelöscht. 30 | Kapitel 3. Entwicklung des GKS Mac-Treibers
3.4.5 cellarray Funktion-ID: 16 Übergabeparameter: 1. xmin; Float 2. xmax; Float 3. ymin; Float 4. ymax; Float 5. dx; Integer 6. dy; Integer 7. dimx; Integer 8. colia; Integer Pointer 9. true color; Integer Rückgabewert: keine Mit der Funktion cellarray wird in einer Fläche, die durch xmin, ymin, xmax, ymax eingegrenzt ist, eine Bitmap Grafik erzeugt. In dem colia Array (color integer array) werden die Bildinformationen als Farbwert pro Pixel übergeben. Mit dx und dy wird der Bereich des Bildes definiert, der in der cell array dargestellt werden soll. Hierbei kann der Bildausschnitt verzerrt werden, da die Anzahl der Pixel in der cell array nicht mit der Anzahl der Pixel des Bildes übereinstimmen können. 3.4.6 fillarea Funktion-ID: 15 Übergabeparameter: 1. n; Integer 2. px; Float Pointer 3. py; Float Pointer Rückgabewert: keine Eine fillarea ist eine Fläche, die durch eine geometrische Figur eingegrenzt ist. Diese Fläche kann mit einer Farbe oder mit einem Pattern ausgefüllt sein. Die Umrandung wird wie bei der polyline-Funktion (Sektion 3.4.7) durch Punkte erzeugt, die mit Linien verbunden werden. Die Koordinaten der Punkte werden als Argumente übergeben. Die Farbe bzw. das Pattern der Füllfläche wird in der gks state list t vom GKS festgelegt. 3.4.7 polyline Funktion-ID: 12 Übergabeparameter: 1. n; Integer 2. px; Float Pointer 3. py; Float Pointer 3.4. Funktionen | 31
Rückgabewert: keine Im alten Mac-Treiber gab es zwei Funktionen, die Linien zeichneten. Das lag daran, dass die QuickDraw-Funktion bei gestrichelten Linien Fehler verursachte. Eine Funktion war demnach für durchgezogene Linien und die andere Funktion emulierte die gestrichelten Linien mit Hilfsfunktionen. Der neue Mac-Treiber verwendet dafür nun die Quartz 2D-Funktion CGContextSetLi- neDash() [Dav06] , die mit einer Folge von Zahlen beliebige gestrichelte Linien erzeugen kann. Außerdem kann Quartz 2D einen Linienzug mit einer Funktion komplett abarbei- ten und muss nicht in einer Schleife jede Linie einzeln zeichnen. Die polyline Funktion erzeugt zu diesem Zweck aus den x- und y- Koordinaten, die als Array’s übergeben wer- den, ein Array von CGPoint-Strukturen, deren Koordinaten in das Koordinatensystem der Workstation umgerechnet werden. Anschließend wird die Linienbreite, die Linien- farbe und das Linienmuster, falls es sich um eine gestrichelte Linie handelt, festgelegt. Die Informationen zur Formatierung der Linien stehen in der gks state list. Wenn alle Einstellungen getätigt wurden, wird der Linienzug in den CGContext gezeichnet. 3.4.8 polymarker Funktion-ID: 13 Übergabeparameter: 1. n; Integer 2. px; Float Pointer 3. py; Float Pointer Rückgabewert: keine Die polymarker Funktion ist im Grunde nur eine Steuerfunktion. Hier wird der Typ und die Farbe des patterns festgelegt und dann in einer Schleife die Anfangspunkte der zu zeichnenden patterns an die Funktion draw marker (Sektion 3.4.10) übergeben. Die Anfangspunkte stehen als x− und y−Koordinaten in den Array’s px und py. 3.4.9 text Funktion-ID: 14 Übergabeparameter: 1. x; Float 2. y; Float 3. text; Char Pointer Rückgabewert: keine Die text Funktion erlaubt das Setzen von Texten an beliebiger Position. Als Ausgangs- punkt dient der linke, untere Punkt des ersten Zeichens. Die Richtung des Textes hängt von aktuellen Koordinatensystem ab. Führt der Text über den Rand des Viewports hinaus, wird der überstehende Teil einfach abgeschnitten. Für eine neue Zeile muss die Funktion von neuem aufgerufen werden. 32 | Kapitel 3. Entwicklung des GKS Mac-Treibers
Es stehen folgende Fonts zur Verfügung: • Times • Helvetica • Courier • Bookman Old Style • Century Schoolbook • Century Gothic • Book Antiqua • Symbol Der Font sowie die Zeichenhöhe stehen in der gks state list. 3.4.10 draw marker Funktion-ID: keine Übergabeparameter: 1. xn; Float 2. yn; Float 3. mtype; Integer 4. mscale; Float 5. mcolor; Integer 6. context; CGContextRef Rückgabewert: keine Die draw marker Funktion ist eine Hilfsfunktion, die von der polymarker Funktion ver- wendet wird. Die polymarker sind als relative Koordinaten in einem zwei-dimensionalem Array in der Funktion definiert. Die erste Dimension bestimmt den Typ des polymarkers. Es gibt insgesamt 26 verschiedene Typen. In der zweiten Dimension des Array’s stehen die Koordinaten, aus denen die polymarker gebildet werden. Die polymarker werden aus Linienzügen und Füllflächen erzeugt. 3.4.11 draw pattern Funktion-ID: keine Übergabeparameter: 1. index; Integer 2. shape; CGPathRef 3. context; CGContextRef 3.4. Funktionen | 33
Rückgabewert: keine Die draw pattern Funktion zeichnet in eine fill area (eingegränzte Fläche), hier als shape übergeben, ein vordefiniertes Muster (pattern). Die pattern sind in quadratischen Matri- zen als Bit-Kombination kodiert. Eine 1 kodiert einen schwarzen Bildpunkt, eine 0 ist ein transparenter Bildpunkt. Ein pattern wird mehrmals nebeneinander und untereinander gelegt bis die fill area mit dem Muster ausgefüllt ist. 3.4.12 gks set transparency Funktion-ID: 203 Übergabeparameter: alpha; Float Rückgabewert: keine Mit der Funktion gks set transparency wird ein globaler Alphawert gesetzt, der bei der Darstellung der Farben im RGBA-Farbraum den Grad der Transparenz angibt. 3.4.13 gks set shadow Funktion-ID: 202 Übergabeparameter: 1. offsetx; Float 2. offsety; Float 3. blur; Float Rückgabewert: keine Mit der Funktion gks set shadow werden die Schatteneffekte definiert. Schatten wer- den als graue Flächen dargestellt, die hinter den grafischen Objekten projiziert werden. Der Versatz des Schattens wird relativ zum zugehörigen Objekt angegeben. Negative Angaben der x - bzw. y-Werte bedeuten eine Verschiebung nach links bzw. nach un- ten, positive Werte analog nach rechts bzw. nach oben. Der blur -Faktor sorgt für einen Verwischungseffekt“ des Schattens, wie in Abbildung 3.6 zu sehen ist. ” 34 | Kapitel 3. Entwicklung des GKS Mac-Treibers
Abbildung 3.6: Darstellung von Schatteneffekten. Das Aktiviren der Schatteneffekte gilt, wie bei den Farben, für alle nachfolgenden grafischen Objekte. 3.4.14 init colors Funktion-ID: keine Übergabeparameter: keine Rückgabewert: keine Diese Funktion holt die Farbschemen aus dem GKS und leitet sie an die Funktion set color rep (Sektion 3.4.19) weiter. Sie wird nach der Erstellung einer Workstation aufgerufen. 3.4.15 init norm xform Funktion-ID: keine Übergabeparameter: keine Rückgabewert: keine Mit der init norm xform Funktion wird zu jedem Window des Anwendungsprogrammes eine Transformationsmatrix initialisiert, die die world coordinates des Windows in die normalized device coordinates des zugehörigen Viewports umrechnet. Die Umrechnung und Speicherung der Koeffizienten ist in der set norm xform Funktion (Sektion 3.4.21) realisiert. 3.4. Funktionen | 35
3.4.16 seg xform Funktion-ID: keine Übergabeparameter: 1. x; Float Pointer 2. y; Float Pointer Rückgabewert: keine Nach einer Transformation der world coordinates in die normalized device coordinates kann es vorkommen, das die Grafik noch gedreht werden muss. Dabei wird jede Koor- dinate einzeln im NDC-Space mit einer Drehmatrix gedreht. 3.4.17 seg xform rel Funktion-ID: keine Übergabeparameter: 1. x; Float Pointer 2. y; Float Pointer Rückgabewert: keine Wenn ein Ausgangspunkt einer Grafik mit der Funktion seg xform gedreht wurde und die nachfolgenden Angaben der Grafik in Abhängigkeit zu dem Ausgangspunkt gemacht werden, müssen diese Angaben ebenfalls neu ausgerichtet werden. Ein polymarker zum Beispiel wird durch feste Koordinaten relativ zum Ausgangspunkt bestimmt. Diese Ko- ordinaten werden mit der seg xform rel Funktion nach einer Drehung neu bestimmt. 3.4.18 set clip rect Funktion-ID: 53 Übergabeparameter: tnr; Integer Rückgabewert: keine Nach dem Aufruf der Funktion set clip rect werden bei der Transformation vom Window in den Viewport die überstehenden Bereiche am Rand des Viewports abgeschnitten. 3.4.19 set color rep Funktion-ID: 48 Übergabeparameter: 1. color; Integer 2. red; Float 3. green; Float 4. blue; Float 5. alpha; Float 36 | Kapitel 3. Entwicklung des GKS Mac-Treibers
Rückgabewert: keine Die Funktion set color rep initialisiert die Farbpalette der Workstation. Erzeugt werden die Farben mit der CGColorCreateGenericRGB -Funktion [Dav06] . Die Parameter red, green, blue und alpha werden einfach weitergeleitet und das Ergebnis in einem Array in der ws state list an Position color abgelegt. 3.4.20 set fill color Funktion-ID: keine Übergabeparameter: 1. color; Integer 2. context; CGContextRef Rückgabewert: keine Mit der Funktion set fill color wird die Farbe der Füllflächen gesetzt. Der Wert color bestimmt die Farbe, die in der Farbtabelle der ws state list hinterlegt ist. Dem CGCon- text der Workstation wird angewiesen, allen folgenden Füllflächen die ausgewählte Farbe zuzuweisen. 3.4.21 set norm xform Funktion-ID: 49 Übergabeparameter: 1. tnr; Integer 2. window; Float Pointer 3. viewport; Float Pointer Rückgabewert: keine set norm xform berechnet die Koeffizienten mit denen die world coordinates eines Win- dows der Anwendung in den zugehörigen Viewport im NDC-Space umgerechnet werden. 3.4.22 set stroke color Funktion-ID: keine Übergabeparameter: 1. color; Integer 2. context; CGContextRef Rückgabewert: keine Die Funktion set stroke color arbeitet analog zu set fill color nur das hier die Farbe der Linien bzw. der Umrandungen gesetzt wird. 3.4. Funktionen | 37
3.4.23 Inline-Funktionen Nicht alle Funktionen des GKS sind 1:1 umgesetzt. activate workstation Im Mac-Treiber wird mit dem Befehl activate workstation eine Variable in der workstation state list gesetzt, mit der abgefragt werden kann, ob die Workstation aktiv ist. deactivate workstation Mit deactivate workstation wird dementsprechend die Work- station deaktiviert. Diese beiden Funktionen werden benötigt, weil das GKS mehrere Workstations einem Anwendungsprogramm zuweisen kann. Es wird dann nur auf die aktiven Workstations zugegriffen. Die Anwendungen können so eine Ausgabe auf allen aktiven Workstations gleichzeitig ausgeben. Der Mac-Treiber unterstützt die Bearbeitung mehrerer Workstations pro Anwendung bisher noch nicht. set window set window wird verwendet, wenn die Anwendung ein neues Window defi- niert. Dazu werden mit der Funktion set norm xform (Sektion 3.4.21) die Trans- formationskoeffizienten des neuen Windows berechnet. set workstation set workstation wird aufgerufen, wenn sich eine Workstation zu ei- nem Window geändert hat. Hier müssen die Transfromationskoeffizienten mit der Funktion set norm xform (Sektion 3.4.21) neu berechnet werden. 38 | Kapitel 3. Entwicklung des GKS Mac-Treibers
Sie können auch lesen