ST-Ecke - ICON-Heiten: Piktogramme näher betrachtet

Eine der augenfälligsten Eigenheiten der Erscheinungsform der grafischen Oberfläche des ATARI ST sind seine Piktogramme, also Bilder, die bestimmte Funktionen darstellen. Diese Bilder, die wir ab sofort neudeutsch ICON (sprich eiken) nennen wollen, sind deshalb so beliebt, weil sie “ohne Worte" den Sinn bildhaft darstellen. Daher sind Programme, die in sinnvoller Anzahl mit Icons ausgestattet werden, meist sehr einfach zu bedienen -nicht umsonst sind oft Bedientableaus von CAD-Systemen mit Symbolen versehen. Dafür gibt es jetzt aber fast umsonst einen Icon-Editor als Sonderdisk - mit diesem und dessen Hintergrundwissen wollen wir uns ein wenig beschäftigen.

Ein kleiner Ausblick

Leider werden Icons auf dem ST ein wenig stiefmütterlich behandelt, was sicherlich in erster Linie daran liegt, daß zunächst überhaupt kein Icon-Editor vorlag. Ein halbes Jahr später erschien dann ein Programm, daß sich Icon-Editor ‘schimpfte’ und mit dem tatsächlich Bildchen gezeichnet werden konnten. Allerdings war diese Software eine Zumutung, denn die Zeit, die ein Benutzer des mit Icons versehenen Programms später einsparen sollte, mußte der Programmierer mehrfach in die Gestaltung des Icons hineinstecken, da dieser Editor kaum Möglichkeiten bot und auch noch viel zu langsam war - schlichtweg “zum Abgewöhnen". Auch heute liefert ATARI nur einen wenig brauchbaren Icon-Editor zum Entwicklungspaket mit. Dieses Manko fiel mir schon vor mehr als zwei Jahren auf, so daß ich damals begann (als eine Art Steckenpferd), meinen eigenen Icon-Editor zu entwickeln. Vor kurzem habe ich diesen zunächst einmal als abgeschlossen freigegeben, wobei es mir nicht darauf ankommt, Geld damit zu verdienen (die Zeit, mit Utilities Geld verdienen zu wollen, ist eh vorbei), sondern daß er eine möglichst große Verbreitung findet. Daher haben wir beschlossen, den Icon-Editor den Lesern unserer Zeitschrift als SONDERDISK anzubieten. Begleitend dazu möchte ich das Thema Icon (sowie Sprites, Mäuse und Füllmuster - dazu später mehr) mal wieder etwas auffrischen und konkret Applikationen liefern, wie die von dem Editor gelieferten Daten in ihren Programmen genutzt werden können. Als Ausgaben stehen die Daten für das Resource-Construction-Set (1.4 und 2.0) von ATARI sowie in C, Pascal und binärem Datenformat (geeignet zur Weiterverarbeitung von beliebigen Sprachen wie auch BASIC) zur Verfügung. Also kann es losgehen, oder?

Subjekt, Prädikat, Objekt...

Bild 1: Eine Dialogbox mit Icons

Nein, nein, lassen wir die weitere Vertiefung der deutschen Grammatik lieber außen vor, aber dennoch wollen wir uns mit dem Objekt und speziell mit einem Objekt in einer Dialogbox beschäftigen. Sicherlich ist dieses Thema schon oft genug beschrieben worden. Trotzdem möchte ich noch einmal kurz darauf eingehen: Eine Dialogbox besteht aus verschieden Teilen (Objekten) wie beispielsweise einer äußeren Box, ein paar (edierbaren) Texten, Tasten (Buttons) und auch Icons. Diese Objekte sind hierarchisch angeordnet. Dazu schauen Sie sich am besten Bild 1 an: Dort finden Sie eine Dialogbox, die zwei Boxen enthält. In diesen zwei Boxen findet man wiederum andere Objekte, wie hier beispielsweise in der linken Box Texte, in der mittleren Buttons (bleiben wir lieber bei dem englischen Wort für Tasten, was sich inzwischen eingebürgert hat) und in der rechten zwei Icons. Dabei kann man die Box 1 als Vaterobjekt (Mutterobjekt könnte man es natürlich auch nennen - es hat sich aber das aus dem englischen kommende ‘father objekt' verbreitet) der Boxen 2, 3 und 4 nennen, wobei die wiederum die Kinder (children) der Box 1 darstellen. Die Icons sind Kinder von Box 4, und Box 3 ist das Vaterobjekt der Buttons. Die Objekte haben auch noch eine gewisse Reihenfolge, so daß die Dialogbox in der richtigen Reihenfolge der Objekte gezeichnet werden kann (Genaueres findet man beispielsweise in ST-Computer 12/89 ‘ Submenüs - Und es geht doch...”, in den diversen ST-Ecken oder im ST-Computer Sonderheft 2). Zur Beschreibung eines Objektes existiert innerhalb des Speichers eine von Digital-Research vordefinierte OBJECT-Struktur (in Pascal RECORD), auf die das AES zugreift. Diese OBJECT-Struktur finden Sie in Listing 1, auf das wir kurz eingehen werden: Im ersten Eintrag steht der Verweis auf das folgende Objekt, so daß also ein Objekt mit dem nächsten verbunden ist und somit eine Kette gebildet wird - das letzte Objekt zeigt dann wieder auf den Vater(Start) zurück. Geschieht nun eine Verzweigung (Box 2 in Box 1), so handelt es sich um ein Kind des Objektes und den Start der “Kinderkette”. Die Nummer dieses Objektes (Box 2) wird in OB HEAD des Objektes BOX 1 als Startobjekt eingetragen. Box 2 wird auf Box 3, Box 3 auf Box 4 und Box 4 wieder auf Box 1 zeigen. Da Box 4 das letzte Kind ist, wird in OB TAIL des Vaterobjektes die Objektnummer von BOX 4 eingetragen. In OB TYPE finden wir die Art des Objektes, in OBFLAGS diverse Merkmale wie DEFAULT, EXIT etc. und in OB STATE den Status eines Objektes wie SELECTED, CROSSED etc. (siehe weiterführende Artikel). Die Ausmaße des Geltungsbereiches eines Objekts (meistens Umrandung bei BOXTEXT oder BOX) werden als x- und y-Koordinaten der linken oberen Ecke sowie der Breite und Höhe des Rechtecks in OBJ, OB J, OB WIDTH und OB HEIGHT angegeben. Der Eintrag OB SPEC ist abhängig vom Objekttyp und zeigt beispielsweise bei einem Text-String auf den Text.

ICON-artig

Kommen wir aber zurück zum Ausgangspunkt, dem ICON. Das Icon ist eines von 13 definierten Objektarten, die bei der Erstellung von Dialogboxen oder Menüs verwendet werden dürfen. Natürlich lassen sich in der OBJECT-Struktur nicht alle für das Icon notwendigen Daten unterbringen. Daher zeigt auch OB SPEC nicht wie bei einem Text-String auf einen Text, sondern auf eine weitere Struktur, die den Namen ICONBLK-Struktur trägt.

   typedef struct object      /* Offset zum Anfang */
   {                          /*        \ /        */
      int      ob_next;       /* 0 Nächstes Objekt */
      int      ob_head:       /* 2 erstes Kind (Kopf) */
      int      ob_tail;       /* 4 letzes Kind (Schwanz) */
      unsigned int ob_type;   /* 6 Objekttyp: Box, Icon, Text... */
      unsigned int ob_flags;  /* 8 Merkmale wie DEFAULT, EXIT ... */
      unsigned int ob_state;  /* 10 Status wie SELECTED, CROSSED... */
      char     *ob_spec;      /* 12 Zeiger auf besondere Erweiterung */
      int      ob_x;          /* 16 linke obere Ecke, X-Koordinate */
      int      ob_y;          /* 18 linke obere Ecke, Y-Koordinate */
      int      ob_width;      /* 20 Breite des Objekts */
      int      ob_height;     /* 22 Höhe des Objekts */
   } OBJECT:

Listing 1: Die OBJECT-Struktur eines Objektes

   typedef struct icon_block /* Offset zum Anfang */
   {                    /*             \ /        */
      int   *ib_pmask;  /* 0 Zeiger auf die Maskendaten */
      int   *ib_pdata;  /* 4 Zeiger auf die Bilddaten */
      char  *ib_ptext;  /* 8 Zeiger auf den Text des Icons */
      int   ib_char;    /* 12 Buchstabe des Icons, mit Farbe */
      int   ib_xchar;   /* 14 X-Position des Buchstabens */
      int   ib_ychar;   /* 16 Y-Position des Buchstabens */
      int   ib_xicon;   /* 18 X-Position des Icons */
      int   ib_yicon;   /* 20 Y-Position des Icons */
      int   ib_wicon;   /* 22 Breite des Icons */
      int   ib_hicon;   /* 24 Höhe des Icons */
      int   ib_xtext;   /* 26 X-Position des Textes */
      int   ib_ytext;   /* 28 Y-Position des Textes */
      int   ib_wtext;   /* 30 Breite der Textbox */
      int   ib_htext;   /* 32 Höhe der Textbox */
   } ICONBLK:

Listing 2: Die ICONBLK-Struktur eines Icons

Die Typ-Deklaration der ICONBLK-Struktur in C finden Sie in Listing 2. Entgegen der normalen Vorgehensweise möchte ich nicht mit dem ersten, sondern mit dem zweiten Eintrag beginnen, der einen Zeiger auf die Bilddaten des Icons darstellt. Diese Bilddaten sind bit-weise wie in der monochromen Auflösung beim ST abgespeichert. Dies funktioniert deshalb so einfach, da das Icon nur zweifarbig (Bit 0 oder 1) sein kann, wobei trotzdem dem Vordergrund (Bilddaten) und dem Hintergrund (Maske) eine beliebige Farbe zugeordnet werden (siehe weiter unten). Die Bilddaten sind byte- und zeilenweise abgespeichert. Daraus ergibt sich eine Blocklänge von Breite/8*Höhe, wobei die Breite auf das nächste Vielfache von acht aufgerundet wird. Da ein Icon an einer beliebigen Stelle postiert werden kann, könnte es auch teilweise über einem anderen Objekt liegen. Sind nun alle Punkte, die in den Bilddaten nicht gesetzt wurden, durchsichtig oder haben sie Hintergrundfarbe? Lösen wir das Geheimnis auf, zumal es die meisten wahrscheinlich schon von der Mausmaske kennen:

Ist an einer Stelle in den Bilddaten ein Punkt nicht gesetzt, und fehlt dieser Punkt auch in der Maske, ist diese Stelle durchsichtig. Wird in der Maske dieser Punkt gesetzt, erscheint er in der Masken-/Hintergrundfarbe. Damit kann man beispielsweise einen Rand um das Icon ziehen, damit es nicht direkt in den unter ihm liegenden Untergrund übergeht. Ein gutes Beispiel finden Sie in Bild 2, in dem eine Kamera als Icon zu sehen ist, bei der einmal die Maske verwendet und auf der anderen Seite weggelassen wurde. Der Aufbau der Maske ist wie der der Bilddaten, und die Adresse finden Sie im ICONBLK unter IB_PMASK. Praktisch ist, daß der Icon-Editor Ihnen die Erstellung der Maske teilweise abnehmen kann, in dem er bei Bedarf eine Maske generiert, die eine Umrandung der Bilddaten entspricht.

Farbiger Buchstabe...

Wenn Sie sich an die Icons auf dem Desktop erinnern, wissen Sie bestimmt, daß zu einem Icon auch ein Text (“Laufwerk”) und ein Buchstabe (A, B. C...) gehören. Einen Zeiger auf diesen Text finden Sie an der dritten Stelle des ICONBLKs (IB_PTEXT). Der Buchstabe ist im unteren Byte von IB CHAR zu finden. Richtig! Demnach muß im oberen Byte auch etwas versteckt sein. Teilen wir dieses Byte ein weiteres Mal in oberes und unteres Halb-Byte (Nibble), so werden wir im oberen Nibble die Vordergrund- und im unteren die Hintergrundfarbe finden, für die also jeweils vier Bit zur Verfügung stehen. Ein Icon muß also nicht schwarzweiß, sondern kann auch rot/grün sein. Ein kleiner Trick verhilft sogar zu drei Farben: An der Stelle, wo in der Maske und in den Bilddaten kein Punkt gesetzt ist, scheint der Hintergrund durch, der durch eine andersfarbige Box gebildet wird.

Relatives Icon

Als oben von den Koordinaten eines Objektes gesprochen wurde, ist noch nicht zur Sprache gekommen, daß diese Koordinaten immer relativ zum Vaterobjekt zu sehen und keine Absolutkoordinaten sind. Dies trifft natürlich auch für ein Icon zu. Allerdings fällt auf, daß es Koordinaten innerhalb der Objektstruktur (ob_x…) und innerhalb der Icon-Blockstruktur (ib_xicon,...) gibt. Was hat es damit auf sich? Zunächst sollten Sie sich die Koordinaten innerhalb der Objektstruktur als Box vorstellen, die das Icon umgibt. Diese Box kann man sogar sichtbar machen, indem man dem Icon den Status OUTLINED in ob_state gibt. Diese Box ist relativ zum Vaterobjekt, wobei die Koordinaten in der Icon-Blockstruktur die relative Position des Icons bezüglich dieser Box angeben. Zunächst mag man den Sinn dieser zusätzlichen Möglichkeit nicht einsehen. Es wird allerdings verständlicher, wenn man weiß, daß die Objektbox, die durch die Koordinaten in der Objektstruktur gebildet wird, den Wirkungsbereich des Icons angibt. Das bedeutet, daß man einen großen Bereich um das Icon anhand dieser Box setzen kann, obwohl ein Icon relativ klein sein kann. Es füllt sich auch dann angesprochen, wenn der Benutzer ein wenig nebendran klickt. Normalerweise würde nun aber das Icon in der linken oberen Ecke der Box kleben (natürlich hätte man auch eine automatische Zentrierung einbauen können), was durch die Koordinaten in der Icon-Blockstruktur ‘zurechtgerückt' werden kann. In Bild 3 erkennt man dies ganz gut, da hier die Box des Icons durch outlined hervorgehoben wurde. Im rechten Beispiel würde ein Anklicken des Icons kein Ereignis hervorrufen, da sich das Icon selbst nicht innerhalb des Wirkungsbereichs befindet. Vielleicht ist dem ein oder anderen Leser in Bild 3 aufgefallen, daß der Text in bezug auf das Bild des Icons nicht immer an dergleichen Stelle steht. Dies kann man durch Verändern der Textkoordinaten IB_XTEXT und IB_YTEXT erreichen. Auch die Größe der Textbox ist veränderbar, so daß sie viel größer als der eigentliche Text sein kann. Interessant ist. daß die Textboxkoordinaten relativ zur Objektbox sind, während die Koordinaten des Buchstabens (IB_XCHAR und IB_YCHAR) relativ zum Icon verwaltet werden. In der Praxis bedeutet dies, daß ein Verschieben des Objektes den gesamten Inhalt (Icon, Buchstabe. Bild) verursacht, während ein Ändern der Icon-Bildkoordinaten auch ein Verschieben des Buchstabens zur Folge hat. Diese Eigenschaft ist recht praktisch: Stellen Sie sich vor. Sie haben ein Icon gezeichnet, das eine Diskettenstation darstellt, und haben innerhalb des Bildes den Laufwerksbuchstaben postiert. Verschieben Sie nun das Icon innerhalb der Objektumrandung, wandert der Buchstabe automatisch mit und bleibt innerhalb des Bildes an der richtigen Stelle. Beachten Sie aber, daß dabei die Textposition nicht verändert wird. Die Höhe und Breite des Icons werden in IB_WICON und IB_HICON angegeben, wobei zu beachten ist, daß die Breite ein Vielfaches von acht betragen sollte.

ICON-sinnig

An dieser Stelle können wir also zusammenfassen, daß es sich bei einem Icon um ein Objekt handelt, das ein Bild, einen Buchstaben und einen Text enthält, die alle relativ zu einer Umrandung positionierbar sind. Diese Umrandung gibt den Wirkungsbereich des Icons an, so daß das Icon im allgemeinen innerhalb des Bereich sein sollte. Wie jedem Objekt kann man auch einem Icon einen Status (ob_status) und Merkmale (ob_flags) zuordnen. Selten wird dabei die Möglichkeit der Darstellung des Wirkungsbereiches durch outlined verwendet, was aber sinnvoll sein könnte. Bis auf EDITABLE (ein Icon-Text ist genauso wenig edierbar wie ein normales STRING-Objekt!) können alle Einstellungen also auch beispielsweise CROSSED oder CHECKED verwendet werden.

Bild 2: Die Wirkung der Maske

Die ICON-tliche Anwendung

Was bringt uns ein neuer und toller Icon-Editor, wenn wir die Daten nicht auch weiterverarbeiten können? Zu diesem Zweck habe ich sehr umfangreiche Ausgaben in den Icon-Editor implementiert. Zunächst können Sie das Icon so ausgeben, daß Sie es später mit dem Resource Construction Set von ATARI (1.4 oder 2.0) wieder laden können. Dazu klicken Sie vor dem Abspeichern im Icon-Editor unter OPTIONEN den Punkt RCS-AUSGABE an. Speichern Sie nun das erstellte Icon, werden drei Dateien erstellt: Zunächst die Icon-Editor-spezifische Datei mit dem Extender DAT (siehe Datenformat und Anwendung unten); danach erstellt der Editor die RCS-Dateien. Das RCS erwartet für die Maske und die Bilddaten zwei getrennte Dateien, die beide den Extender ICN haben sollten, da dieser beim Laden eines Icons im RCS automatisch vorgegeben wird. Deshalb wird als weiteres Unterscheidungsmerkmal in der letzten Stelle des Namens ein D für DATA oder M für Mask untergebracht. Daher sollte der Name eines Icon auch nicht länger als sieben Buchstaben sein. Das Laden eines Icons aus dem RCS geschieht nun folgendermaßen: Ziehen Sie zunächst ein vorgegebenes Icon wie ein normales Objekt in Ihre Dialogbox (oder zu erstellende Menüleiste). Danach selektieren Sie es, indem Sie mit der Maus einmal draufklicken (es sollte dadurch invertiert werden...). Wenn Sie nun in der Menüzeile des RCS nachschauen, ist ein Punkt LOAD selektierbar gemacht worden, der von Ihnen auch angeklickt wird. Daraufhin erscheint zweimal hintereinander eine Fileselektorbox. In der ersten Fileselektorbox wird der Name der Icon-Bilddaten- und in der zweiten der Name der Icon-Maskendatei angegeben. Wenn Sie alles richtig gemacht haben, finden Sie Ihr geladenes Icon innerhalb der Dialogbox (oder Menüzeile) wieder. Danach können Sie dieses Icon wie andere Objekte bezüglich des Status' und der Merkmale (fast) beliebig verändern (kein EDITABLE!). Leider ermöglichen die RCS' von ATARI, mit denen es möglich ist, ein Icon zu laden, keine großartigen Verschiebungen des Icons, des Textes und des Buchstabens - nur ein paar vordefinierte Positionen für die Positionierung des Textes und des Buchstabens sind möglich, während das Icon immer in der linken oberen Ecke ‘klebt’. Schade ist es auch, daß man dem RCS keine weiteren Daten als die reinen Bild- und Maskendaten übermitteln kann. Trotzdem bietet der Icon-Editor ein Verschieben aller Teile sowie die Eingabe eines Textes und Zeichens, die zu einem Icon gehören. Diese Daten werden in einer Weise abgespeichert, die zwar nicht von einem RCS, aber sehr einfach von einem selbstgeschriebenen Programm genutzt werden. Alles, was sie dazu brauchen, finden Sie in Listing 3.

Um die Handhabung der selbsterstellten Icons möglichst einfach zu machen, habe ich zwei Routinen programmiert. Die erste Routine ist in der Lage, ein Icon von Disk zu laden und dies an eine bestimmte Stelle innerhalb eines Objektbaums zu setzen. Dazu kreiert man sich die Dialogbox mit dem Standard-Icon innerhalb des RCS und gibt ihm einen Namen (in unserem Beispiel schlichtweg ICON). Beim Starten wird mit ins_icon(dateiname, dialogboxadresse,ICON) das zu ladende Icon an die Stelle des Standard-Icons gesetzt. Dabei werden alle Einstellungen (ICON-Position, Objekt- und Textboxgröße, Farben. Text. Buchstaben...), die Sie im Icon-Editor gemacht haben, automatisch übernommen! Außerdem wird auch der entsprechende Speicherplatz für die Daten vom Betriebssystem angefordert. Wenn Sie möchten, können Sie die Routine auch so umschreiben, daß nicht für jedes Teil (Bilddaten. Maskendaten. Icon-Blockstruktur. String) eine getrennte Speicheranforderung gemacht wird [ändern sie dann aber auch clr_icn()]. Wenn Sie später Ihr Programm beenden, sollten Sie mit clr_icn(ICON) (ICON ist wie oben der Beispielname) den reservierten Speicherbereich wieder freigeben. Wenn Sie nun beispielsweise in einem Feld die Dateinamen und die zugehörigen Objekte abspeichern, läßt sich sehr einfach in einer Schleife eine Vielzahl von Icons einiesen und in die Baumstruktur der Dialogbox einfügen.

Der Vollständigkeit halber möchte ich noch das Dateiformat angeben, was auch in ins_icn() abgelesen werden kann. Am Anfang steht der ICONBLK des erstellten Icons, der vollständig übernommen werden kann. Danach finden wir die Objektstruktur des Icons, wie Sie im Icon-Editor vorliegt. Hieraus verwenden wir nur die Koordinaten sowie die Flags und den Status - die Objektverknüpfungen übernehmen wir natürlich nicht. Danach folgen die Daten für die Maske und das Icon-Bild (in dieser Reihenfolge) und dann der Text-String, der nach schöner C-Manier mit einer Null abgeschlossen ist.

Anfangs habe ich mir überlegt ein eventuell noch kompakteres Format zum Abspeichern zu wählen, allerdings ist das AES bis auf Kleinigkeiten schon so kompakt, daß es wenig zu verbessern gäbe. Außerdem hat man so die Möglichkeit, sehr einfach die erstellten Icons in eigene Programme einzubinden. Es wäre zu überlegen, ob man sich ein Programm schreibt, daß mehrere Icons zu einer Datei zusammenfügt (vielleicht zum Wiederfinden mit einem internen Namensverzeichnis) und ins_icn() entsprechend umschreibt. Toben Sie sich am besten ein wenig aus, und wenn Sie ein gutes Hilfsprogramm geschrieben haben und uns schicken, könnten Sie es eventuell in Zukunft auf der Icon-Editor-Sonderdisk finden.

Das nächste Mal

Mit diesem Dateiformat ist es natürlich auch sehr einfach möglich, die Icons aus BASIC heraus zu verwenden. Ein Beispiel dazu (prinzipiell ist dies die Umsetzung von Listing 3 in BASIC) finden Sie in der nächsten ST-Ecke. Dann werden wir uns mit den weiteren Möglichkeiten des Icon-Editors beschäftigen, mit dem auch Sprites, Mausbilder und Füllmuster erstellt werden können. Diese können dann als Quelltexte in PASCAL (Modula-Leute hergehört) oder C ausgegeben und damit sehr einfach in den Quelltext eingebunden werden. Man gestatte mir eine kleine Anmerkung zum Schluß: Icon mit IKONE zu übersetzen, halte ich nicht für sinnvoll; auch wenn sie noch so schön sind, göttlich sind sie bestimmt nicht...

SH

Bild 3: Der Wirkungsbereich eines Icons
#include <obdefs.h>
#include <osbind.h>
#include "insicn.h"

main ()
{
   int x,y,w,h;
   long baum;        /* Anfangsadresse d.Dialogbox-ObjektStruktur */
   long ins_icn();   /* ICON-Einfiigeroutine */

   appl_init();      /* bei AES anmelden */

   if (!rsrc_load("insicn.rsc"))    /* Demo-RSC-Datei laden */
   {                                /* hat nicht funktioniert */
      appl_exit();                  /* bei AES abmelden */
      return(0);                    /* Programm verlassen */
   }
   rsrc_gaddr(0,BAUM,&baum);        /* Adresse der Dialogbox */

   if (ins_icn("test.dat",baum,ICON)==-1L) /* Einfügen des ICONs */
      return (-1);                         /* Bei Fehler -> Abbruch */

   form_center(baum,&x,&y,&w,&h);            /* Box zentrieren */
   objc_draw(baum,0,MAX_DEPTH,x,y,x+w,y+h);  /* zeichnen */ 
   form_do(baum,0);                          /* Bearbeiten */

   clr_icn(baum,ICON);              /* Icon wieder löschen */
   
   appl_exit();                     /* Applikation abmelden */
}

long ins_icn(name,tree,ob_index)    /* Einfügeroutine für Icons */
char *name;                         /* Dateiname des Icons */
long tree;                          /* Baumstrukturadresse */
int ob_index;                       /* Objektnummer */
{
   int fd,i=-1;
   ICONBLK *icon;
   OBJECT obj, *ob;
   int *data, *mask;
   long block_size;
   char strin[30], *string;

   /* Speicherbereich in Größe eines ICONBLKs reservieren */ 
   icon= (ICONBLK*) Malloc((long)sizeof(ICONBLK)); 
   if (!icon)
      return(-1L);      /* Nicht genug Speicher frei -> zurück */

   fd= Fopen(name,0);   /* Datei öffnen */

   Fread(fd,(long)sizeof(ICONBLK),icon); /* ICONBLK lesen */
   Fread(fd,(long)sizeof(OBJECT),&obj);  /* OBJECT-Strukur lesen */
   /* Ermitteln der Größe der Datenmenge von DATA und MASKE */ 
   block_size = (icon->ib_wicon)/8*(icon->ib_hicon);
   mask= (int*) Malloc(block_size); /* Maskenspeicher reservieren */

   if (!mask)        /* kein Speicher frei */
   {
      Mfree(icon);   /* anderen Speicher wieder freigeben */
      return(-1L);   /* zurück */
   }
   data= (int*) Malloc(block_size); /* Speicher für Bilddaten */ 
   if (!data)        /* Genug Speicher da? */
   {
      Mfree(icon);   /* Nein, vorher reservierten */
      Mfree(mask);   /* Speicher wieder freigeben */
      return(-1L);
   }
   Fread(fd,block_size,mask); /* Lesen von Maske und Bild */
   Fread (fd,block_size,data);

   do                /* Icon-String einlesen */
   {
      i++;
      Fread(fd,1L,&strin[i]);
   }while (strin[i));               /* I = Länge des Strings */
   string= (char*) Malloc((long)i); /* Speicher reservieren */

   if (!string)      /* Speicher da? */
   {
      Mfree(icon);   /* Nein */
      Mfree(mask);   /* Speicher */
      Mfree(data);   /* freigeben */
      return(-1L);
   }
   strcpy(string,strin); /* String in Speicher kopieren */

   Fclose(fd); /* Datei schließen */

   ob= (OBJECT*) (tree+24*ob__index);  /* Adresse des Objekts */ 
   ob->ob_spec= (char*) icon;          /* ICONBLK eintragen */
   ob->ob_width = obj.ob_width;        /* Objektumrandung */
   ob->ob_height = obj.ob_height;      /* aus geladener OBJECT- */
   ob->ob_state = obj.ob_state;        /* Struktur übernehmen */
   ob->ob_flags = obj.ob_flags;
   icon->ib_pmask= mask;               /* Maskendaten eintragen */
   icon->ib_pdata= data;               /* Bilddaten eintragen */
   icon->ib_ptext= string;             /* String eintragen */

   return((long)icon);  /* Adresse auf Iconblk zurückgeben */
}

clr_icn(tree,ob_index)  /* Löscht alle reservierten Speicher */
long tree;              /* ACHTUNG: restauriert OBJEKT nicht!! */
int ob_index;           /* Danach kein Aufruf des Objektes mehr1 */
{
   ICONBLK *icon;       /* Zeiger auf Iconblk */
   OBJECT *obj;         /* Zeiger auf Objekt */

   obj= (OBJECT*) (tree+24*ob_index);  /* Objektadresse */
   icon= (ICONBLK*) obj->ob_spec;      /* ICONBLK- Adresse */
   Mfree(icon->ib_pmask);  /* Maskenspeicher freigeben */
   Mfree(icon->ib_pdata);  /* Bilddaten freigeben */
   Mfree(icon->ib_ptext);  /* String freigeben */
   Mfree(icon);            /* ICONBLK freigeben */
}

Listing 3: Das Laden und Einfügen eines Icons



Aus: ST-Computer 01 / 1990, Seite 100

Links

Copyright-Bestimmungen: siehe Über diese Seite