Pagina didattica di G. Servizi
Home >> Documentazione


manuale d'uso della libreria passe_par_tout

PASSE_PAR_TOUT

passe_par_tout è il nome della libreria grafica richiamabile da programmi scritti sia in FORTRAN sia in C sia in C++ e che funziona senza modifiche su qualsiasi server X11 ovvero, limitatamente alle funzioni PostScript, su qualsiasi sistema provvisto di un compilatore C o C++ (e quindi meritevole di essere usato). Il presente documento è strutturato nei seguenti capitoli:





























































































Versione corrente

La presente documentazione descrive la libreria come disponibile qui alla data del

19 marzo 2019

Qualsiasi versione rilasciata in data anteriore può non essere del tutto conforme alla documentazione e/o contenere difetti non ancora segnalati.

torna daccapo



























































































Generalità sulla libreria

Sono in vigore le clausole generali seguenti:

                     character*12 pippo
                     integer*2 ipippo(6)
                     equivalence (pippo(1:1), ipippo(1))
                           .
                     pippo = 'pippo '
                     pippo(12:12) = char(0) ! ESSENZIALE
                           .
                     call .... (..., ...., ipippo, ..... )
                              .

A ogni buon conto la libreria contiene due funzioni, utilizzabili stavolta SOLO COME FUNCTIONS, che si incaricano della conversione (vedere funzioni m_conv_string e m_conv_chars); Un modo alternativo di fornire alla libreria stringhe di caratteri consiste nell'utilizzare vettori di singoli caratteri anziché vere e proprie stringhe. In altre parole la stringa pippo andrebbe dichiarata in FORTRAN con il seguente procedimento:

                    character pippo(6)
                    pippo(1) = 'p'
                    pippo(2) = 'i'
                    pippo(3) = 'p'
                    pippo(4) = 'p'
                    pippo(5) = 'o'
                    pippo(6) = char(0)


Si noti il valore OBBLIGATORIO di pippo(6). Con questo procedimento l'array pippo può essere fornito alla libreria senza bisogno né di arrays INTEGER*2, né di istruzioni EQUIVALENCE né di chiamate alle citate funzioni di conversione.

Tutto il contenuto grafico e tutti i parametri caratteristici di ogni finestra sono completamente indipendenti da quelli delle altre finestre, eccetto le dimensioni in pixels che sono (per default) uguali per tutte e sono fissate all'inizio dalla funzione m_startg. È comunque possibile attribuire dimensioni diverse ad ogni finestra lavorando opportunamente con la funzione m_window.

Il contenuto di ogni finestra può essere "rinfrescato" in ogni momento (cfr. m_wait_for_events, m_loop_for_events) in modo che va perduto solo alla fine del programma e/o alla chiusura della finestra (cfr. m_close).

Per effettuare il "rinfresco" la libreria memorizza tutto l'output grafico indirizzato a ogni singola finestra come una successione di "tokens": il numero di tokens mantenuto in memoria per ogni finestra cresce indefinitamente al crescere della quantità di output generato: nessun controllo è compiuto in proposito salvo l'invio su standard output di un messaggio di avvertimento quando si oltrepassa una soglia superiore a ogni ragionevolezza (60000 = sessantamila).

Un discorso diverso concerne le finestre utilizzate come contenitori di pixmaps, per le quali la libreria conserva in memoria la relativa pixmap (cfr. m_use_as_pixmap). In questo caso la quantità di memoria utilizzata per la finestra è fissa, indipendentemente dalla complessità del disegno prodotto. La scelta tra l'uso di finestre "normali" e finestre "pixmap" dipende per l'appunto dalla natura del disegno che occorre fare: per grafici di funzioni con un numero relativamente basso di segmenti sono preferibili le finestre "normali"; per plot di fase e per ogni disegno di grandissima complessità (tra cui, a maggior ragione, le animazioni) sono da preferire le pixmap.

torna daccapo













































































Uso di display multipli

Si tratta di un'estensione introdotta nel novembre 2007 e che, alla data in cui sono scritte queste note, è da considerare una beta-versione che attende di essere sperimentata per poterne convalidare l'efficienza. Consente a un'unica applicazione la gestione simultanea di numerosi server interconnessi via rete e accessibili l'uno all'altro, permettendo la realizzazione di programmi utili sia al lavoro (simulazioni grafiche multiple e interattive) sia al divertimento (giochi interattivi di ogni genere).

torna daccapo













































































Il widget set di passe_par_tout

Introdotto nel giugno 2016 consiste in una famiglia di funzioni dedicate alla creazione di finestre che consentano la gestione di menu interattivi, sul modello di altre librerie grafiche di ampia diffusione. Niente di più di quanto qualsiasi programmatore men che sprovveduto avrebbe potuto fare da sé usando con un minimo di acume quanto la libreria ha sempre messo a disposizione dei suoi utenti.
Le funzioni che fanno parte di questa sezione della libreria sono:

m_refreshmenu
m_menu
m_widget_loop
m_manage_button
m_set_textfield_button
m_get_textfield_button
m_get_button_status
m_change_ptr
m_change_sectors

Contestualmente è stata creata la struttura Bottone, della cui definizione completa l'utilizzatore finale della libreria non ha alcun bisogno di preoccuparsi (per conservare una minima compatibilità coi programmi scritti in FORTRAN), le cui istanze sono lo strumento fondamentale per la gestione interattiva. Allo stato attuale dello sviluppo le istanze di Bottone sono di nove tipi distinti, per ciascuno dei quali è stata definita una costante opportuna, al livello del preprocessore:

  1. bottoni cursori: (#define BOTTONE_SCORREVOLE -1)

  2. bottoni attivatori: (#define BOTTONE_ATTIVATORE 0)

  3. bottoni interruttori: (#define BOTTONE_INTERRUTTORE 1)

  4. bottoni selettori: (#define BOTTONE_SELETTORE 2)

  5. bottoni multiselettori: (#define BOTTONE_MULTISELETTORE 3)

  6. bottoni output: (#define BOTTONE_TEXTFIELD 4)

  7. bottoni input floating: (#define BOTTONE_INPUT_FLOAT 5)

  8. bottoni input interi: (#define BOTTONE_INPUT_INT 6)

  9. bottoni input stringhe: (#define BOTTONE_INPUT_CHARS 7)

I valori espliciti delle citate costanti possono essere usati, nel rispetto delle regole generali della libreria, al posto dei loro nomi rappresentativi.
La semantica di ciascun tipo di bottone è descritta nelle istruzioni d'uso delle singole funzioni, in particolare in quelle relative alla funzione m_menu.

torna daccapo













































































m_get_button_status(finestra, bottone)

Gli argomenti di questa funzione hanno lo stesso significato e lo stesso tipo descritti in m_manage_button, ma, diversamente da altre funzioni della libreria che restituiscono valori interi, questa restituisce, in un puntatore a char, l'indirizzo della variabile interna alla struttura del bottone, individuato dagli argomenti ricevuti, in cui è mantenuto lo stato, attivato o non attivato, del bottone medesimo.
Utile, ad esempio, per pilotare l'attivazione e la disattivazione di bottoni attraverso bottoni interruttori della stessa interfaccia, come mostrato in uno dei programmi esempio forniti come corredo della documentazione relativa alla funzione m_menu.
Qualsiasi valore dei parametri trasmessi sia fuori intervallo di validità risolve l'esecuzione di questa funzione in "nessuna operazione".

torna a widget set
torna daccapo













































































m_change_ptr(finestra, bottone, pulsante, ptr)

I primi due argomenti di questa funzione hanno lo stesso significato e lo stesso tipo di quelli descritti in m_manage_button. Il terzo argomento ha lo stesso tipo dei primi due, ma il valore puntato deve essere 0 oppure 1 oppure 2 secondo quale pulsante del mouse risulta coinvolto: rispettivamente il sinistro o il centrale o il destro.
L'ultimo argomento è un puntatore a void, ossia lo stesso tipo dei contenuti all'ultimo livello di puntamento nell'ultimo argomento ricevuto da m_menu. La funzione sostituisce appunto con ptr, in qualsiasi momento dell'esecuzione del programma venga invocata, il valore corrente del puntatore a void attualmente detenuto dal bottone individuato dai primi due argomenti e relativo al pulsante di mouse individuato dal terzo argomento.
Qualsiasi valore dei parametri trasmessi sia fuori intervallo di validità risolve l'esecuzione di questa funzione in "nessuna operazione"; peraltro il puntatore ptr trasmesso può tranquillamente essere anche il puntatore nullo.
Esempi d'uso forniti in m_menu.

torna a widget set
torna daccapo













































































m_change_sectors(finestra, bottone, settori)

I primi due argomenti di questa funzione hanno lo stesso significato e lo stesso tipo di quelli descritti in m_manage_button, ma in questo caso il bottone individuato deve essere di tipo selettore o multiselettore, altrimenti la funzione si risolve in "nessuna operazione", esattamente come accadrebbe se si fornissero valori fuori intervallo.
Se il bottone individuato è di tipo congruo, allora il terzo argomento, di tipo puntatore a puntatori a double/REAL*8, viene utilizzato per sostituire il valore corrente del dominio di selezione del bottone stesso.
Precisamente, se il bottone è un selettore l'argomento settori DEVE PUNTARE TRE puntatori a double/REAL*8 di cui il terzo DEVE ESSERE il puntatore nullo. I primi due puntatori DEVONO, a loro volta, puntare ciascuno un solo valore double/REAL*8, in ordine crescente, che saranno usati come nuovi minimo e massimo del dominio di selezione del bottone.
Se invece il bottone è un multiselettore l'argomento settori DEVE PUNTARE un numero arbitrario N > 3 di puntatori a double/REAL*8, l'ultimo dei quali deve ancora essere il puntatore nullo; i precedenti N-1 puntatori devono ancora una volta puntare ciascuno un singolo valore double/REAL*8, in ordine. Essi sostituiranno i punti di transizione del dominio di selezione del bottone, e l'ultimo dei valori puntati fungerà da fondo scala per il multiselettore.
Esempi d'uso forniti in m_menu.

torna a widget set
torna daccapo













































































m_menu(loc, tit, col, b, lab, val, p(void *, void *), v)

m_refreshmenu(finestra)


La seconda funzione è necessaria davvero raramente, ossia quando si verifichino desincronizzazioni nella ridisegnatura delle finestre dovute a time out o data races in programmi a threads multipli. Serve appunto a forzare la ridisegnatura della finestra-menu il cui indice si trova nell'argomento ricevuto, di tipo puntatore a int/INTEGER*4.

La prima funzione, invece, è il fondamento del widget set dato che crea e realizza sullo schermo una finestra dedicata a supportarne l'interfaccia con la libreria: la finestra creata si inserisce nella cronologia normale di tutte le altre finestre, acquisendo l'indice che le compete e che viene restituito al chiamante come valore di ritorno, come fa m_window; su finestre generate da questa funzione non è tuttavia accessibile alcuna forma di disegnatura: ogni funzione che tentasse di farlo viene cortocircuitata su "nessuna operazione". Contestualmente all'introduzione nella libreria delle funzioni del widget set il numero massimo di finestre gestibili da un unico programma sullo stesso display è stato raddoppiato e portato a 32, di modo che, TEORICAMENTE, ciascuna finestra ordinaria potrebbe essere affiancata da una propria finestra menu. È tuttavia evidente che un programmatore che non dorma dovrebbe poter essere in grado di gestire anche il più complicato programma grafico con UNA SOLA di tali finestre, visto quanto ci si accinge a descrivere e tentare di spiegare.

I primi due argomenti sono trasmessi, PARI PARI, nello stesso ordine, alla funzione m_place_window di questa stessa libreria e hanno quindi tipo e significato descritti colà; va solo osservato che, per l'uso che qui ne viene fatto, l'argomento loc deve puntare valori non negativi, senza che questa funzione lo controlli in alcun modo.

Il terzo argomento, col, di tipo puntatore a int/INTEGER*4, indica su quante colonne vanno distribuiti i bottoni che dovranno essere inseriti nella finestra e quale dimensione orizzontale debbano avere: in particolare il numero EFFETTIVO di colonne è dato dal VALORE ASSOLUTO di questo argomento, con la convenzione che, se il segno è positivo, le dimensioni di OGNI bottone debbano essere fornite individualmente mentre col segno negativo le si lascia calcolare alla funzione stessa in base alla larghezza delle etichette fornite (cfr. appresso). Lo stesso effetto si ottiene se il valore puntato è zero (0), che viene trattato esattamente alla stessa stregua di -1. In ogni caso le dimensioni esterne della finestra sono autodeterminate da questa funzione in modo tale da potervi inserire tutti i bottoni richiesti in modo conveniente e, possibilmente, gradevole e lo sfondo della finestra è sempre NERO (almeno nella versione attuale). I bottoni sono inseriti nell'ordine in cui sono forniti (cfr. appresso) partendo dall'alto a sinistra: il numero di righe su cui sono distribuiti è autodeterminato dalla funzione partendo dal numero totale e da quello delle colonne. Non vi è un limite superiore al numero di bottoni oltre alla propria ragionevolezza; tuttavia se non si fornissero funzioni di callback e si pretendesse di utilizzare l'interfaccia nella sua forma "semplificata", descritta appresso, NON SI DOVREBBE POI PRETENDERE ANCHE DI INSERIRE NEL MENU PIÙ DI 100 (CENTO) BOTTONI (addio ragionevolezza), pena il verificarsi di malfunzionamenti FUORI CONTROLLO.

L'argomento b (il quarto) deve essere un puntatore a puntatore a int/INTEGER*4 dal cui contenuto la funzione arguisce il numero totale di bottoni da inserire nella finestra, come si è già anticipato che debba poter avvenire: precisamente il numero di bottoni è dato da quello dei puntatori NON NULLI puntati da b PRIMA di un puntatore NULLO finale, obbligatorio (i fortranisti si ARRANGINO su come identificare un puntatore nullo). Ognuno di tali puntatori NON NULLI deve a sua volta puntare 7 (sette) valori interi il cui significato è il seguente:


L'argomento lab (il quinto) serve a specificare le etichette da scrivere, nel primo colore di contrasto, al centro di ciascun bottone e, come tale, deve essere un oggetto della stessa natura del secondo argomento della funzione main, ossia un puntatore a puntatori a carattere BEN TERMINATI, uno per ogni bottone.
NESSUN CONTROLLO viene compiuto sulla presenza, in questo argomento, di puntatori nulli che provocherebbero errori di accesso con probabilità 5: se si vuole lasciare un bottone SENZA etichetta non si inserisca in lab un puntatore nullo nella posizione competente a quel bottone, MA PIUTTOSTO un puntatore che punti la stringa di lunghezza nulla ("\0").
Una parola in più va detta sull'etichetta da apporre a un bottone interruttore: se nel valore puntato dal corrispondente puntatore in lab è presente il codice ASCII 1 questo, o meglio la sua prima occorrenza, divide la stringa in due parti, quella a sinistra e quella a destra di quel carattere, e queste due parti saranno visualizzate ALTERNATIVAMENTE a ogni click sul bottone, cominciando con la visualizzazione della parte a sinistra. Ciascuno faccia di questa possibilità l'uso che ritiene più opportuno.

L'argomento val (il sesto) deve essere un puntatore a puntatori a puntatori a double/REAL*8, vale a dire, per chi conosce il C++, un puntatore con 3 (TRE) asterischi; per i fortranisti deve essere un array a tre dimensioni, con tutte le cautele nascoste nella cervellotica convenzione CONTRONATURA riguardante l'allineamento adottata da tale linguaggio. Assumendo senz'altro la convenzione del C/C++ in questa documentazione, al livello di puntamento più esterno occorre che siano puntati tanti puntatori a 2 (DUE) asterischi quanti sono i bottoni, ma in questo caso si possono inserire tranquillamente puntatori a 2 asterischi NULLI in corrispondenza di bottoni di tipo DIVERSO da quello dei bottoni selettori, multiselettori e cursori. Al limite estremo, se nella finestra non venisse richiesto ALCUN BOTTONE di tali tipi, l'intero puntatore a 3 asterischi val potrebbe essere nullo, troncando sul nascere ogni ulteriore discorso (GRAN LINGUAGGIO). Pertanto, assodato che puntatori NON NULLI a DUE asterischi POSSONO essere puntati da val solo in corrispondenza di bottoni appartenenti ai tipi citati, ognuno di essi può essere tuttavia lasciato nullo oppure no. Quando un selettore o multiselettore o cursore riscontra che il PROPRIO puntatore a DUE asterischi è NULLO, si dispone a essere un bottone il cui dominio di selezione (cfr. appresso) è semplicemente l'intervallo [0,1], indipendentemente dall'essere selettore o multiselettore o cursore. Quando, invece, il puntatore a DUE asterischi relativo a uno di questi tre tipi di bottoni è NON NULLO si ha un diverso comportamento secondo appunto il tipo: i selettori e i cursori assumono che il puntatore a DUE asterischi punti nient'altro che DUE puntatori semplici (a UN asterisco), ognuno dei quali punta, a sua volta, un UNICO valore double/REAL*8. Tali valori saranno interpretati dai selettori e dai cursori come minimo e massimo del proprio dominio di selezione, in luogo di 0 e 1. È pertanto NECESSARIO che siano inseriti nella memoria nell'ORDINE GIUSTO e che siano DIVERSI tra loro, col primo strettamente MINORE del secondo (NESSUN CONTROLLO IN PROPOSITO).
Invece un bottone multiselettore che trova NON NULLO il proprio puntatore a 2 asterischi assume che il numero di puntatori a UN asterisco che esso punta sia imprecisato a priori (da cui il prefisso "multi") e determinato, come in casi simili, dal fatto che l'ultimo di essi sia il puntatore NULLO. A quel punto tutti gli altri puntatori precedenti sono assunti puntare un UNICO valore double/REAL*8, come avveniva per gli altri due tipi, in ordine crescente: questi costituiranno i punti di separazione del dominio di selezione in sottodominii e l'ultimo fungerà da valore di fondo scala.

Gli ultimi due argomenti sono di gran lunga i più interessanti. Cominciando con l'ultimo, v, deve trattarsi di un array di puntatori a puntatori a void; la capienza dell'array è semplicemente 3 (TRE), vale a dire un puntatore a DUE asterischi per ogni pulsante di un mouse standard. Ognuno di questi tre puntatori a DUE asterischi può essere lasciato nullo; quando non sia nullo deve puntare un numero di puntatori a UN asterisco pari al numero di bottoni, con facoltà di lasciare nulli anche TUTTI questi puntatori a UN SOLO asterisco. Quando uno di questi ultimi puntatori fosse non nullo, DOVRÀ essere il risultato dell'operazione di casting a (void *) di un VALIDO PUNTATORE di QUALUNQUE TIPO che si trovi nel programma. La funzione lo utilizzerà per trasmetterlo come PRIMO DI DUE argomenti a una corrispondente funzione (cfr. qui appresso).

In effetti il penultimo argomento è una collezione, con la STESSA cardinalità dell'ultimo argomento, di puntatori a funzione con la segnatura indicata e restituenti un int, di modo che esiste una corrispondenza 1 a 1 tra puntatori a funzioni puntate nel penultimo argomento e puntatori a void puntati dall'ultimo e da trasmettere a dette funzioni, quando ne venisse richiesta l'esecuzione. Il secondo argomento trasmesso alle funzioni puntate in p non deve essere fornito dall'utente: ci pensa la libreria che vi pone un puntatore correttamente inizializzato a una
struct _dati_widget
e sottoposto all'operazione di casting a void*. Tale struttura, la cui dichiarazione è disponibile nel documento d'intestazione incluso passe_par_tout.h, contiene i seguenti membri (i fortranisti si ARRANGINO e/o PAGHINO IL FIO della loro pertinace ostinazione):



Terminata la descrizione degli argomenti ricevuti da questa funzione rimane solo da discutere la semantica dei diversi bottoni, relativamente al loro tipo e al fatto che siano in stato ATTIVATO, ossia presenti fisicamente entro la finestra.

Quando si esegue la funzione m_widget_loop ogni click di mouse eseguito su un bottone ATTIVO comporta una reazione da parte dell'interfaccia. Qui di seguito se ne dà l'elenco:

Osservazioni e puntualizzazioni:

L'interfaccia, per come è stata concepita e realizzata, allo stato attuale è già piuttosto ricca, consentendo la possibilità di eseguire TRE diverse funzioni per ogni bottone attivatore presente, trasmettendo a ciascuna, indipendentemente da ciascun'altra, sostanzialmente QUALSIASI COSA, vista la segnatura adottata; inoltre, per ogni bottone interruttore inserito nell'interfaccia, è possibile la gestione interattiva di proprie variabili booleane col cui valore, con ogni evidenza, si può far fare al proprio programma TUTTO e il suo contrario. Infine i bottoni selettori, cursori, e di input consentono di inserire nel programma dati di ogni natura e in ogni momento dell'esecuzione: i primi e i secondi quando non è necessaria un'estrema precisione nel valore del dato inserito, ma solo la sua appartenenza a, o la sua variazione continua in, un certo intervallo; gli ultimi, invece, quando si voglia inserire un dato fino alla precisione desiderata. I bottoni di output, in questo contesto, possono consentire al programma la richiesta di introdurre dei dati attraverso il valore della propria etichetta, modificabile in ogni momento dell'esecuzione, oppure la visualizzazione di qualsiasi altro (breve) messaggio utile.

L'interfaccia è sicura (fino a prova contraria) proprio grazie all'uso esteso di puntatori, con la corrispondente facoltà di controllarne l'eventuale nullità (GRAN LINGUAGGIO); si sottolinea che se un utilizzatore fornisce SOLO puntatori nulli per qualsiasi entità (escluse le etichette) l'interfaccia funziona comunque, sia pure in maniera elementare, dato che, allora, la funzione m_widget_loop è interrotta da qualsiasi click di mouse, ma in tal caso si conserva almeno l'informazione su quale bottone sia stato cliccato, attraverso il valore restituito al chiamante che potrebbe essere usato, da un programmatore meno che beota, come bersaglio di un proprio switch, eseguendo IVI le funzioni che ha trascurato di agganciare all'interfaccia.

In effetti, diversamente da altre funzioni della libreria, il cui valore di ritorno indica semplicemente se tutto è andato liscio oppure no, quello restituito da m_widget_loop consente di riconoscere facilmente come se ne è usciti, secondo il seguente schema:

In tutto l'elenco per "indice del bottone" s'intende la posizione del bottone nella finestra menu, numerata, dall'alto a sinistra, partendo da zero.
Tutti i valori elencati sono inseriti nei due bytes meno significativi dell'intero restituito; negli altri due bytes la funzione inserisce l'indice della finestra su cui si è attuato il click interrompente il ciclo (per intendersi quella per cui nei bytes meno significativi si trova ?01 o ?02 o ?03). Il programmatore potrà usufruire di tale informazione secondo la propria convenienza.

Un'ultima osservazione concerne la disposizione dei bottoni all'interno della finestra e, segnatamente, il valore da usare per l'argomento col (il terzo). Si è detto che, qualora sia positivo, le dimensioni dei bottoni devono essere date individualmente dal programmatore: ma questo significa che poi tali dimensioni sono rigorosamente onorate. Se uno è tonto e richiede dodici bottoni, ciascuno largo 600 pixels, da disporre su sei colonne, POI NON SI LAMENTI SE NON LI VEDE, perché, per vederli, occorrerebbe un monitor di larghezza pari almeno a 600 * 6 = 3600 pixels, quando i monitor 16x9 di uso comune hanno una larghezza di 2048. La morale è che chi non sa fare i conti è meglio (oltre che starsene a casa) che dia a col valori negativi e comunque appropriati.

La struttura _dati_widget

Come già detto la libreria trasmette un puntatore a una valida istanza di tale struttura, come secondo parametro, a qualsiasi funzione associata a bottoni attivatori o cursori, all'atto della sua esecuzione conseguente a un evento di mouse su di essi. Ciò è di particolare rilievo se si considera che ogni "evento di mouse" si ripartisce in TRE eventi distinti per ciascun pulsante di cui il mouse è dotato: pressione del pulsante; suo (eventuale) trascinamento a pulsante premuto; rilascio del pulsante.

Una funzione eventualmente associata a un certo pulsante per eventi riscontrati su un bottone attivatore viene eseguita quindi più di una sola volta: almeno DUE volte (alla pressione E al rilascio) ovvero un numero ELEVATO di volte se tra pressione e rilascio avviene un trascinamento a pulsante trattenuto premuto. Addirittura questo potrebbe comportare l'esecuzione di DUE FUNZIONI DIVERSE se si preme il pulsante su un certo bottone attivatore e poi lo si trascina fino a rilasciarlo su UN ALTRO ATTIVATORE, nella STESSA finestra, che avesse associata un'altra funzione per quello stesso pulsante. Il programmatore ha la possibilità di decidere come gestire questo comportamento, dall'interno delle PROPRIE funzioni, che egli/ella stesso/a associa ai diversi bottoni all'atto della creazione del menu, giustappunto basandosi sui valori contenuti, e già descritti, nell'oggetto puntato dal puntatore ricevuto come ultimo argomento e precisamente, nel contesto che si sta discutendo, sul valore della variabile membro ragione e su quelli dell'array chiamato index.
Per quanto attiene ai bottoni cursori, la ripartizione degli eventi di mouse nelle loro tre fasi è certamente di più immediata comprensione ed è stata già introdotta. Vale nondimeno anche per essi la facoltà di gestire al meglio le operazioni eseguite nelle funzioni associate, secondo la fase dell'evento in atto.
Al termine di queste annotazioni non vi sarà chi non si sia avveduto che la struct _dati_widget dà al programmatore la possibilità di scegliere fra un approccio in cui a ogni bottone e a ogni pulsante sia associata una funzione distinta (neutralizzando, per ciò stesso, l'utilità della struct _dati_widget, eccettuato il membro ragione) e l'approccio opposto, in cui UNA SOLA FUNZIONE è associata a cani e porci e le diverse reazioni si determinano al suo interno utilizzando PESANTEMENTE la più volte citata struct.


Esempi d'uso:

Esempio 1:
un programma che presenta un'unica finestra menu con TUTTI i tipi di bottoni e usa TUTTE le funzioni del Widget set


#include<passe_par_tout.h>
#define BOTTONI_RICHIESTI 9

int
coloriP[  ] =
{ROSSO, VERDE, GIALLO, BLU, MAGENTA, CIANO, BIANCO, BIANCO, BIANCO},
coloriC[  ] =
{BIANCO, NERO, NERO, ROSSO, BIANCO, NERO, NERO, NERO, NERO},
tipiP[  ] =
{BOTTONE_ATTIVATORE, BOTTONE_INTERRUTTORE,
BOTTONE_SELETTORE, BOTTONE_MULTISELETTORE,
BOTTONE_TEXTFIELD, BOTTONE_INPUT_FLOAT,
BOTTONE_INPUT_INT, BOTTONE_INPUT_CHARS,
BOTTONE_SCORREVOLE};

void definisci_bottoni(int **&butti, int n)
{if(n > 9) cerr << "questo programma esempio è mal formato\n", exit(255);
butti = new int*[n+1];
for(int i=0; i != n; ++i)
butti[i] = new int[7],
butti[i][0] = 250+270*(i==3 || i==2), butti[i][1] = 60-35*(i==3 || i==2),
butti[i][2] = coloriP[i],
butti[i][3] = coloriC[i],
butti[i][4] = ROSSO,
butti[i][5] = tipiP[i],
butti[i][6] = ACCESO;
butti[n] = nullptr;}

int funza(void *a, void * = nullptr)
{int i(0), j(3);
cout
<< "sono funza e ricevo "
<< (int)(*(char*) a) << endl;
double ** x = new double*[9]
{new double(1.0), new double(2.0), new double(3.0),
new double(4.0), new double(5.0), new double(6.0),
new double(7.0), new double(8.0), nullptr};
m_change_sectors(&i, &j, x);
return 0;}

class Pappo
{public:
static constexpr int i = 222;
int j{0};
void operator!(  ) {j = !j;}
};

int funzz(void *a, void * = nullptr)
{cout
<< "sono funzz e ricevo "
<< ((Pappo *)a) -> i << ' ' << ((Pappo *)a) -> j << endl; return 0;}

int main(  )
{int
i, l, j, icucco, **butti,
locazione[  ]{0,0}, (**ptrfz[3])(void *, void *);
void **voidptr[3];
Pappo pappo;
char strval[500], ** labelle = new char*[BOTTONI_RICHIESTI]
{const_cast<char*>("Sono un bottone attivatore"),
const_cast<char*>("Sono un bottone interruttore"),
const_cast<char*>("Sono un bottone selettore"),
const_cast<char*>("Sono un bottone multiselettore"),
const_cast<char*>("Sono un bottone di output"),
const_cast<char*>("Sono un bottone di input float"),
const_cast<char*>("Sono un bottone di input int"),
const_cast<char*>("Sono un bottone di input char"),
const_cast<char*>("Sono uno slider")};
double L, *** cucco = new double**[BOTTONI_RICHIESTI+1];
char booleano[  ] = {1, 15};
for(i=0; i != 3; ++i)
ptrfz[i] = new (int(*[BOTTONI_RICHIESTI])(void *, void *)),
voidptr[i] = new void*[BOTTONI_RICHIESTI];
for(i=0; i != BOTTONI_RICHIESTI; ++i)
cucco[i] = 0,
ptrfz[0][i] = funza, ptrfz[1][i] = funzz, ptrfz[2][i] = funza,
voidptr[0][i] = (void *)booleano,
voidptr[1][i] = (void *)&pappo,
voidptr[2][i] = (void *)(booleano+1);

cucco[icucco = BOTTONI_RICHIESTI >= 9 ? BOTTONI_RICHIESTI-7 :
(BOTTONI_RICHIESTI >= 3 ? 1 : 0)]
= new double*[2]{new double(80.0), new double(81.0)},
cucco[icucco+1] = new double*[5]
{new double(0.0), new double(10.0), new double(18.0), new double(24.0), 0},

m_startg(const_cast<char*>(""), &(i=100), &(i=100)),
definisci_bottoni(butti, BOTTONI_RICHIESTI),
m_menu
(locazione, const_cast<char*>("titolo"), &(i=-5), butti,
labelle, cucco, ptrfz, voidptr);

cout << "dimmi il numero del bottone da smaneggiare ", cin >> i,
m_manage_button(&(icucco=0), &i),
cout << "ora, appena digiti un numero, lo rimaneggio ", cin >> l,
m_manage_button(&icucco, &i);

m_set_textfield_button(&icucco, &(l=4), const_cast<char*>("labellina"));
cout << "il bottone textfield ha come etichetta ["
<< m_get_textfield_button(&icucco, &l) << "]\n";

l = 1, j = 3;
for(i=0; i != 3; ++i)
m_change_ptr(&icucco, &l, &i, (void*)m_get_button_status(&icucco, &j));
cout << "ora, nell'ordine, clicca due volte col pulsante destro il bottone interruttore:\n"
"vedrai scomparire e riapparire il multiselettore;\n"
"se invece cliccherai sul bottone attivatore vedrai cambiare i settori dello\n"
"stesso multiselettore.\nDopo questo, fai quello che vuoi\n";
L = 0.0, i = 0,
m_widget_loop(&L, &i, strval),
cout << "da widget_loop ricevo [" << strval << "] di lunghezza "
<< strlen(strval) << "; val = " << L << " e vali = " << i << '\n';
}


Il programma si autocommenta se lo si legge con attenzione alla luce delle spiegazioni fornite; si osservi come sia possibile trasmettere alle funzioni registrate per i diversi pulsanti, così come ai puntatori a void, l'indirizzo di oggetti istanze di proprie classi, come l'oggetto pappo istanziato in main.
Si osservi altresì che la presenza di una operator! accessibile nella classe Pappo permette al programmatore di definire con cura, e secondo le proprie preferenze, come debba essere interpretata la commutazione booleana operata da un bottone interruttore.
Si provi a eseguire questo programma, a interagire con l'interfaccia e a modificarla in modo congruo con le istruzioni date.


Esempio 2:
sulla falsariga del precedente, questo programme crea ben TRE finestre menu mantenendo un'unica esecuzione di m_widget_loop


#include<passe_par_tout.h>
#define BOTTONI_RICHIESTI 9

int
coloriP[  ] =
{ROSSO, VERDE, GIALLO, BLU, MAGENTA, CIANO, BIANCO, BIANCO, BIANCO},
coloriC[  ] =
{BIANCO, NERO, NERO, ROSSO, BIANCO, NERO, NERO, NERO, VERDE},
tipiP[  ] =
{BOTTONE_ATTIVATORE, BOTTONE_INTERRUTTORE,
BOTTONE_SELETTORE, BOTTONE_MULTISELETTORE,
BOTTONE_TEXTFIELD, BOTTONE_INPUT_FLOAT,
BOTTONE_INPUT_INT, BOTTONE_INPUT_CHARS,
BOTTONE_SCORREVOLE};

void definisci_bottoni(int **&butti, int n)
{if(n > 9) cerr << "questo programma esempio ` mal formato\n", exit(255);
butti = new int*[n+1];
for(int i=0; i != n; ++i)
butti[i] = new int[7],
butti[i][0] = 250+270*(i==3 || i==2), butti[i][1] = 60-35*(i==3 || i==2),
butti[i][2] = coloriP[i],
butti[i][3] = coloriC[i],
butti[i][4] = BLU,
butti[i][5] = tipiP[i],
butti[i][6] = ACCESO;
butti[n] = nullptr;}

int funza(void *a, void *b = nullptr)
{_dati_widget *d = reinterpret_cast<_dati_widget *>(b);
cout
<< "sono funza e ricevo "
<< (int)(*(char*) a) << endl;
cout << "sono stata eseguita a causa della pressione del pulsante "
<< (int)d->click << "\nsul bottone " << d->index[0]
<< " della finestra menu " << d->index[1]
<< "\ncon motivazione " << d->ragione << endl;
return 0;}

int funzc(void *a, void * = nullptr)
{cout
<< "sono funzc, la funzione per il pulsante destro, e ricevo "
<< (int)(*(char*) a) << endl;
return 0;}

class Pappo
{public:
static constexpr int i = 222;
int j{0};
void operator!(  ) {j = !j;}
};

int funzz(void *a, void * = nullptr)
{cout
<< "sono funzz, la funzione per il pulsante centrale, e ricevo "
<< ((Pappo *)a) -> i << ' ' << ((Pappo *)a) -> j << endl; return 0;}

int main(  )
{int
i, l, icucco, **butti, **bitti,
locazione[  ][2]{0,0,0,400,0,800}, (**ptrfz[3])(void *, void *);
void **voidptr[3];
Pappo pappo;
char strval[500], ** labelle = new char*[BOTTONI_RICHIESTI]
{const_cast<char*>("Sono un bottone attivatore"),
const_cast<char*>("Sono un bottone interruttore"),
const_cast<char*>("Sono un bottone selettore"),
const_cast<char*>("Sono un bottone multiselettore"),
const_cast<char*>("Sono un bottone di output"),
const_cast<char*>("Sono un bottone di input float"),
const_cast<char*>("Sono un bottone di input int"),
const_cast<char*>("Sono un bottone di input char"),
const_cast<char*>("Sono uno slider")},
**lebolle = new char*[4]
{const_cast<char*>("per modo di dire"),
const_cast<char*>("per finta"),
const_cast<char*>("per scherzare"),
const_cast<char*>("piripo")};
double L, *** cucco = new double**[BOTTONI_RICHIESTI+1];
char booleano[  ] = {1, 15};
for(i=0; i != 3; ++i)
ptrfz[i] = new (int(*[BOTTONI_RICHIESTI])(void *, void *)),
voidptr[i] = new void*[BOTTONI_RICHIESTI];
for(i=0; i != BOTTONI_RICHIESTI; ++i)
cucco[i] = 0,
ptrfz[0][i] = funza, ptrfz[1][i] = funzz, ptrfz[2][i] = funzc,
voidptr[0][i] = (void *)booleano,
voidptr[1][i] = (void *)&pappo,
voidptr[2][i] = (void *)(booleano+1);

cucco[icucco = BOTTONI_RICHIESTI >= 9 ? BOTTONI_RICHIESTI-7 :
(BOTTONI_RICHIESTI >= 3 ? 1 : 0)]
= new double*[2]{new double(80.0), new double(81.0)},
cucco[icucco+1] = new double*[5]
{new double(0.0), new double(10.0), new double(18.0), new double(24.0), 0},

m_startg(const_cast<char*>(""), &(i=100), &(i=100)),
definisci_bottoni(butti, BOTTONI_RICHIESTI),
definisci_bottoni(bitti, 4),
m_menu
(locazione[0], const_cast<char*>("seconda"), &(i=0), bitti,
lebolle, nullptr, nullptr, nullptr);
m_redraw(&(i=0)),
m_menu
(locazione[1], const_cast<char*>("terza"), &(i=0), bitti,
lebolle, cucco, ptrfz, voidptr);
m_redraw(&(i=1)),
m_menu
(locazione[2], const_cast<char*>("titolo"), &(i=-5), butti,
labelle, cucco, ptrfz, voidptr);
m_redraw(&(i=2)),

cout << "dimmi il numero del bottone da smaneggiare"
" e su quale finestra (fai attenzione): ",
cin >> i >> icucco,
m_manage_button(&icucco, &i),
cout << "ora, appena digiti un numero, lo rimaneggio ", cin >> l,
m_manage_button(&icucco, &i);

m_set_textfield_button(&(icucco=2), &(l=4), const_cast<char*>("labellina"));
cout << "il bottone textfield ha come etichetta ["
<< m_get_textfield_button(&icucco, &l) << "]\n";

L = 0.0, i = 0,
m_widget_loop(&L, &i, strval),
cout << "da widget_loop ricevo [" << strval << "] di lunghezza "
<< strlen(strval) << "; val = " << L << " e vali = " << i << '\n';
}


Questo programma ha mostrato come l'interfaccia si attivi su un numero arbitrario di finestre.


Esempio 3:
questo programma mostrerà il widget set al lavoro per qualcosa.


#include<passe_par_tout.h>
#define BOTTONI_RICHIESTI 6

struct dati {static char booleano; static int lati;};
char dati::booleano = 1;
int dati::lati = 3;

int
coloriP[  ] =
{BIANCO, BIANCO, BIANCO, BIANCO, MAGENTA, BIANCO},
coloriC[  ] =
{NERO, NERO, NERO, NERO, NERO, NERO},
tipiP[  ] =
{BOTTONE_ATTIVATORE, BOTTONE_INTERRUTTORE,
BOTTONE_ATTIVATORE, BOTTONE_ATTIVATORE,
BOTTONE_MULTISELETTORE, BOTTONE_TEXTFIELD};

void definisci_bottoni(int **&butti, int n)
{if(n > BOTTONI_RICHIESTI)
cerr << "questo programma esempio è mal formato\n", exit(255);
butti = new int*[n+1];
for(int i=0; i != n; ++i)
butti[i] = new int[7],
butti[i][2] = coloriP[i],
butti[i][3] = coloriC[i],
butti[i][4] = NERO,
butti[i][5] = tipiP[i],
butti[i][6] = ACCESO;
butti[n] = nullptr;}

int disegna(void *a, void * = nullptr)
{double
pol[18], anginiz = 0.0, c, s,
angolo_centro = 2.0*M_PI/dati::lati,
raggio = 0.85;
char cc = *((char*)a);
int i, l;
for(i=0; i != dati::lati; ++i)
c = cos(anginiz), s = sin(anginiz),
pol[2*i] = raggio*c, pol[2*i+1] = raggio*s,
anginiz += angolo_centro;
m_select(&(i=1));
if(cc) m_polygon(pol, &dati::lati);
else
{m_move(pol);
for(i=0; i != dati::lati-1; ++i) m_line(pol+2*(i+1));
m_line(pol);}
return 0;}

int cancella(void *a, void * = nullptr)
{int i = 1;
m_clear(&i);
return 0;}

int termina(void *a, void * = nullptr)
{m_endg(  ), exit(111); return 0;}

int main(  )
{int i, l, **butti, locazione[  ]{0,0}, (**ptrfz[3])(void *, void *);
void **voidptr[3];
char strval[500], ** labelle = new char*[BOTTONI_RICHIESTI]
{const_cast<char*>("Disegna un poligono"),
const_cast<char*>("Poligono pieno\001Poligono vuoto"),
const_cast<char*>("Cancella finestra"),
const_cast<char*>("Uscita"),
const_cast<char*>("Numero di lati (>2)"),
const_cast<char*>("")};
double L=10, x[  ]{-1,-1,1,1}, *** cucco = new double**[BOTTONI_RICHIESTI+1];
for(i=0; i != 3; ++i)
ptrfz[i] = new (int(*[BOTTONI_RICHIESTI])(void *, void *)),
voidptr[i] = new void*[BOTTONI_RICHIESTI];
for(i=0; i != BOTTONI_RICHIESTI; ++i)
voidptr[0][i] = voidptr[1][i] = voidptr[2][i] = nullptr, cucco[i] = nullptr,
ptrfz[0][i] = ptrfz[1][i] = ptrfz[2][i] = nullptr;
ptrfz[0][0] = disegna, voidptr[0][0] = (void *)&dati::booleano,
ptrfz[0][2] = cancella,
voidptr[0][1] = voidptr[1][1] = voidptr[2][1] = (void *)&dati::booleano,
ptrfz[0][3] = termina;
cucco[4]
= new double*[9]
{new double(3.0), new double(4.0), new double(5.0),
new double(6.0), new double(7.0), new double(8.0),
new double(9.0), new double(10.0), nullptr};
m_startg(const_cast<char*>(""), &(i=600), &(i=600)),
definisci_bottoni(butti, BOTTONI_RICHIESTI),
m_menu
(locazione, const_cast<char*>("titolo"), &(i=-2),
butti, labelle, cucco, ptrfz, voidptr);
ostringstream ossa;
ossa << "con " << dati::lati << (dati::booleano ? " pieno" : " vuoto") << '\0',
m_set_textfield_button(&(i=0), &(l=5), const_cast<char*>(ossa.str(  ).data(  )));
m_window(&(i=0), &(l=0)),
m_frame(x, x+1, x+2, x+3), L = 3;
while(true)
m_widget_loop(&L, &i, strval),
ossa.seekp(0),
L > 2 && L < 10 ?
dati::lati = L : 0,
ossa << "con " << dati::lati << (dati::booleano ? " pieno" : " vuoto") << '\0',
m_set_textfield_button(&(i=0), &(l=5), const_cast<char*>(ossa.str(  ).data(  )));
}


Anche in questo caso il programma dovrebbe essere stato autoesplicativo.


Esempio 4:
infine lo stesso programma dato nell'Esempio 2 viene riproposto con la funzione m_widget_loop eseguita in un proprio, DISTINTO, thread.


#include<passe_par_tout.h>
#include<thread>
#define BOTTONI_RICHIESTI 8

int
coloriP[  ] =
{ROSSO, VERDE, GIALLO, BLU, MAGENTA, CIANO, BIANCO, BIANCO},
coloriC[  ] =
{BIANCO, NERO, NERO, ROSSO, BIANCO, NERO, NERO, NERO},
tipiP[  ] =
{BOTTONE_ATTIVATORE, BOTTONE_INTERRUTTORE,
BOTTONE_SELETTORE, BOTTONE_MULTISELETTORE,
BOTTONE_TEXTFIELD, BOTTONE_INPUT_FLOAT,
BOTTONE_INPUT_INT, BOTTONE_INPUT_CHARS};

void definisci_bottoni(int **&butti, int n)
{if(n > 8) cerr << "questo programma esempio è mal formato\n", exit(255);
butti = new int*[n+1];
for(int i=0; i != n; ++i)
butti[i] = new int[7],
butti[i][0] = 250+270*(i==3 || i==2), butti[i][1] = 60-35*(i==3 || i==2),
butti[i][2] = coloriP[i],
butti[i][3] = coloriC[i],
butti[i][4] = ROSSO,
butti[i][5] = tipiP[i],
butti[i][6] = ACCESO;
butti[n] = nullptr;}

int funza(void *a, void * = nullptr)
{cout
<< "sono funza e ricevo "
<< (int)(*(char*) a) << endl;
return 0;}

int funzc(void *a, void * = nullptr)
{cout
<< "sono funzc e ricevo "
<< (int)(*(char*) a) << endl;
return 0;}

class Pappo
{public:
static constexpr int i = 222;
int j{0};
void operator!(  ) {j = !j;}
};

int funzz(void *a, void * = nullptr)
{cout
<< "sono funzz e ricevo "
<< ((Pappo *)a) -> i << ' ' << ((Pappo *)a) -> j << endl; return 0;}

int main(  )
{m_multi_threaded_program(  );
int
i, l, icucco, **butti, **bitti,
locazione[  ][2]{0,0,0,400,0,800}, (**ptrfz[3])(void *, void *);
void **voidptr[3];
Pappo pappo;
char strval[500], ** labelle = new char*[BOTTONI_RICHIESTI]
{const_cast<char*>("Sono un bottone attivatore"),
const_cast<char*>("Sono un bottone interruttore"),
const_cast<char*>("Sono un bottone selettore"),
const_cast<char*>("Sono un bottone multiselettore"),
const_cast<char*>("Sono un bottone di output"),
const_cast<char*>("Sono un bottone di input float"),
const_cast<char*>("Sono un bottone di input int"),
const_cast<char*>("Sono un bottone di input char")},
**lebolle = new char*[4]
{const_cast<char*>("per modo di dire"),
const_cast<char*>("per finta"),
const_cast<char*>("per scherzare"),
const_cast<char*>("piripo")};
double L, *** cucco = new double**[BOTTONI_RICHIESTI+1];
char booleano[  ] = {1, 15};
thread * th;
for(i=0; i != 3; ++i)
ptrfz[i] = new (int(*[BOTTONI_RICHIESTI])(void *, void *)),
voidptr[i] = new void*[BOTTONI_RICHIESTI];
for(i=0; i != BOTTONI_RICHIESTI; ++i)
cucco[i] = 0,
ptrfz[0][i] = funza, ptrfz[1][i] = funzz, ptrfz[2][i] = funzc,
voidptr[0][i] = (void *)booleano,
voidptr[1][i] = (void *)&pappo,
voidptr[2][i] = (void *)(booleano+1);

cucco[icucco = BOTTONI_RICHIESTI >= 8 ? BOTTONI_RICHIESTI-6 :
(BOTTONI_RICHIESTI >= 3 ? 1 : 0)]
= new double*[2]{new double(80.0), new double(81.0)},
cucco[icucco+1] = new double*[5]
{new double(0.0), new double(10.0), new double(18.0), new double(24.0), 0},

m_startg(const_cast<char*>(""), &(i=100), &(i=100)),
definisci_bottoni(butti, BOTTONI_RICHIESTI),
definisci_bottoni(bitti, 4),
m_menu
(locazione[0], const_cast<char*>("seconda"), &(i=0), bitti,
lebolle, nullptr, nullptr, nullptr);
m_redraw(&(i=0)),
m_menu
(locazione[1], const_cast<char*>("terza"), &(i=0), bitti,
lebolle, cucco, ptrfz, voidptr);
m_redraw(&(i=1)),
m_menu
(locazione[2], const_cast<char*>("titolo"), &(i=-5), butti,
labelle, cucco, ptrfz, voidptr);
m_redraw(&(i=2)),

cout << "dimmi il numero del bottone da smaneggiare"
" e su quale finestra (fai attenzione): ",
cin >> i >> icucco,
m_manage_button(&icucco, &i),
cout << "ora, appena digiti un numero, lo rimaneggio ", cin >> l,
m_manage_button(&icucco, &i);

m_set_textfield_button(&(icucco=2), &(l=4), const_cast<char*>("labellina"));
cout << "il bottone textfield ha come etichetta ["
<< m_get_textfield_button(&icucco, &l) << "]\n";

L = 0.0, i = 0,
th = new thread(m_widget_loop, &L, &i, strval),
th->join(  ),
cout << "da widget_loop ricevo [" << strval << "] di lunghezza "
<< strlen(strval) << "; val = " << L << " e vali = " << i << '\n';
}


Si lascia alla fantasia di chi legge immaginare il panorama vastissimo di opportunità lasciato scorgere da un programma pur così semplice.

torna a widget set
torna daccapo













































































m_widget_loop(valorefloating, valoreint, stringa)

È la funzione che attua efficacemente l'interfaccia grafica tra il programma e il widget set.
La funzione si AGGANCIA a una finestra menu appropriata in seguito a uno degli eventi riconosciuti dall'interfaccia, innescando un CICLO INFINITO (da cui il nome della funzione) dal quale si esce in uno dei seguenti modi:

Il ciclo infinito MAI si interrompe per qualsiasi interazione con un bottone di output o con un bottone cursore.

È evidente che il buon funzionamento di un'interfaccia grafica dipenda in ampia misura dalla scrupolosa aderenza, da parte di un utilizzatore, alle regole semantiche dell'interfaccia medesima e per questo si sono date QUI, PER PRIME, le modalità di uscita dal ciclo infinito; per tutto il resto, compresi esempi d'uso, si rinvia alla descrizione della funzione m_menu.

torna a widget set
torna daccapo













































































m_set_textfield_button(finestra, bottone, stringa)

I primi due argomenti di questa funzione hanno lo stesso significato e lo stesso tipo descritti in m_manage_button, ma nel caso presente l'effetto di "nessuna operazione" si ha, in aggiunta ai casi colà citati, anche qualora il bottone indirizzato NON sia un bottone di input/output oppure NON sia attivo. In caso contrario questa funzione sostituisce l'etichetta correntemente visualizzata nel bottone con il contenuto del terzo argomento che, con ogni ovvietà, dovrà essere un array di caratteri correttamente terminato col carattere nullo (ne tengano conto i FORTRANISTI, ahiloro).
L'esempio d'uso per questa funzione si trova nel codice inserito nella descrizione di m_menu.

torna a widget set
torna daccapo













































































m_get_textfield_button(finestra, bottone)

Gli argomenti di questa funzione hanno lo stesso significato e lo stesso tipo descritti in m_manage_button, ma nel caso presente l'effetto di "nessuna operazione" si ha, in aggiunta ai casi colà citati, anche qualora il bottone indirizzato NON sia un bottone di input/output oppure NON sia attivo. In caso contrario questa funzione restituisce al chiamante, in un puntatore a char (ne tengano conto i FORTRANISTI, ahiloro), l'etichetta attualmente visualizzata nel bottone.
L'esempio d'uso per questa funzione si trova nel codice inserito nella descrizione di m_menu.

torna a widget set
torna daccapo













































































m_manage_button(finestra, bottone)


Come altre funzioni della libreria consiste in un "alternatore" che modifica lo stato di attività di un certo bottone ponendolo in quello opposto allo stato attuale.
I due argomenti sono entrambi int/INTEGER*4: il primo rappresenta l'indice della finestra contenente il bottone da attivare/disattivare (come in ogni altro caso simile deve essere >= 0), il secondo l'indice del bottone da attivare/disattivare all'interno di quella finestra (anch'esso >= 0).
Un bottone disattivato sparisce dalla finestra fino a un'eventuale riattivazione susseguente.
Se il valore di finestra non è quello di una finestra dedicata a menu o se il valore di bottone è fuori intervallo per la finestra indirizzata l'esecuzione di questa funzione si risolve in "nessuna operazione". In ogni altro caso il bottone indirizzato subisce l'azione descritta, SENZA CHE IN ALCUN MODO CAMBI quale finestra sta ricevendo output grafico.
L'esempio d'uso di questa funzione si trova nel codice inserito nella descrizione di m_menu.

torna a widget set
torna daccapo













































































L'interfacciamento con OpenGL

In questa pagina non saranno inserite spiegazioni sull'uso delle funzioni di OpenGL, che sono reperibili ovunque, ma solo l'essenziale per poter fornire a quella libreria, da parte di passe_par_tout, il supporto per l'apertura di finestre che essa non possiede e la gestione di eventi di vario tipo, in particolare la possibilità di proficua interazione con il widget set.

L'interfaccia si attiva tramite l'esecuzione della funzione

m_window_GL

in sostituzione della classica m_window: ciò cagiona l'apertura sul monitor di una finestra che si inserisce nell'usuale cronologia delle finestre di passe_par_tout, come se fosse stata aperta da m_window, ma che, al suo interno, ha la configurazione adeguata per essere bersaglio di esecuzione per le funzioni grafiche di OpenGL. Per questa stessa ragione ogni richiesta di esecuzione di funzioni "normali" di passe_par_tout che l'avesse come finestra di destinazione sarebbe bellamente ignorata. La configurazione in questione viene impostata in OGNI finestra aperta con m_window_GL nello stesso programma: essa comprende la creazione di un "contesto" di esecuzione compatibile con la versione di OpenGL installata sulla macchina ospite, la selezione di un adeguato visual, che sarà associato a ogni finestra e che, auspicabilmente, finirà spesso col coincidere col default visual e la creazione di una tavolozza compatibile con i seguenti attributi, il cui significato si assume noto:



In aggiunta alle predette configurazioni viene anche impostata la maschera per la gestione degli eventi occorrenti all'interno delle finestre; tale maschera ha il seguente valore (anche qui se ne assume noto il significato):

StructureNotifyMask | KeyPressMask | KeyReleaseMask | ExposureMask | VisibilityChangeMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask

I parametri che devono essere trasmessi a m_window_GL sono qui appresso minuziosamente descritti.

m_window_GL(L, A, titolo, init, ptdr, ptd)

I primi due sono due puntatori a int/INTEGER*4 che indirizzano due valori ciascuno: il primo valore rappresenta la dimensione, in pixels, della finestra da aprire sul monitor (dimensione orizzontale in L e verticale in A), mentre il secondo rappresenta la posizione, sempre in pixels, che deve occupare l'angolo superiore sinistro della finestra rispetto all'angolo superiore sinistro dello schermo (ancora orizzontale in L e verticale in A).
L'argomento titolo è un puntatore ben terminato a char che, come dice il nome, porta in sé il titolo da attribuire alla finestra; se viene trasmesso il puntatore nullo il titolo sarà la stringa "Finestra GL_" completata dal numero ordinale nella cronologia della libreria.
L'argomento init è un puntatore a funzione che riceve un parametro puntatore a int/INTEGER*4 e restituisce un int/INTEGER*4: se è validamente inizializzato la funzione puntata viene eseguita, una tantum, all'atto dell'apertura della finestra trasmettendole, nel puntatore che essa riceve, tre valori interi che sono, nell'ordine, l'indice della finestra nella cronologia di passe_par_tout e le sue due dimensioni in pixels (le stesse ricevute da m_window_GL nei suoi primi due argomenti). Va da sé che l'avveduto programmatore che abbia trasmesso a m_window_GL un valido puntatore init avrà provveduto a inserire nella funzione puntata tutte le direttive di inizializzazione della scena OpenGL, da rappresentare nella finestra, che avrà ritenuto necessarie. Se init viene trasmesso come puntatore nullo si otterrà, in ogni caso, un'inizializzazione default descritta appresso.

Il penultimo parametro, ptdr, è anch'esso un puntatore a funzione che, se non è nullo, viene indelebilmente associato alla finestra; in questo caso la funzione eventualmente puntata, pur continuando a restituire un int/INTEGER*4, deve ricevere un puntatore a void che sarà l'ultimo argomento (ptd) ricevuto da m_window_GL. Nella funzione puntata da ptdr lo scaltro programmatore inserirà tutte le chiamate di funzioni di OpenGL necessarie per disegnare la propria scena e in ptd tutto ciò che la citata funzione ha bisogno di ricevere per poter lavorare: eventualmente anche NULLA. La libreria provvedrà a far eseguire QUESTA funzione tutte le volte che si renda necessario ridisegnare la finestra ed è pertanto alquanto inverosimile che abbia senso trasmettere ptdr come puntatore nullo.

inizializzazione default

Avviene in modo silente allorché a m_window_GL si richiede di creare e aprire sullo schermo una finestra e non le si fornisce un valido puntatore init: giovi ricordare che in caso contrario l'inizializzazione default è SOPPRESSA, essendo in toto sostituita da ciò che il programmatore scrive nella propria funzione di inizializzazione puntata dal puntatore init.

Nell'inizializzazione default si attua un modello di illuminazione di "ambienza" alquanto chiaro, ma leggermente opaco (0.7, 0.7, 0.7, 0.7) e si imposta a false il parametro GL_LIGHT_MODEL_TWO_SIDE. Nel modello di illuminazione citato sono attivate due luci: GL_LIGHT0 e GL_LIGHT1: la prima ha un valore di diffusione (0.6, 0.6, 0.6, 1) e uno di riflessione speculare (0.7, 0.7, 0.3, 1); la seconda è trattata come luce direzionale con parametro GL_SPOT_DIRECTION di coordinate (-1, 0, 0, 0) e con componente di diffusione (0, 1, 0, 1): un faretto verde. La collocazione spaziale di GL_LIGHT1 è il punto (0,0,2,1).
Vengono altresì impostati i valori GL_SMOOTH per il modello di ombreggiatura e GL_LEQUAL per la depth function; inoltre viene attivato il parametro GL_COLOR_MATERIAL, abilitato il GL_DEPTH_TEST e viene caricata la matrice identità sia nella GL_MODELVIEW sia nella GL_PROJECTION. Da ultima viene eseguita la funzione
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
con il colore (0,0,0,1) di modo che lo sfondo della finestra appaia NERO (ciò consente di distinguere a colpo d'occhio le finestre aperte con m_window_GL da quelle aperte da m_window che, salvo intenzioni contrarie del programmatore, hanno abitualmente lo sfondo BIANCO).

Tutte le funzionalità del widget set sono fruibili anche per finestre OpenGL: basta solo che le funzioni puntate dai puntatori associati ai bottoni contengano istruzioni appropriate, come già sottolineato in questo stesso documento; anche le normali funzioni di "attesa eventi" presenti in passe_par_tout possono essere tranquillamente usate come per ogni altra finestra.

In aggiunta a quanto si è appena finito di dire le finestre aperte da m_window_GL possono essere equipaggiate di ulteriori gestori di eventi che possono generare risposte in seguito a pressioni di tasti della tastiera (in qualunque numero) e di click di mouse sulle finestre medesime.

Cominciando da questi ultimi va detto che ogni click di mouse, con ciascuno dei tre pulsanti che ogni mouse normale possiede, comporta un cambio di angolazione del punto di vista della scena secondo rotazioni di un angolo fisso attorno a ognuno dei tre assi coordinati: asse x per il pulsante sinistro, y per il centrale e z per il destro. L'ammontare dell'angolo di rotazione corrispondente a ogni click è predeterminato in passe_par_tout ed è di 5 (cinque) gradi sessagesimali. Per modificarlo, qualora il programmatore ne sentisse la necessità, è disponibile un'apposita funzione

m_set_GL_angle(finestra, angoli)

che riceve nel primo argomento l'indice (puntatore a int/INTEGER*4) della finestra su cui si vuole intervenire e nel secondo (puntatore a float/REAL*4) i tre valori degli incrementi dell'angolo di rotazione rispetto ai tre assi coordinati. Si riesce a intuire che valori negativi implicano l'inversione delle rotazioni. Se il click di mouse viene effettuato tenendo contemporaneamente premuto uno dei tasti CTRL della tastiera si ottiene il non trascurabile effetto di reimpostare al valore di partenza l'angolo di rotazione relativo all'asse coinvolto dal pulsante premuto: in altre parole con tre click consecutivi con ciascuno dei tre pulsanti, e col tasto CTRL premuto, si riporta il punto di vista allo stato iniziale (prescindendo da eventuali cambiamenti permanenti di prospettiva impostati dal fruitore della libreria nelle proprie funzioni di ridisegnatura).

La funzione

m_add_GL_keyevent_handlers

consente di associare a una finestra aperta da m_window_GL un numero "elevatissimo" di funzioni che rispondano alla pressione di (quasi) OGNI TASTO presente sulla tastiera quando il focus è detenuto da quella finestra. Gli argomenti che questa funzione attende sono ora descritti:

m_add_GL_keyevent_handlers(N, key, ptrf, ptrv)

L'argomento N, di tipo puntatore a int/INTEGER*4, contiene il valore dell'indice della finestra, secondo la cronologia propria di passe_par_tout, cui va/vanno associata/e la/le funzione/i di callback; se la finestra così indicizzata NON FOSSE stata aperta con m_window_GL l'esecuzione di questa funzione viene cortocircuitata su "nessuna operazione".
L'argomento key, dello stesso tipo di N, detiene il valore del carattere, nella tabella ASCII, a partire dal quale devono essere compiute le associazioni

"tasto premuto<--->funzione eseguita";

significa che se key puntasse il valore 97=='a' le associazioni verrebbero compiute a partire dalla pressione del tasto "a minuscola".
L'argomento ptrf è un array di puntatori a funzione il cui ultimo elemento DEVE ESSERE IL PUNTATORE NULLO (ciò serve a contarne gli elementi) e la cui segnatura DEVE ESSERE quella di funzioni che ricevono, nell'ordine, un puntatore a void e due puntatori a int/INTEGER*4 e restituiscono un int/INTEGER*4. La funzione associa OGNI PUNTATORE valido a un tasto della tastiera a partire da quello fornito in key: tanto per essere espliciti, se si mantiene key=='a' e si forniscono in ptrf TRE puntatori validi (non nulli), il primo viene associato al tasto 'a', il secondo al 'b' e il terzo al 'c'; coerentemente, se NON si fornisse ALCUN puntatore valido, ossia se il primo puntatore in ptrf è NULLO, non verrebbe compiuta ALCUNA associazione, quale che fosse il valore di key. L'associazione tasto/puntatore, una volta compiuta, DEVE poter essere onorata poiché la libreria eseguirà, senza ulteriori indugi, la funzione puntata OGNI VOLTA che venga posta in attesa di eventi e si verifichi l'evento corrispondente: se poi è la funzione puntata a essere bacata e a far interrompere il programma la libreria declina fin da subito qualsiasi responsabilità.
L'ultimo argomento, ptrv, è un array di puntatori a void che DEVE avere la stessa cardinalità di ptrf: ognuno dei puntatori contenuti sarà trasmesso, come primo parametro, ordinatamente a ognuna delle funzioni puntate all'atto della richiesta esecuzione: qui i puntatori possono essere tranquillamente nulli, a patto che poi la funzione che li riceve non pretenda di utilizzarli...ma questa è (forse) una puntualizzazione superflua per programmatori che siano così evoluti da voler leggere queste note. Nei due ulteriori puntatori a int/INTEGER*4 le funzioni eseguite riceveranno, rispettivamente, il codice ASCII del tasto premuto, che ne ha causato l'esecuzione, e l'indice della finestra in cui l'evento di pressione di tasto si è concretizzato. In questo modo l'autore delle funzioni si trova in mano tutti gli strumenti necessari a far prendere opportune decisioni esecutive ai propri codici.

Viene ora fornito un programma-esempio funzionante in cui, tramite commenti, è posto in luce e in atto tutto l'ambaradan che è stato discusso.

# include <passe_par_tout.h>

/*
un array di tre oggetti di una certa struct con elementi facilmente riconoscibili
*/
struct Pappo
{int k;
Pappo(int k) : k(k) {  }} pappo[  ]{Pappo(0), Pappo(1), Pappo(2)};

/*
la funzione funza(GLuint) è quella che effettua materialmente il disegno
sulla scena di un prisma di un numero di lati pari al valore dell'argomento
ricevuto ovvero di una sfera oppure di due tronchi di cono. Ciò si ottiene
attraverso l'esecuzione della glList numero l-2 (nella penultima riga di codice)
*/
int funza(GLuint l)
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT),
glMatrixMode(GL_PROJECTION),
glCallList(l-2),
glFlush(  );}

/*
le quattro funzioni gunza, hunza, iunza e junza, tutte con la stessa segnatura,
sono associate alla pressione di tre tasti sulla tastiera secondo quanto
richiede la m_add_GL_keyevent_handlers eseguita in main immediatamente prima
di entrare nella funzione di attesa di eventi m_wait_for_events. Tutte e quattro
manifestano sull'output standard il proprio autocompiacimento per essere state
eseguite e il valore dei parametri ricevuti.
*/
void gunza(void *v, int *key, int *finestra)
{Pappo *pappo = reinterpret_cast<Pappo*>(v);
cout << "sono gunza(void*, int*, int*); sono stata innescata per la pressione di "
<< *key << " dalla finestra " << *finestra << "\n"
<< "ho ricevuto questo Pappo: " << pappo->k << endl;}

void hunza(void *v, int *key, int *finestra)
{Pappo *pappo = reinterpret_cast<Pappo*>(v);
cout << "sono hunza(void*, int*, int*); sono stata innescata per la pressione di "
<< *key << " dalla finestra " << *finestra << "\n"
<< "ho ricevuto questo Pappo: " << pappo->k << endl;}

void iunza(void *v, int *key, int *finestra)
{Pappo *pappo = reinterpret_cast<Pappo*>(v);
cout << "sono iunza(void*, int*, int*); sono stata innescata per la pressione di "
<< *key << " dalla finestra " << *finestra << "\n"
<< "ho ricevuto questo Pappo: " << pappo->k << endl;}

void junza(void *v, int *key, int *finestra)
{Pappo *pappo = reinterpret_cast<Pappo*>(v);
cout << "sono junza(void*, int*, int*); sono stata innescata per la pressione di "
<< *key << " dalla finestra " << *finestra << "\n"
<< "ho ricevuto questo Pappo: " << pappo->k << endl;}


/*
le funzioni gunza(void*) e funza(void*) vengono ricevute da m_window_GL come
penultimo argomento e quindi sono utilizzate come funzioni di ridisegnatura
di ciascuna delle due finestre OpenGL che sono state aperte sullo schermo,
ricevendo come proprio argomento l'indirizzo della variabile "otto"
dichiarata in main, per quanto concerne funza, e il puntatore nullo per quanto
concerne gunza. Al loro interno eseguono una tantum (mercé la variabile
booleana "non_inizializzata", doverosamente qualificata static): funza
la definizione delle glList che disegnano ben 38 prismi di un numero crescente
di lati e una sfera traslata dall'origine; gunza, invece, un'unica glList
che disegna una coppia di tronchi di cono di diverso colore rotati, traslati e
giustapposti uno contro l'altro. Una di tali liste, secondo il valore sito
all'indirizzo dell'argomento, e ricavato nella seconda linea del codice,
sarà poi eseguita da funza(GLuint) SEMPRE invocata al termine della funzione.
Dal canto suo gunza fa eseguire alla stessa funza(GLuint) l'unica glList di
cui dispone.
*/
int gunza(void *v)
{static bool non_inizializzata = true;
static GLuint ultima_thule;
if(non_inizializzata)
{non_inizializzata = false;
GLint spicchi = 36, fette = 12;
GLUquadric * quadrica[4] =
{gluNewQuadric(  ), gluNewQuadric(  ), gluNewQuadric(  ), gluNewQuadric(  )};
GLdouble ang, ang1, raggio = 0.4;
glNewList(ultima_thule = glGenLists(1), GL_COMPILE);
glColor3f(0.f,1.f,0.f),
gluQuadricOrientation(quadrica[0], GLU_INSIDE),
gluQuadricOrientation(quadrica[1], GLU_OUTSIDE),
gluQuadricOrientation(quadrica[2], GLU_OUTSIDE),
gluQuadricOrientation(quadrica[3], GLU_OUTSIDE),
glMatrixMode(GL_PROJECTION),
glRotatef(60.f, 1.f, 1.f, 0.f),
glTranslatef(0.f, 0.f, 0.5f),
gluCylinder(quadrica[0], raggio, raggio/2, 0.5, spicchi, fette),
glTranslatef(0.f, 0.f, 0.5f),
glColor3f(0.5f,0.f,0.f),
gluDisk(quadrica[2], 0, raggio/2, spicchi, fette),
glTranslatef(0.f, 0.f, -0.5f),
glScalef(1.f, 1.f, -1.f),
glColor3f(0.f,1.f,1.f),
gluCylinder(quadrica[1], raggio, raggio/2, 0.5, spicchi, fette),
glTranslatef(0.f, 0.f, 0.5f),
glColor3f(0.25f,0.f,0.f),
gluDisk(quadrica[3], 0, raggio/2, spicchi, fette),
glTranslatef(0.f, 0.f, -0.5f),
glTranslatef(0.f, 0.f, -0.5f),
glRotatef(-60.f, 1.f, 1.f, 0.f),
glEndList(  );}
funza(ultima_thule+2);
return 1;}

int funza(void *v)
{static bool non_inizializzata = true;
GLuint *u = static_cast<GLuint *>(v);
static GLuint ultima_thule;
if(non_inizializzata)
{non_inizializzata = false;
GLsizei k = 38;
GLint spicchi = 36, fette = 12;
GLuint j, s, l = glGenLists(k);
GLUquadric * quadrica = gluNewQuadric(  );
GLdouble ang, ang1, raggio = 0.4;
for(j=l; j <= l+k; ++j)
{glNewList(j, GL_COMPILE),
glColor3f(.5f,.6f,.7f),
s = 3+j-l,
glBegin(GL_POLYGON);
for (int i=0; i != s; ++i)
ang = i*2*M_PI/s,
glVertex3d(cos(ang),sin(ang),0.0),
glNormal3d(0.,0.,1.);
glEnd(  ),
glColor3f(0.f,.6f,.7f),
glBegin(GL_POLYGON);
for (int i=0; i != s; ++i)
ang = i*2*M_PI/s,
glVertex3d(cos(ang),sin(ang), 0.1),
glNormal3d(0.,0.,-1.);
glEnd(  ),
glColor3f(1.0f,0.f,0.f),
glBegin(GL_QUAD_STRIP);
for (int i=0; i != s-1; ++i)
ang = i*2*M_PI/s, ang1 = (i+1)*2*M_PI/s,
glVertex3d(cos(ang),sin(ang), 0.1),
glVertex3d(cos(ang),sin(ang), 0.0),
glVertex3d(cos(ang1),sin(ang1), 0.1),
glVertex3d(cos(ang1),sin(ang1), 0.0),
glNormal3d(cos(0.5*(ang+ang1)), sin(0.5*(ang+ang1)), 0.0);
glVertex3d(1.0, 0.0, 0.1),
glVertex3d(1.0, 0.0, 0.0),
glNormal3d(cos(0.5*ang1), sin(0.5*ang1), 0.),
glEnd(  ),
glEndList(  );}
glNewList(ultima_thule = glGenLists(1), GL_COMPILE);
glColor3f(1.f,1.f,0.f),
glMatrixMode(GL_PROJECTION),
glTranslatef(0.f, 0.f, 0.5f),
gluSphere(quadrica, raggio, spicchi, fette);
glTranslatef(0.f, 0.f, -0.5f),
glEndList(  );}
if(*u >= 3 && *u <= 40) funza(*u);
else funza(ultima_thule+2);
return 1;}

/*
la funzione funza(int*) viene trasmessa a m_window_GL come suo quarto
parametro, e soltanto nella sua prima esecuzione;
come tale viene eseguita UNA VOLTA e UNA SOLA all'apertura della prima
delle due finestre OpenGL che si aprono sullo schermo. Per come è scritta non fa altro
che eseguire la STESSA inizializzazione default che avrebbe eseguito passe_par_tout
se m_window_GL avesse ricevuto, al posto di QUESTA funza, il puntatore nullo.
In effetti si può apprezzare che nella seconda esecuzione di m_window_GL,
in cui si ha appunto la sostituzione di nullptr alla prima ricorrenza di funza
nella prima chiamata di m_window_GL, l'unica differenza visibile è la
scomparsa dei messaggi inviati sull'output standard tramite l'oggetto clog.
*/
int funza(int *a)
{clog << "opero inizializzazione del ciarpame OpenGL per la finestra # "
<< *a << "(" << *(a+1) << ',' << *(a+2) << ")" << endl;
GLfloat ambiente[  ] = {0.7f, 0.7f, 0.7f, 0.7f};
GLfloat diffusa[  ][2] = {0.6f, 0.6f, 0.6f, 1.f, 0.0f, 1.0f, 0.0f, 1.0f};
GLfloat riflessione[  ] = {0.7f, 0.7f, 0.3f, 1.f};
GLfloat posizione[  ] = {0.0f, 0.0f, 2.0f, 1.0f};
GLfloat direzione[  ] = {0.f, 0.f, -1.f, 0.f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambiente),
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffusa[0]),
glLightfv(GL_LIGHT0, GL_SPECULAR, riflessione),
glLightfv(GL_LIGHT1, GL_POSITION, posizione),
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffusa[1]),
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direzione),
glShadeModel(GL_SMOOTH),
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE),
glDepthFunc(GL_LEQUAL),
glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION|GL_AMBIENT_AND_DIFFUSE|GL_SPECULAR),
glEnable(GL_COLOR_MATERIAL),
glEnable(GL_LIGHTING),
glEnable(GL_LIGHT0),
glEnable(GL_LIGHT1),
glClearColor(0.0, 0.0, 0.0, 1),
glMatrixMode(GL_PROJECTION),
glLoadIdentity(  ),
glMatrixMode(GL_MODELVIEW),
glEnable(GL_DEPTH_TEST),
glLoadIdentity(  ),
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT),
clog << "operata inizializzazione del ciarpame OpenGL per la finestra # "
<< *a << "(" << *(a+1) << ',' << *(a+2) << ")" << endl;}


/*
una semplicissima funzione di disegnatura del grafico di una funzione
QUALUNQUE sul dominio [0, 2*pigreco] nel colore "colore"
*/
void disegna(double (*f)(double), int colore)
{double x[2];
m_color(&colore);
x[0] = 0.0;
x[1] = f(x[0]),
m_move(x);
for(int i=1; i != 251; ++i)
x[0] = i/250.0,
x[1] = f(2.0*M_PI*x[0]),
m_line(x);}

int main(  )
{int L, A, otto, x[  ]{100, 200}, LL[  ]{500, 500}, AA[  ]{500, 0};
char a;
double z[  ]{0, -1, 1, 1};

/*
i tre array di puntatori pt, pt2 e v sono trasmessi, come ultimi due parametri, a
m_add_GL_keyevent_handlers per realizzare le associazioni tra tasti e funzioni
*/
void (*pt[  ])(void*, int*, int*) = {gunza, hunza, iunza, nullptr};
void (*pt2[  ])(void*, int*, int*) = {hunza, junza, gunza, nullptr};
void *v[  ] = {(void*)pappo, (void*)(pappo+1), (void*)(pappo+2), nullptr};

m_startg(const_cast<char*>(""), &(L=400), &(A=400)),

/*
viene aperta una finestra "standard" di passe_par_tout: questa sarà, come di
consueto, la finestra numero 0, avrà dimensioni 400x400 pixels e verrà aperta
accostata all'angolo superiore sinistro dello schermo. Vi si disegnano i grafici
del coseno e del seno su un intero periodo.
*/
m_window(&(L=95), &(A=95)),
m_frame(z, z+1, z+2, z+3),
disegna(cos, ROSSO),
disegna(sin, BLU),

clog <<
"se vuoi disegnare un prisma digita un valore compreso tra 3 e 40;\n"
"al di fuori di questo intervallo otterrai una sfera giallastra traslata ", cin >> otto;

/*
viene aperta una finestra interfacciata con OpenGL: la sua posizione sul monitor
parte dal pixel (500, 0) e le sue dimensioni sono 500x500 pixels. La funzione
funza(int *), se fornita, viene eseguita contestualmente all'apertura della
finestra e a questa viene associata, come funzione di ridisegnatura, la funzione
funza(void*) cui ogni volta che sarà eseguita verrà trasmesso l'indirizzo in
memoria della variabile "otto".
*/
m_window_GL(LL, AA, nullptr, funza, funza, (void*)&otto);

/*
viene aperta una seconda finestra "standard" che assumerà il numero 2 nella
cronologia delle finestre; questa finestra non ha un frame.
*/
m_window(&(L=0), &(A=0)),

/*
viene aperta una seconda finestra interfacciata con OpenGL che prenderà il
numero 3; confrontare i parametri trasmessi con quelli forniti alla prima,
la numero 1 della cronologia.
*/
AA[1] = 700,
m_window_GL(LL, AA, const_cast<char*>("titolo effettivo"), nullptr, gunza, nullptr),

/*
si entra nella funzione m_string_for_events: secondo le classiche regole di
passe_par_tout se ne uscirà SOLO digitando uno dei caratteri della stringa
"abcde" mentre il fuoco è NELLA finestra OpenGL #1. Digitando uno di tali caratteri
col mouse in qualsiasi altra finestra, ovvero un carattere diverso, non succederà
NULLA.
*/
A = 1,
a = m_string_for_events(const_cast<char*>("abcde"), &A);
cout << "hai digitato '" << a << "' sulla finestra # 1" << endl;

/*
si esegue m_add_GL_keyevent_handlers per associare l'array pt e i relativi
puntatori v alla finestra OpenGL #1, connettendone l'esecuzione alla pressione
rispettivamente dei tasti 'r', 's' e 't'.
*/
m_add_GL_keyevent_handlers(&A, &(L='r'), pt, v);

/*
quindi si entra in m_wait_for_events che sarà interrotta, in base alle regole
di passe_par_tout, SOLO dalla pressione del tasto "Invio" col mouse entro una
finestra QUALSIASI. Durante la permanenza in questa funzione il programma riceve
ed elabora qualsiasi pressione dei tasti 'r', 's' e 't' nella finestra OpenGL #1
e qualsiasi click di mouse, sia su di essa sia sull'altra finestra OpenGL:
alla pressione dei tasti si vedranno eseguite le corrispondenti funzioni,
mentre a ogni click con qualsiasi pulsante del mouse si vedrà cambiare
coerentemente il punto di vista della scena, arrivando anche a poter apprezzare
la diversa colorazione della faccia opposta del prisma o del tronco di cono oppure
gli effetti dell'illuminazione sulla sfera. Finalmente, alla pressione di
"Invio" si permette al programma di proseguire...
*/
m_wait_for_events(&(A=EVENTO_ENTER));


/*
il tentativo di agganciare hunza al tasto 't' fallisce: ad esso resta associata
iunza; vanno a buon fine le associazioni di junza a 'u' e di gunza a 'v'.
Quest'ultima funzione risulta quindi agganciata sia a 'r' sia a 'v' ed è quindi
in grado di tenere comportamenti diversi secondo il tasto che l'ha fatta
eseguire. Si osservi inoltre che gunza riceve anche due "Pappo" diversi...
Tutto ciò è confermato dalla pressione dei tasti 'r' 's' 't' 'u' 'v'
fintanto che il programma resta dentro m_wait_for_events.
*/
A = 1,
m_add_GL_keyevent_handlers(&A, &(L='t'), pt2, v);
m_wait_for_events(&(A=EVENTO_ENTER));

/*
all'ultima uscita da m_wait_for_events si scrive un messaggio benaugurante sulla
finestra numero 2, usando le funzioni classiche di passe_par_tout...
*/
m_select(&(A=2)),
m_color(&(A=ROSSO)),
m_text_int(const_cast<char*>("buon lavoro con OpenGl"), x);
m_redraw(&(A=2)),

/*
e si dà il tempo di leggerlo prima di chiudere tutto.
*/
sleep(5),
m_endg(  );}

torna a OpenGL
torna daccapo




































































Il comando di compilazione e link ccg

Per poter eseguire il linking della libreria con un proprio programma residente nel file pippo.x è disponibile il comando



                              ccg

Nel nome del file che contiene il programma il suffisso .x significa ovviamente .f oppure .c oppure .C, .cpp, .cxx, .c++ secondo il linguaggio adottato; in ogni caso il comando ccg è capace di distinguere da sé quale compilatore invocare.



Esempio:

                     ccg    pippo.f
                     ccg    pippo.c
                     ccg    pippo.C

producono tutti un file eseguibile di nome

                              pippo

nella cartella corrente.



il comando ccg, nella suddetta forma breve, serve solo a fare il link con la libreria passe_par_tout; se il file pippo.x contiene chiamate a una (e una sola) libreria esterna diversa (ad esempio la libreria libmia.a) il comando ccg cambia come segue:

                       ccg pippo.x  mia  path

ove mia è il nome della libreria richiesta (si rammenta che il prefisso lib e il suffisso .a sono in genere obbligatori per files di libreria) e path è il percorso completo in cui si trova il documento libmia.a È necessario che la libreria libmia.a sia strutturata in modo coerente con la macchina che esegue la compilazione.

Se poi pippo.x chiama più di una sola libreria esterna diversa da passe_par_tout, o se si vogliono fornire comunque altre opzioni personalizzate, il comando ccg prevede alcune sintassi solo leggermente più complesse, spiegate qui appresso.

  1. Se, oltre a una propria libreria, si vuole fornire anche un proprio path per la ricerca di propri headers:

    ccg     pippo.x    mia      path      pathinclude

  2. Se si vuole fornire solo un proprio path di headers, senza fornire una propria libreria

    ccg        pippo.x       -        pathinclude
    (qui il carattere - funge da segnaposto per entrambi gli argomenti mancanti mia e path)

  3. Se si vogliono fornire opzioni particolari al compilatore e/o al linker si tenga presente che tutto quanto viene aggiunto alla linea comando dopo i primi quattro o tre argomenti (secondo le sintassi 1 o 2) passa in modo trasparente al comando di compilazione e link del sistema operativo in esercizio, e viene inserito PRIMA del nome del file di input. (La domanda che sorge spontanea, in un caso simile è: "perché non usare direttamente i comandi di sistema?")

    Ad esempio

    ccg      pippo.x       -          -          -I pathinclude

    è totalmente equivalente, anche se richiede la conoscenza delle chiavi delle opzioni, a

    ccg      pippo.x      -      pathinclude

Va osservato che la libreria è strutturata come uno shared object che carica automaticamente anche le shared libraries di sistema necessarie e che sono già fornite, in default, le seguenti opzioni:

torna daccapo



























































































Posti di lavoro utilizzabili

Qualsiasi macchina dotata di un adeguato server X11 funzionante, che (eventualmente) potrà "servire" un cliente remoto debitamente autorizzato attraverso i protocolli standard.
Va detto che la libreria, proprio per potersi fregiare del suo nome, evita di stabilire qualsiasi protocollo col Window Manager (WM) in esercizio: questo implica che eseguendo un programma che utilizza la libreria non è consentito gestire le finestre usando il WM (ad esempio distruggendole con un click del mouse sul loro bottone di chiusura) e pretendere che il programma prosegua.

torna daccapo


































































































Chiamata tipo delle funzioni della libreria

tipo(1) in fortran: call nome_funzione(arg1, arg2,..., argn)
tipo(2) in fortran: i = nome_funzione(arg1, arg2,..., argn)
tipo(3) in C o C++: i = nome_funzione(&arg1, &arg2,..., &argn);
tipo(4) in C o C++: nome_funzione(&arg1, &arg2,..., &argn);


NOTA BENE: RISPETTARE SEMPRE le lettere minuscole o maiuscole.
NOTA BENE: nella descrizione delle singole routines è SEMPRE adottata la notazione NEUTRA (ovvero diversa da tutti i 4 modi predetti e perciò NON DIRETTAMENTE UTILIZZABILE)

nome_funzione(arg1, arg2, .... , argn)


NOTA BENE: Gli esempi d'uso delle singole funzioni sono dati in C o C++ per invogliare gli utenti a "migrare" verso tale linguaggio, incomparabilmente migliore del Fortran. Tutti gli esempi sono direttamente compilabili e verificabili, utilizzando come compilatore il compilatore C++.

Fanno eccezione le due funzioni di utilità
m_conv_string
m_conv_chars
(che si usano solo in Fortran).

Le sorgenti degli esempi possono essere copiate direttamente dalla pagina tramite una normale operazione di "copia-incolla".

Convenzioni sui nomi:

fatta eccezione per le funzioni di utilità
m_conv_string e m_conv_chars
TUTTE LE FUNZIONI IL CUI NOME inizia per "m_" e contiene parole in pseudo-inglese sono dedicate a grafica su DISPLAY in tempo reale.

Viceversa tutte quelle che iniziano per "m" (senza underscore) e contengono parole in pseudo-italiano sono dedicate alla grafica PostScript su file.

Tra queste TUTTE QUELLE il cui nome contiene esplicitamente la stringa "_ps" (eccettuata, ovviamente, minizio_ps) possono essere chiamate SOLTANTO se c'è un file di output PostScript correntemente aperto.

Le funzioni che generano codice PostScript, ESSENDO DESTINATE PER LORO NATURA A PRODURRE DOCUMENTAZIONE PERMANENTE, SONO SEMPRE PIÙ ACCURATE DI QUANTO SIANO LE LORO OMOLOGHE PER DISPLAY.

torna daccapo

















































m_add_my_own_opacity(n, funzione, buff)

Questa funzione consente, a un utente evoluto, di "ignorare" l'algoritmo interno della libreria per la miscelazione dei colori in connessione con le trasparenze (cfr. funzione m_opacity) e di fornirne uno "proprio".
L'argomento n≥0, di tipo int/INTEGER*4, indica il numero della finestra cui l'algoritmo di miscelazione deve essere applicato (ne segue che ne può perfino essere fornito uno diverso per ciascuna finestra; NATURALMENTE, qualora la finestra "destinataria" non abbia il bit ATTIVA_TRASPARENZA acceso l'esecuzione della presente funzione risulta del tutto irrilevante [cfr. qui]); il secondo argomento, funzione, indica appunto il nome della funzione che contiene l'algoritmo e che, se si esegue m_add_my_own_opacity, DEVE OBBLIGATORIAMENTE essere scritta dall'utente rispettando il seguente prototipo:

         unsigned long funzione(unsigned long, unsigned long, char *)

Il terzo argomento, buff, è un puntatore a carattere (ne tengano conto gli eventuali fortranisti, così come della necessità di dichiarare la propria funzione come EXTERNAL) che viene trasmesso INTONSO alla funzione funzione come suo ultimo argomento (cfr. prototipo) nel quale, quindi, l'utente può far ricevere alla propria funzione qualsiasi genere di dato le occorra per il suo corretto funzionamento.

Negli altri due argomenti a funzione sono trasferiti rispettivamente i codici del colore (secondo il modo di trattare i colori del server X11) del pixel presente nella pixmap e di quello che "sopraggiunge" in seguito alla richiesta di disegnare, in quella stessa posizione della pixmap, un nuovo oggetto.
La funzione utilizzerà tale coppia di valori per calcolare, e restituire, il codice del colore "miscelato".
La libreria non effettua alcun test sui valori attribuiti agli argomenti della presente funzione.

Esempio d'uso:

# include <passe_par_tout.h>

unsigned long miscela(unsigned long in, unsigned long out, char *c)
{static char u = 1;
if(c && u) u = 0, cout << c << '\n';
return in | out;}

int main(int narg, char ** arg, char ** env)
{const char *u="8", *cici = "cici";
double xmin, ymin, xmax, ymax, x[2], t[2],
o = atof(arg[1]), d = atof(arg[2]);
int K, L, i,
colori[  ]={ROSSO, VERDE, BLU, GIALLO, MAGENTA, CIANO, NERO};
xmin = ymin = -10.0, xmax = ymax = 10.0,
K = L = 600,
m_startg(const_cast<char *>(u), &K, &L),
K = L = 95,
K |= OMBREGGIA_FINESTRA,
L |= ATTIVA_TRASPARENZA,
L |= FINESTRA_DOPPIA,
m_window(&K, &L);
if(narg > 3) K = 1, L=ROSSO, m_use_as_pixmap(&K, &L);
if(narg > 4) m_add_my_own_opacity(&(K=0), miscela, const_cast<char *>(cici));
K=1, t[0] = 6.0, t[1] = 3.0,
m_frame(&xmin, &ymin, &xmax, &ymax), x[0] = 0.0;
for(i=0; i < BIANCO; i++)
m_color(colori + i),
x[1] = -4.0 + i,
m_opacity(&o),
m_ellipse(x, t, &K),
o += d;
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}



Il precedente programma, tratto da quello fornito come esempio d'uso della funzione m_opacity, illustra un utilizzo della presente funzione. Si osservi che il puntatore a carattere (terzo argomento trasferito a m_add_my_own_opacity) qui viene usato solamente per mostrare che viene trasferito correttamente. Si osservi anche che, quantunque sia stata lasciata nel programma la richiesta di esecuzione di m_opacity, questa risulta IRRILEVANTE se viene eseguita m_add_my_own_opacity, il che avviene se sulla linea comando appaiono almeno quattro argomenti opzionali.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

torna daccapo

Uso delle trasparenze

m_opacity(o)

In condizioni standard la libreria disegna punti, linee e aree in modo opaco, ossia in modo tale che, nel caso in cui diversi oggetti si sovrappongano, risulti INTERAMENTE visibile solo quello disegnato più di recente, mentre le parti di oggetti sottostanti, anche oggetti interi, sono definitivamente invisibili.
L'introduzione del concetto di trasparenza permette, come è intuibile, di vedere oggetti già disegnati in precedenza attraverso oggetti sovrapposti.
La fruizione di questa possibilità, utile in diversi contesti, è subordinata all'accensione del bit ATTIVA_TRASPARENZA nel secondo argomento fornito a m_window all'atto dell'apertura della finestra.
Una finestra così creata continua a funzionare in modo standard finché non sia eseguita, per quella finestra, la funzione m_opacity che riceve un solo argomento di tipo double/REAL*8 e di valore compreso tra 1.0: totale opacità, ossia condizioni di funzionamento standard; o 0.0: totale trasparenza, ossia oggetti neppure disegnati perché invisibili.
La funzione m_opacity può essere eseguita quante volte si vuole per la stessa finestra: l'ultimo valore di opacità impostato si applica a tutti i disegni successivi, né più né meno di quanto accade, ad esempio, per la funzione m_color; se invece viene eseguita per una finestra che non fosse stata creata col bit ATTIVA_TRASPARENZA acceso equivale a nessuna operazione.

Il colore risultante con cui sono disegnate le parti di oggetto sovrapposte è ottenuto, in mancanza di avviso contrario, con un unico algoritmo interno alla libreria; se l'utente desidera fornire un proprio algoritmo di miscelazione dei colori, utilizza la funzione m_add_my_own_opacity.
In ogni caso il colore risultante NON È considerato dalla libreria come un nuovo colore e NON occupa un posto nella tavolozza dei colori (cfr. m_new_color).

Va altresì tenuto conto del fatto che ANCHE IL COLORE DELLO SFONDO concorre a determinare il colore risultante degli oggetti trasparenti, a meno che non sia stata richiesta un'altezza della finestra pari a un numero dispari di pixels oppure si sia eseguito l'OR binario del secondo argomento trasferito a m_window con la costante predefinita SFONDO_OPACO.

Se una finestra con trasparenze è ombreggiata da un file PS ombra quest'ultimo viene sempre prodotto come se per la finestra in questione fosse stata eseguita m_use_as_pixmap, anche quando ciò non sia avvenuto. Questo per l'intrinseca opacità del linguaggio PostScript vettoriale.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** arg, char ** env)
{char *u=const_cast<char *>("");
double xmin, ymin, xmax, ymax, x[2], t[2],
o = atof(arg[1]), d = atof(arg[2]);
int K, L, i,
colori[  ]={ROSSO, VERDE, BLU, GIALLO, MAGENTA, CIANO, NERO};
xmin = ymin = -10.0, xmax = ymax = 10.0,
K = L = 600,
m_startg(u, &K, &L),
K = L = 95,
K |= OMBREGGIA_FINESTRA,
L |= ATTIVA_TRASPARENZA,
L |= FINESTRA_DOPPIA,
m_window(&K, &L);
if(narg > 3) K=1, L=ROSSO, m_use_as_pixmap(&K, &L);
t[0] = 6.0, t[1] = 3.0,
m_frame(&xmin, &ymin, &xmax, &ymax), x[0] = 0.0;
for(i=0; i < BIANCO; i++)
m_color(colori + i),
x[1] = -4.0 + i,
m_opacity(&o),
m_ellipse(x, t, &K),
o += d;
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}

Questo programma disegna sette ellissi colorate, nei colori standard, e sovrapposte. Lo si esegua con diverse scelte dei due argomenti sulla linea comando, il primo essendo il livello di opacità della prima ellisse e il secondo l'incremento di opacità per le ellissi successive.
Si confrontino i risultati delle due esecuzioni
     a.out  1  0 (comportamento standard)

e
     a.out  0  0 (trasparenza totale)

Si provi anche l'incidenza del colore dello sfondo, ad esempio facendo in modo che sia eseguita m_use_as_pixmap e modificando a piacimento il valore del suo secondo argomento.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

torna daccapo

Nota sulle animazioni

La libreria produce due tipi di animazioni: un tipo portabile e un tipo in formato riconoscibile solo da questa stessa libreria.
Al primo tipo provvedono le due funzioni m_write_photogram e m_mount_film, al secondo le tre funzioni m_write_owned_photogram, m_mount_owned_film e m_animate.
Le animazioni del primo tipo sono realizzate appoggiandosi a programmi esterni alla libreria e che generalmente si trovano installati in (quasi) tutti i sistemi riconducibili alla famiglia Unix, come è Linux; nel caso che programmi di questo genere siano assenti, o siano sostituiti da altri meno consueti o si trovino in percorsi non standard la libreria fa ricorso a variabili d'ambiente dedicate (cfr.) in modo da potere, in ogni caso, usufruire di un programma acconcio oppure anche evitare del tutto di provare a realizzare delle animazioni.
Molti dei più usuali programmi di conversione, e in particolare quello usato in default, vale a dire il programma convert della suite ImageMagick, risultano assai lenti nel montaggio delle animazioni, ed ecco il motivo per cui la libreria esegue tale mandato preferibilmente in modo batch, e presentano inoltre problemi di limitazione al numero dei fotogrammi gestibili che, talora, potrebbero risultare inaccettabili. D'altra parte le animazioni realizzate nel primo modo hanno l'innegabile pregio di poter essere trasportate (quasi) ovunque, senza bisogno di portarsi dietro anche la presente libreria.

Viceversa le animazioni del secondo tipo non si appoggiano su alcunché di esterno alla libreria, ma proprio per questo possono essere usate solo su macchine che l'abbiano installata. Hanno il pregio di non risentire di alcun limite sul numero di fotogrammi, tranne la capienza del disco e/o della memoria, e di non ricorrere all'ambiente per altra ragione che non sia semplicemente la conoscenza della cartella in cui scaricare, temporaneamente o definitivamente, i fotogrammi dell'animazione.
La funzione in più rispetto al primo tipo di animazioni è semplicemente il player delle animazioni stesse, non necessario per il primo tipo in quanto già disponibile sul sistema operativo in base alla suite di programmi esterni cui si sia fatto ricorso.

NOTA SUL PASSATO:
L'introduzione del secondo tipo di animazioni comporta che, se mai qualcuno avesse conservato da qualche parte un file binario qualsivoglia che sia stato prodotto da versioni precedenti della presente libreria (ipotesi remotissima, ma non si sa mai), per continuare a usarlo nella versione presente dovrà modificarlo, tramite un programmino C di quattro righe, inserendo all'offset 6 due bytes, non uno di più non uno di meno, il cui contenuto sia la rappresentazione binaria dello short int di valore 1 (uno) sull'architettura hardware che aveva generato il file.
In difetto di ciò il file in questione è buono da essere buttato via e calpestato dagli uomini.

NOTA SUL PRESENTE:
La contropartita positiva della nota precedente consiste nel fatto che i file binari prodotti attualmente transitano da un'architettura all'altra intonsi e sono ovunque interpretati correttamente.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

torna daccapo

Elenco delle funzioni

NOME FUNZIONE          OPERAZIONE COMPIUTA
__________________________________________________________________


Funzioni di servizio



m_conv_string converte stringhe fortran
m_conv_chars converte stringhe fortran
m_inquire_monitor_size legge le dimensioni dello schermo
m_toggle_mouse_save_right inibisce e ripristina salvataggio di pixmap
m_toggle_message inibisce e ripristina messaggi
minverti_messaggio inibisce e ripristina messaggi
m_sound_message inibisce/ripristina il suono del "bell"
msuono_messaggio inibisce/ripristina il suono del "bell"
mversione_passe_par_tout scrive la data di installazione
m_get_current_pointer_position riceve la posizione del mouse (senza click)
m_toggle_pointer_motion inibisce/ripristina il rilevamento di MotionNotify
m_move_pointer sposta il mouse in una data posizione
m_move_pointer_int sposta il mouse in una data posizione
m_map_fonts seleziona l'ordine dei font per il contorno


m_multi_threaded_program attiva un ambiente operativo multithread


Funzioni grafiche a schermo

m_prestartg allocazione di memoria
m_startg inizializzazione grafica DISPLAY
m_endg fine grafica DISPLAY



m_open_display connessione a un nuovo DISPLAY
m_close_display disconnessione di un DISPLAY
m_select_display attivazione di un DISPLAY connesso
m_which_display restituisce il DISPLAY corrente



m_place_window colloca (e titola) la finestra
m_window apertura finestra
m_opacity impostazione della trasparenza
m_add_my_own_opacity trasparenza personalizzata
m_snap_shadow chiusura/riapertura di PostScript ombra
m_save_window scrive su file una finestra
m_load_window legge da file una finestra
m_clear cancellazione finestra
m_close chiusura finestra
m_select indirizza output su finestra
m_select_frame indirizza output su sistema di riferimento
m_which_window indica quale finestra sta ricevendo output
m_which_frame indica quale sistema di riferimento sta ricevendo output
m_redraw ridisegnatura di una finestra



m_log_scales definisce scale logaritmiche
m_frame definizione coordinate
m_reset_frame ri-definizione coordinate
m_multiframe definizione coordinate multiple
m_quote quotatura del disegno
m_color_frame stabilisce il colore del riferimento
m_how_clip seleziona il modo di clipping



m_move movimento "a pennino alzato"
m_line movimento "a pennino abbassato"
m_point tracciamento di un punto
m_symbol scelta del simbolo
m_size_symbol modifica la grandezza del simbolo
m_set_size_symbol imposta grandezza iniziale dei simboli
m_reset_size_symbol ripristina grandezza iniziale dei simboli
m_dash scelta del tratteggio
m_thickness scelta dello spessore delle linee
m_how_join_lines scelta dello stile di giunzione delle linee
m_vector disegna un vettore
m_ellipse disegna un'ellisse
m_arc disegna un settore ellittico
m_target disegna un diagramma circolare, come il bersaglio delle freccette
m_polygon disegna un poligono "pieno"
m_curve traccia una spline cubica o una curva di bézier
m_modify_bezier sposta interattivamente i punti di bézier
m_text_ext "ingombro" di stringhe
m_text scrittura di stringhe
m_font seleziona un fonte di caratteri
m_font_by_name seleziona un fonte di caratteri
m_reset_font rimette il fonte iniziale di caratteri
m_map_font altera la precedenza per il fonte di caratteri per le quote
m_recover_font rimette un fonte già richiesto



m_move_int movimento raster "a pennino alzato"
m_line_int movimento raster "a pennino abbassato"
m_point_int tracciamento raster di un punto
m_vector_int disegno raster di un vettore
m_ellipse_int disegno raster di un'ellisse
m_arc_int disegno raster di un settore ellittico
m_target_int disegno raster di un diagramma circolare
m_polygon_int disegno raster di un poligono "pieno"
m_text_int scrittura raster di stringhe



m_mouse lettura del cursore
m_mouse_from_any lettura del cursore
m_mouse_int lettura del cursore
m_mouse_int_from_any lettura del cursore
m_wait_for_events funzione per attesa di un evento
m_loop_for_events loop per attesa eventi
m_string_for_events loop per attesa eventi con selezione dell'uscita
m_modified_key_events loop come sopra, ma con tasti modificatori.
m_wait_for_microseconds pausa temporale
m_flush output immediato del buffer X11
m_shutdown_event_handler disattiva il gestore di eventi interno della libreria
m_restart_event_handler riattiva il gestore di eventi interno della libreria



funzioni del Widget set



m_use_as_pixmap usa una finestra come pixmap
m_clear_pixmap cancella una pixmap
m_fill_pixmap riempie una pixmap
m_fill_int_pixmap riempie una pixmap
m_show_pixmap copia una pixmap in una finestra
m_remove_pixmap toglie una pixmap da una finestra
m_save_pixmap scrive su file la pixmap corrente
m_load_external_pixmap usa una pixmap esterna come sfondo
m_save_pixmap_to_load salva la finestra attuale in modo da poter essere "ricaricata" tramite m_load_external_pixmap
m_load_tiles carica un numero arbitrario di pixmaps esterne
m_load_diaphanous_tiles come la precedente, con effetto di trasparenza
m_move_tiles sposta pixmaps caricate con una delle due precedenti funzioni
m_hide_tiles omette visualizzazione di pixmaps caricate con m_load_*tiles
m_unhide_tiles ripristina visualizzazione di pixmaps oscurate dalla precedente
m_unload_tiles rimuove definitivamente pixmaps
m_change_pixmap_background fa quello che dice il nome



m_color scelta del colore
m_get_color lettura del colore di un pixel
m_new_color definizione di un nuovo colore in modo RGB
m_new_color_hcv definizione di un nuovo colore in modo HCV
m_insert_color inserimento di un nuovo colore in posizione arbitraria nella tavolozza
m_insert_color_hcv come la precedente, ma in modo HCV
m_replace_color sostituzione di un colore nella tavolozza
m_remove_color eliminazione di un colore dalla tavolozza
m_remap_colors cambiamento dell'ordine dei colori nella tavolozza



m_legend crea una legenda per la finestra
m_move_legend sposta la legenda in una posizione diversa
m_recolor_legend cambia i colori della legenda
m_hide_legend toglie la legenda dalla finestra, conservandola in memoria
m_unhide_legend rivisualizza una legenda nascosta
m_destroy_legend distrugge (definitivamente) la legenda liberando la memoria associata



m_get_server_info interroga il server X11 per ottenere dati globali
m_get_window_info interroga il server X11 a proposito di una finestra
m_add_my_own_redraw "aggiunge" una propria routine di ridisegnatura
m_add_my_own_event_handler "aggiunge" un proprio gestore di eventi



m_write_photogram genera un fotogramma per un'animazione
m_mount_film effettua il montaggio di fotogrammi in un'animazione



m_write_owned_photogram genera un fotogramma per un'animazione in formato proprietario
m_mount_owned_film effettua il montaggio di fotogrammi proprietari in un'animazione
m_animate riproduce un filmato proprietario







Funzioni grafiche PostScript

mrapporto_assi preseleziona forma della figura PostScript
minizio_ps apertura e inizializzazione PostScript
mfine_ps chiusura definitiva PostScript



mmarca_ps colloca o restituisce un "mark" sul file
mmarca_stringa_ps scrive una stringa nel file corrente
mcancella_ps cancella il file PS tra due "marks"
mrimuovi_ps rimuove dal file PS la parte compresa tra due stringhe
mchiudi_ps chiusura di singolo file PostScript
mindirizza_ps cambio del file PostScript attivo
mqualefile_ps indica quale file è attivo



mscalelogaritmiche_ps definisce scale logaritmiche
mpaginaA4_ps accesso alla pagina A4 intera
mfinestra_ps definizione coordinate
mfattore_scala_ps fattore di scala per quote
morigine_ps scelta dell'origine
mcontorno_ps disegno del riferimento e clipping
mfora_contorno_ps disabilita il clipping
mricontorna_ps ripristina il clipping
massegna_bounding_box_ps assegna la bounding box



mcomponi_accento scrittura di caratteri accentati
mquotature_ps scrittura delle quotature
mquotature_con_stringhe_ps "
mtitoli_ps titolazione della figura
mscrivi_ps scrittura di stringhe
mscrivi_quasi_come_TeX_ps scrittura di stringhe con sintassi TeX
mfonte_ps scelta del fonte di caratteri
mcercafonte_per_nome_ps scelta del fonte tramite il nome



mmuovi_ps movimento "a penna alta"
mlinea_ps movimento "a penna bassa"
mspessore_linea_ps spessore della linea tracciata
mgiunzione_linee_ps giunzione della linea tracciata
mpunto_ps marcamento di punti
msimbolo_ps scelta del simbolo
mgrandezza_simbolo_ps grandezza del simbolo scelto
mripristina_grandezza_simbolo_ps grandezza default del simbolo
mtratteggio_ps scelta del tratteggio
mfreccia_ps disegno di un vettore
mellisse_ps disegna un'ellisse
marco_ps disegna un settore ellittico
mbersaglio_ps disegna un diagramma circolare
mpoligono_ps disegna un poligono "pieno"
mcurva_ps traccia una spline cubica



msfondo_ps scelta del colore per lo sfondo
mcolore_ps scelta del colore
mcolore_rgb_ps scelta del colore in modo RGB
mcolore_hcv_ps scelta del colore in modo HCV



mlegenda_ps controparte PS di m_legend
msposta_legenda controparte PS di m_move_legend
mricolora_legenda controparte PS di m_recolor_legend
mnascondi_legenda controparte PS di m_hide_legend
mrivela_legenda controparte PS di m_unhide_legend
mdistruggi_legenda controparte PS di m_destroy_legend



minizia_bitmap inizializzazione di bitmap
mdistruggi_bitmap distruzione di bitmap
mcancella_bitmap cancellazione di bitmap
mcancella_colore_bitmap " " con colore di sfondo
mtrasforma_bitmap coordinate assolute di bitmap
mcambia_bitmap accesso al pixel in una bitmap
mstampa_bitmap_ps codice PostScript per bitmap
mclasse_bitmap specifica la classe di una bitmap
mseleziona_bitmap seleziona una classe specificata



mcodifica_colore_bitmap definisce il colore di un pixel nella classe di bitmap selezionata
mcodifica_colore_hcv_bitmap come la precedente, ma in modo HCV



mimpagina impaginatore di files







Funzioni grafiche "3D"

La libreria non può effettuare della grafica tridimensionale vera e propria senza rinunciare al suo stesso nome. Tuttavia è fornito un minuscolo gruppo di funzioni che "simula" un istogramma tridimensionale sotto forma di colonne del tipo "Lego". Un primo sottogruppo effettua tale operazione su schermo; un secondo sottogruppo, costituito da una sola funzione, la compie su file PostScript.

Il primo gruppo comprende

m_use_as_Lego dedica una finestra a un istogramma 3D
m_draw_Lego disegna un istogramma 3D
m_clear_Lego cancella un istogramma 3D


Il secondo comprende

mdisegnaLego_ps disegna un istogramma 3D

torna daccapo

























































m_multi_threaded_program(  )

Questa funzione priva di argomenti deve essere la prima a essere eseguita, obbligatoriamente ancora prima di m_startg, qualora si intenda eseguire funzioni della libreria in un programma strutturato in threads multipli. Eseguirla per un programma ordinario può condurre a comportamenti non definiti del server grafico: per questo è stata tenuta distinta e separata da ogni altra funzione e NON, per esempio, tacitamente eseguita dall'interno di m_startg.
È esclusiva responsabilità del programmatore eseguirla SE e NEL MOMENTO IN CUI occorra. Non si ritiene necessario un esempio d'uso.

Va detto che la libreria, quando viene istruita, attraverso l'esecuzione di questa funzione, a lavorare in un contesto multithreaded, tende ad autoproteggersi, quanto più sia possibile, contro l'eventualità che si producano data races di threads concorrenti.
Per questo, in tale contesto, NON EFFETTUA esecuzioni implicite della funzione m_redraw che invece si produrrebbero, in contesti a thread singolo, per il semplice ingresso del cursore del mouse in una delle finestre grafiche, o per altri eventi "inconsciamente" generati dall'esecutore del programma, e questo per evitare l'esecuzione implicita di m_select e il conseguente data race con un thread che stesse simultaneamente disegnando in un'altra finestra.

Quando però un programma multithreaded volesse anche usufruire di finestre del widget set (situazione evidentemente riscontrabile in programmi di qualche pregio), NON ESSENDO POSSIBILE, con TOTALE evidenza, che la libreria disconosca quegli stessi eventi che fanno funzionare i bottoni dei menu, e non essendo NEPPURE possibile, con ALTRETTALE evidenza, intervenire sul codice già compilato delle funzioni del server grafico, dovrà essere l'autore del programma a proteggersi contro i data races che il proprio codice possa generare. Qui si forniscono alcuni suggerimenti, senza pretesa che siano esaustivi per tutte le situazioni che potrebbero prodursi.



... in attesa di esempi ...

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript


m_modify_bezier(n)

Questa funzione, il cui unico argomento di tipo int/INTEGER*4 indica la finestra cui si applica (n>=0), equivale a "nessuna operazione" se sulla finestra in questione non è stata disegnata alcuna curva di Bézier (cfr m_curve). In caso contrario realizza un'esecuzione implicita di m_select e innesca un ciclo infinito interrotto SOLTANTO dalla pressione del tasto 'z' (non importa se minuscolo o maiuscolo) mentre la finestra detiene l'input focus (cfr interazioni con mouse e tastiera).
Per tutta la durata del ciclo nella finestra selezionata sono visualizzate solo le curve di Bézier in essa contenute, complete dei relativi punti di controllo, visualizzati comunque, indipendentemente da quel che era stato fornito alla funzione m_curve nel suo secondo argomento.
È a questo punto possibile modificare interattivamente il numero e la posizione dei punti di controllo e, di conseguenza, l'aspetto e l'ordine della relativa curva di Bézier. In particolare

All'uscita dal ciclo infinito la finestra viene interamente ridisegnata (ricompaiono tutti gli altri disegni messi fuori causa durante il ciclo) con le curve di Bézier nel loro nuovo aspetto.

N.B.
Se la finestra selezionata è sottoposta a trasparenza, anche questa è sospesa durante il ciclo di editing. Sarà ripristinata solo all'uscita così come saranno non disegnati i punti di controllo se così era stato stabilito all'atto della creazione delle curve attraverso la funzione m_curve.

N.B.
Se i punti di controllo sono marcati con simboli molto grandi che vanno a "coprire" qualche altro disegno nella finestra il loro eventuale spostamento può lasciare delle "lacune" nella posizione precedentemente occupata. A questo inconveniente si porrà rimedio in base al numero di rimostranze.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n[5], K, L;
double * x, y[4];
n[0] = atoi(args[1]),
n[1] = 100, n[2] = 1, n[3] = 2, n[4] = 8;
x = new double[2*(n[0]+1)];
for(i=0; i <= n[0]; i++)
x[2*i] = static_cast<double>(i),
x[2*i+1] = -1.0 + 2.0 * (i % 2);
y[0] = x[0] - 0.05 * (x[2*n[0]] - x[0]),
y[2] = x[2*n[0]] + 0.05 * (x[2*n[0]] - x[0]),
y[2] += (double)(y[0] == y[2]),
y[1] = -1.05, y[3] = 1.05,
m_startg(const_cast<char *>(""), &(K=700), &(L=700)),
m_window(&(K=OMBREGGIA_FINESTRA), &(L=FINESTRA_DOPPIA)),
m_frame(y, y+1, y+2, y+3),
m_color(&(i=MAGENTA)),
m_curve(x, n),
m_color(&(i=NERO)),
n[0] *= -1,
m_curve(x, n),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_modify_bezier(&(K=0)),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}


Questo programma traccia una spline cubica color magenta e una curva di Bézier nera con punti di controllo verdi, di ordine pari al numero fornito sulla linea comando, dopo di che consente l'editing della curva di Bézier attraverso la funzione qui descritta. Al termine viene anche ottenuto un file PostScript dato che la finestra era ombreggiata.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

























































m_curve(x, n)
m_curve_int(j, n)
mcurva_ps(x, n)

Si tratta della stessa funzione, denominata diversamente per indirizzarsi rispettivamente (secondo le regole della libreria) alla grafica su schermo, alla grafica su schermo rasterizzata e a quella su file PS.
Interpola un insieme di punti del piano (ordinati secondo ascissa crescente) facendovi passare una spline cubica e disegnandola sulla finestra (o sul file) in esercizio (cfr. m_select e mindirizza_ps). L'argomento x è un puntatore a 2(k+1) valori double/REAL*8, ove k è il primo valore puntato dal puntatore a int/INTEGER*4 n trasferito come secondo argomento.
L'argomento j per la versione m_curve_int è un puntatore a int/INTEGER*4 che svolge lo stesso ruolo di x relativamente alla grafica rasterizzata. In x vanno ordinatamente trasferite (secondo le ascisse crescenti) le coordinate di k+1 punti del piano in accordo con lo schema (x{2i},x{2i+1})=(ascissa,ordinata) dell'i-esimo punto.
In j andranno analogamente inserite le coordinate dei punti in versione "pixel" (cfr. tutte le funzioni raster) Il secondo argomento n deve puntare anche un secondo valore int/INTEGER*4 che serve a dire alla funzione quanti punti vadano inseriti in ogni intervallo delimitato dai punti assegnati al fine di tracciare la spline.
Le funzioni restituiscono al chiamante, diversamente da altre funzioni della libreria, un puntatore a double (i fortranisti sono esclusi da questo beneficio) che indirizza i coefficienti calcolati per la spline; precisamente tale puntatore indirizza 4k valori, i primi k essendo i coefficienti dei termini lineari della spline, i secondi k quelli quadratici, i terzi k quelli cubici e gli ultimi k i termini noti. Lo spazio di memoria occupato da questo puntatore NON deve essere rilasciato dal chiamante dato che ci pensa la libreria all'atto della chiusura della finestra e/o del file per cui sono state invocate queste funzioni; per questa stessa ragione gli indirizzi in cui il chiamante eventualmente riceva i valori restituiti NON sono più da ritenere affidabili alla chiusura delle finestre e/o dei files relativi.
Se le funzioni non potessero essere eseguite (nessuna finestra grafica accessibile, nessun file PS aperto, o qualunque altra causa) sarà restituito il puntatore nullo (a maggior ragione NON rilasciabile).

Se il primo valore intero puntato dall'argomento n è negativo ne viene usato il valore assoluto, che viene anche restituito in uscita nel puntatore stesso; in questo caso, però, le 2*(1+abs(n{0})) coordinate fornite come primo argomento sono interpretate come coordinate dei punti di controllo di una curva di Bézier di ordine abs(n{0}) e il puntatore n deve puntare fino a cinque valori interi anziché solo due.
Il secondo valore puntato ha lo stesso significato discusso sopra; il terzo deve esserci e assume un significato booleano: se falso non c'è altro da aggiungere; se invece è vero significa che si vuole evidenziare la posizione dei punti di controllo della curva e allora devono essere forniti anche gli ultimi due valori puntati da n, da usarsi rispettivamente per selezionare colore e simbolo (cfr. m_color e m_symbol) con cui tali punti sono marcati.
L'utilità delle curve di Bézier si ha soprattutto in applicazioni CAD, ma anche in un programma di analisi di dati potrebbero essere di valido ausilio, specialmente in connessione con la possibilità di poterle editare interattivamente (cfr. m_modify_bezier); si potrebbe, ad esempio, trovare interattivamente un "fit" a occhio di un insieme di dati tramite una curva che vi si adatterebbe al meglio e di cui si avrebbe sempre a disposizione, in maniera automatica, l'espressione analitica.
L'ultima cosa da dire, nel caso si sia chiesta una curva di Bézier, è che il valore restituito dalle funzioni è sempre il puntatore nullo, non essendovi di fatto alcunché di significativo da restituire ed essendo difficilmente ipotizzabile l'eventualità che, in questo caso, si possa incorrere in un errore di esecuzione.

Esempi d'uso:

#include <passe_par_tout.h>
#ifndef Q
#define Q 5
#endif

int main(int narg, char * * args, char * * env)
{double *x = new double[Q*2], *s = new double[Q*2],
z[  ] = {-M_PI, -1.2, M_PI, 1.2}, y[2];
int i, K, L, n[2], *X = new int[Q*2], *S = new int[Q*2];
for(i=0; i < Q; i++)
s[2*i] = x[2*i] = -M_PI + i * 2.0 * M_PI / (Q-1.0),
x[2*i+1] = cos(x[2*i]), s[2*i+1] = sin(s[2*i]),
S[2*i] = X[2*i] = static_cast<int>((x[2*i]+M_PI)*600/(2.0 * M_PI)),
X[2*i+1] = 550 - static_cast<int>((x[2*i+1]+1.0)*250),
S[2*i+1] = 550 - static_cast<int>((s[2*i+1]+1.0)*250);
m_startg(const_cast<char *>(""), &(K=600), &(L=600)),
m_window(&(K=OMBREGGIA_FINESTRA), &(L=0)),
m_frame(z, z+1, z+2, z+3),
y[0] = z[0], y[1] = cos(y[0]), m_move(y);
for(i=0; i < 501; i++)
y[0] = -M_PI + i * M_PI / 250.0, y[1] = cos(y[0]), m_line(y);
m_color(&(K=BLU)),
y[0] = z[0], y[1] = sin(y[0]), m_move(y);
for(i=0; i < 501; i++)
y[0] = -M_PI + i * M_PI / 250.0, y[1] = sin(y[0]), m_line(y);
m_color(&(K=ROSSO)),
n[0] = Q-1, n[1] = 100,
m_curve(x, n),
m_curve(s, n),
m_curve_int(X, n),
m_curve_int(S, n),
m_loop_for_events(&(K='z'), &(L=-1)),
m_endg(  ),
minizio_ps(const_cast<char *>("pappo.ps"), &(y[0]=1.0), &(y[1]=1.0)),
mfinestra_ps(z, z+1, z+2, z+3),
mcontorno_ps(&(L=1)),
mcurva_ps(x, n),
mfine_ps(  );}

Questo programma traccia le spline cubiche che passano per Q punti presi sul grafico delle funzioni cos e sin su un intero periodo.
Sono esemplificate tutte le versioni della funzione e anche l'uso di un file PS ombra connesso con la finestra grafica. Le funzioni "esatte" sono tracciate con 500 segmenti, mentre le spline con 100 in ogni sottointervallo (con Q=5) e in colore diverso.
Il programma è solo indicativo e scritto malissimo, abusando di costanti esplicitamente inserite nel codice.


# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n[5], K, L;
double * x, y[4], z[  ]={1.0, 1.0};
n[0] = atoi(args[1]), n[1] = 100,
n[2] = 1, n[3] = VERDE, n[4] = ASTERISCO;
x = new double[2*(n[0]+1)];
for(i=0; i <= n[0]; i++)
x[2*i] = static_cast<double>(i),
x[2*i+1] = -1.0 + 2.0 * (i % 2);
y[0] = x[0] - 0.05 * (x[2*n[0]] - x[0]),
y[2] = x[2*n[0]] + 0.05 * (x[2*n[0]] - x[0]),
y[2] += (double)(y[0] == y[2]),
y[1] = -1.05, y[3] = 1.05,
n[0] *= -1,
m_startg(const_cast<char *>(""), &(K=700), &(L=700)),
m_window(&(K=OMBREGGIA_FINESTRA), &(L=0)),
m_frame(y, y+1, y+2, y+3),
i = n[0],
m_curve(x, n),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  ),
minizio_ps(const_cast<char *>("pappo.ps"), z, z+1),
mfinestra_ps(y, y+1, y+2, y+3),
mcontorno_ps(&(L=1)),
n[0] = i,
mcurva_ps(x, n),
mfine_ps(  );}

Questo programma traccia una curva di Bézier, di ordine fornito sulla linea comando, tanto su una finestra grafica ombreggiata da un file PS ombra quanto su un file PS esplicitamente aperto dal programma nella cartella corrente e di nome pappo.ps.
I valori puntati da n richiedono che i punti di controllo siano evidenziati con asterischi di colore verde.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

























































m_conv_string(s, l, j, log)

utile solo per programmi FORTRAN e utilizzabile SOLO come FUNCTION (cfr. informazioni sulle chiamate tipo), serve a convertire la stringa s, di lunghezza dichiarata l, nell'array INTEGER*2 j (di lunghezza l/2). log è una variabile logica che vale true solo se il programma deve girare su macchine LSB, altrimenti vale sempre false. È l'unica funzione della libreria che dipende in qualche modo dall'architettura della macchina ospite.

Esempio d'uso:

       Character*20 s
       Integer*2  j(10)
        .
        .
       s = 'abcdefghijklmnopqrst '
       l = 20
       i = m_conv_string(s, l, j, .false.)

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































m_conv_chars(s, l, c)

utile solo per programmi FORTRAN e utilizzabile SOLO come FUNCTION (cfr. informazioni sulle chiamate tipo), serve a convertire la stringa s, di lunghezza dichiarata l, nell'array di caratteri c che può essere trasferito come argomento alle funzioni della libreria che richiedono stringhe in ingresso; più efficace e più portabile di m_conv_string che viene mantenuta per compatibilità con vecchi programmi.

Esempio d'uso:

character*11 file
character cfile(0:11)
file = 'abcdefghijk'
i = m_conv_chars(file, 11, cfile)

A questo punto cfile è pronto per essere usato con qualsiasi funzione della libreria. Si noti la lunghezza dell'array cfile.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































m_shutdown_event_handler(n)

Serve a inibire l'attività dei gestori di eventi interni della libreria; l'argomento n è di tipo INTEGER*4/int e se non è negativo serve a inibire i gestori di eventi solo relativamente agli eventi che coinvolgono la finestra di indice n (cfr. m_window). Se invece n è negativo si inibiscono i gestori di eventi indipendentemente dalla finestra in cui l'evento accade.
Questa routine va usata con cautela e preferibilmente da parte di utenti capaci di fornire i propri gestori di eventi (cfr. m_get_server_info e m_get_window_info) perché dopo che è stata eseguita le chiamate a m_wait_for_events, m_loop_for_events, m_string_for_events e m_modified_key_events diventano inefficaci.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































































m_restart_event_handler(n)

Funzione "contraria" a m_shutdown_event_handler serve a riattivare i gestori di eventi interni della libreria che fossero stati disattivati. L'argomento n ha lo stesso significato e le stesse funzioni descritte per m_shutdown_event_handler.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"











































































































m_get_server_info(  )

Funzione senza argomenti, può essere eseguita SOLO dopo che sia già stata eseguita m_startg (ovviamente). Restituisce in uscita un puntatore a una struttura di tipo Data_X (typedefinita nell'header file passe_par_tout.h). Gli elementi della struttura sono i seguenti:

Display *display;
Colormap colormap;
XtAppContext contesto;
Visual *visual;
unsigned int depth;

Si ritiene che i fruitori di tale funzione siano già abbastanza esperti da comprenderne il significato e le implicazioni.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"































































































m_get_window_info(n)

Funzione che interroga la finestra di indice n (cfr. m_window), necessariamente aperta, e che restituisce in uscita un puntatore a una struttura di tipo Data_Win (typedefinita nell'header file passe_par_tout.h).
Gli elementi di tale struttura sono:

Window window;
Widget widget, shell;
GC contesto_grafico;
Drawable drawable;
int offset[2];
Dimension dimen[2];
Pixmap pixmap;

Quest'ultimo elemento è NULL se la finestra non è stata dedicata a una pixmap (cfr. m_use_as_pixmap). Si ritiene che i fruitori di tale funzione siano già abbastanza esperti da comprenderne il significato e le implicazioni.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"











































































































m_add_my_own_redraw(n, funzione, argomenti)

Questa funzione permette (ai programmatori C o C++ un po' più che beoti) di aggiungere a ogni finestra una propria routine di ridisegnatura che sarà eseguita SUBITO DOPO quella interna della libreria (cfr. m_redraw). Gli argomenti hanno il seguente significato:

  1. n    (int *)    indice della finestra cui si vuole aggiungere la funzione di redraw;

  2. funzione (int (*)(XtPointer))     puntatore alla funzione da aggiungere (deve ovviamente essere scritta dall'utente)

  3. argomenti (XtPointer)    valore dell'unico argomento da trasferire alla funzione.


Si ritiene che i fruitori di tale funzione siano già abbastanza esperti da comprendere significato e implicazioni sia della funzione stessa sia dei tipi citati nella descrizione; si rimanda anche alle descrizioni di m_get_server_info e m_get_window_info che sono essenziali per l'uso di questa funzione. Ad ogni buon conto si fornisce qui di seguito, senza altri commenti che quelli inseriti nel codice, un breve programma funzionante che illustra qualche applicazione elementare del gruppo di funzioni "avanzate".


# include <passe_par_tout.h>

int funzione_disegno(XtPointer G)
{struct _dati {Data_X *data_server; Data_Win *data_win; double xmin, xmax;} *Dati_X;
double x[2];
int K, *S;
Dimension E[2];
Dati_X = (struct _dati *)G;
x[0] = Dati_X->xmin, x[1] = pow(10.0, x[0]),
m_move(x);
m_color(&(K=ROSSO));
x[0] = Dati_X->xmax, x[1] = pow(10.0, x[0]),
m_line(x);
m_color(&(K=BLU));
S = Dati_X->data_win->offset,
E[0] = Dati_X->data_win->dimen[0],
E[1] = Dati_X->data_win->dimen[1],
XDrawLine(Dati_X->data_server->display, Dati_X->data_win->drawable, Dati_X->data_win->contesto_grafico, *S, *(S+1), *E-*S, *(E+1)-*(S+1));
return 0;}


XtCallbackProc cucu(Widget w, XtPointer dc, XtPointer dw)
{cout << "hai distrutto la finestra\n";
return (XtCallbackProc)NULL;}


int main(  )
{char *u=const_cast<char *>("");
struct _dati {Data_X *data_server; Data_Win *data_win; double x[2];} *Dati_X;
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2];
int K=400, L = 400, s[  ]={0,1};
XtPointer GG;
Dati_X = (struct _dati *)malloc(sizeof(struct _dati)),
m_startg(u, &K, &L),
Dati_X->x[0] = xmin, Dati_X->x[1] = xmax,
Dati_X->data_server = m_get_server_info(  ),
K = L = 95,
K <<= 24,
K |= 0x00ffff00,
m_window(&K, &L), /* APERTURA FINESTRA CON SFONDO GIALLO */
Dati_X->data_win = m_get_window_info(&(K=0)), /* inizializzazione del puntatore Data_Win */
/* REGISTRAZIONE di una Callback definita dall'UTENTE (perfettamente inutile) */
XtAddCallback
(Dati_X->data_win->shell, XtNdestroyCallback, (XtCallbackProc)cucu, (XtPointer)Dati_X),

m_shutdown_event_handler(&(K=0));
/* DISATTIVAZIONE EVENT HANDLER INTERNI */

m_how_clip(&K),
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
GG = (XtPointer)Dati_X;
funzione_disegno(GG); /* IRRILEVANTE */
m_add_my_own_redraw(&(K=0), funzione_disegno, GG);
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
/* INEFFICACE (causa esecuzione di m_shutdown...)*/

m_mouse(x); /* EFFICACE: simula un "MainLoop"; può essere sostituita da una funzione di "looping" scritta dall'utente. */
m_endg(  );}



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"































































































m_add_my_own_event_handler(n, funzione, argomenti)

Questa funzione è un semplice "wrapper" attorno alla funzione XtAddEventHandler dell'Intrinsic Toolkit, che, beninteso, può essere richiamata esplicitamente da chiunque abbia interrogato il server X11 (cfr. m_get_server_info).
Consente di associare a ogni finestra una propria routine di gestione degli eventi in aggiunta o in alternativa a quelle interne alla libreria (cfr. m_shutdown_event_handler e m_restart_event_handler).
L'argomento n (int) è l'indice della finestra cui il gestore di eventi viene associato (n >= 0). La finestra in questione deve essere già stata aperta (cfr. m_window). L'argomento funzione è un puntatore a funzione di tipo XtEventHandler (con i dovuti 4 argomenti) che deve essere inizializzato al gestore di eventi scritto e fornito dall'utente.
L'argomento argomenti è di tipo XtPointer e contiene i dati per il corrispondente argomento (dello stesso tipo) di funzione. La libreria "associa" funzione a due widgets: la topLevelShell che supporta la finestra e la DrawingArea su cui viene fatto apparire il disegno. Nello scrivere la propria funzione l'utente ne potrà tener conto riguardo all'argomento di tipo Widget. Inoltre nell'atto di aggiungere il gestore di eventi la libreria attiva tutti gli event_masks e pone True il flag nonmaskable.

Si ritiene che i fruitori di questa funzione siano già abbastanza esperti da comprendere significato e implicazioni sia della funzione stessa sia dei tipi citati nella descrizione; ad ogni buon conto si fornisce qui di seguito un breve programma di esempio. Lo si esegua e si effettuino, a titolo di esperimento, le più varie manipolazioni della finestra, compresi spostamenti e click di mouse, pressione di tasti sulla tastiera, iconizzazioni, spostamenti, sovrapposizioni parziali e totali con altre finestre etc...


# include <passe_par_tout.h>

XtEventHandler maneggia
(Widget w, XtPointer P, XEvent *evento, Boolean *c)

{int n;
const char *tipo_evento[  ]={
"hai premuto un tasto della tastiera",
"hai rilasciato un tasto della tastiera",
"hai premuto un bottone del mouse",
"hai rilasciato un bottone del mouse",
"hai mosso il puntatore del mouse entro la finestra",
"sei entrato nella finestra col puntatore del mouse",
"sei uscito dalla finestra col puntatore del mouse",
"la finestra ha guadagnato il fuoco",
"la finestra ha perduto il fuoco",
"il server X11 è stato informato di una mappatura di codici della tastiera",
"la finestra è stata esposta",
"la finestra è stata esposta per quanto concerne il contesto grafico",
"la finestra non è stata esposta",
"la finestra ha subito un cambiamento di visibilità",
"la finestra è stata creata",
"la finestra è stata distrutta",
"la finestra è stata tolta dallo schermo",
"la finestra è stata realizzata sullo schermo",
"il server X11 ha ricevuto la richiesta di realizzazione",
"la finestra ha cambiato il proprio parent",
"la finestra è stata riconfigurata",
"il server X11 ha ricevuto la richiesta di riconfigurazione",
"la finestra ha subito un cambiamento di gravità",
"il server X11 ha ricevuto la richiesta di cambiamento di dimensioni",
"gli eventi relativi alla finestra hanno subito un cambiamento di circolazione",
"il server X11 ha ricevuto la richiesta di cambiamento di circolazione\
degli eventi",

"la finestra ha subito un cambiamento di proprietà",
"la selezione primaria è stata cancellata",
"il server X11 ha ricevuto la richiesta di selezione primaria",
"la finestra ha subito un cambiamento di selezione",
"il server X11 ha ricevuto un'informazione di cambiamento di tavolozza",
"il Window Manager ha inviato un messaggio al server",
"il server X11 ha ricevuto un'informazione circa la realizzazione della finestra",
"LASTEvent"};
n = (long)P,
m_redraw(&n),
printf("%s\n", tipo_evento[evento->type-KeyPress]);
if(evento->type == ClientMessage) m_endg(  ), exit(0);
return (XtEventHandler)NULL;}


int main(int narg, char ** args)
{char *u=const_cast<char *>("");
Data_X *data_server;
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0;
int K=400, L = 400;
m_startg(u, &K, &L),
data_server = m_get_server_info(  );
K = L = 95,
K <<= 24,
K |= 0x00ffff00,
m_window(&K, &L);
K = -10;
if(narg == 1) m_shutdown_event_handler(&K);
K = 0;
m_add_my_own_event_handler(&K, maneggia, (XtPointer)(long)K),
m_frame(&xmin, &ymin, &xmax, &ymax),

m_flush(  ),
XtAppMainLoop(data_server->contesto);}


N.B.: La routine iniziale (maneggia) è un semplice esempio di gestore di eventi fornito dall'utente che si limita a:

  1. effettuare la ridisegnatura dell'unica finestra presente (peraltro vuota, nell'esempio dato).

  2. segnalare su stdout tutti gli eventi ricevuti; i possibili eventi sono tutti elencati e processati, ma in un caso concreto non sarà necessario processarli tutti.

  3. in concomitanza dell'evento di tipo ClientMessage, che, in mancanza di qualsiasi protocollo concordato col Window Manager (come nel caso presente) si attua al momento del click di chiusura della finestra, provocare l'uscita dal programma.


La funzione main ha come solo scopo l'apertura di una finestra e l'esecuzione di m_add_my_own_event_handler. Si osservi che, nel caso non venga fornito alcun argomento sulla linea comando, viene anche compiuta la disattivazione del gestore di eventi interno (con la chiamata di m_shutdown_event_handler); si osservi altresì che quando si usa un proprio gestore di eventi (e a più forte ragione quando questo è l'unico gestore di eventi in attività) è indispensabile terminare main con la chiamata di XtAppMainLoop, altrimenti il programma termina immediatamente e nemmeno si vedrà apparire la finestra.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































































m_write_owned_photogram(finestra, filmato, fotogramma)

Questa funzione è formalmente identica all'omologa m_write_photogram (cui si rimanda per esempio d'uso, significato degli argomenti e valore restituito all'uscita) distinguendosene solamente per il formato del file prodotto. Infatti, a differenza di quella, m_write_owned_photogram genera fotogrammi interpretabili solo dalla stessa libreria che li ha prodotti.
Lo svantaggio è un'evidente diminuzione della "portabilità" delle animazioni così create; il vantaggio è un'assai migliore "prestazione" nella riproduzione e soprattutto nessun limite teorico al numero di fotogrammi inseribili in un'animazione.
La finestra per cui si richiede la scrittura del fotogramma può indifferentemente essere un contenitore di pixmap o no, ma la miglior riproduzione si ottiene senz'altro con le pixmap (come del resto si è sempre sottolineato, fin dal paragrafo Generalità).

Non è da escludere, in un prossimo futuro, e secondo le necessità dell'autore e/o degli utilizzatori più assidui, che venga introdotto un meccanismo automatico di generazione dei fotogrammi, senza nemmeno più che ci sia bisogno di eseguire questa funzione (come ottenere ciò è già scritto nella mente dell'autore).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{char
*u=const_cast<char *>(""),
*film=const_cast<char *>("film");
char *file, z = 0;
double
xmin = 0.0, ymin = 1.0,
xmax = 5.0, ymax = 100000.0,
x[2], rgb[  ]={0.5, 0.4, 0.0};
int K=500, L = 500, s[  ]={0,1}, i;
m_startg(u, &K, &L),
m_sound_message(&z),
K = L = 95, L |= FINESTRA_DOPPIA,
m_window(&K, &L),
K = 1, L = m_new_color(rgb, rgb+1, rgb+2),
m_use_as_pixmap(&K, &L),
m_how_clip(&K),
m_log_scales(s),
file = (char *)malloc(strlen(film)+20),
sprintf(file, "%s", film),
m_frame(&xmin, &ymin, &xmax, &ymax);
for(s[0]=1; s[0] <= 100; s[0]++)
{K = 1, L = -1,
m_clear_pixmap(&K, &L),
x[0] = xmin,
x[1] = pow(10.0, (1.0+s[0]/100.0)*x[0]),
m_move(x);
for(i=0; i < 1001; i++)
x[0] = xmin + (double)i*(xmax-xmin)/500.0,
x[1] = pow(10.0, (1.0+s[0]/100.0)*x[0]),
m_line(x);
K = -1, L = 'a',
m_flush(  ),
K = 0,
m_redraw(&K),
m_write_owned_photogram(&K, file, s);}
m_endg(  );}


Questo programma, ripreso dagli esempi dati per m_line e altre funzioni di questa stessa libreria, traccia 100 volte una linea in scala semilogaritmica con pendenze ogni volta diverse. Per ogni ridisegnatura viene eseguita m_write_owned_photogram che "fotografa" la finestra K nel file di nome $LOGNAME"film"xxxxxxxxxx (ove "film" è il valore della stringa fornita come argomento, $LOGNAME è il valore di quella variabile d'ambiente contenente il proprio nome di login e xxxxxxxxxx sono 10 cifre decimali che rappresentano il numero del fotogramma, contenuto nel terzo argomento s). Si noti che la stringa fornita come secondo argomento DEVE avere capienza per le "aggiunte" operate all'interno della funzione (essenzialmente deve essere capace di contenere strlen(film)+strlen($LOGNAME)+10 caratteri oltre al terminatore).
I fotogrammi, come detto, saranno depositati nella cartella indicata dalla variabile d'ambiente PASSE_PAR_TOUT_CINECITTA, o, in default, nella cartella /tmp (occorre che ci sia spazio).
Si noti infine che il numero di cifre usate per il numero di fotogramma implica di poter giungere, in linea puramente teorica, fino a 4294967295 fotogrammi (ossia il maggiore unsigned int possibile) nello stesso filmato.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




























































m_write_photogram(finestra, filmato, fotogramma)

Permette di generare fotogrammi per animazioni a partire dal contenuto di una finestra. Gli argomenti sono:

finestra int/INTEGER*4 numero della finestra (>=0)
filmato char */CHARACTER*(*) nome del film
fotogramma int/INTEGER*4 numero del fotogramma.

I programmatori FORTRAN tengano conto di quanto detto altrove in merito al trasferimento di argomenti di tipo stringa.

Al momento in cui viene eseguita questa funzione il contenuto della finestra numero finestra viene letto e copiato in un file situato in un'area individuata dalla variabile d'ambiente


PASSE_PAR_TOUT_CINECITTA


il cui valore "default" è la stringa "/tmp/" (si noti la "/" finale (!)).
Il file in questione viene "indelebilmente" associato al nome filmato, al numero fotogramma, che deve essere compreso (estremi inclusi) tra 1 e 10000 (diecimila), e all'utente che ha eseguito la funzione.
In altre parole diventa il fotogramma numero fotogramma dell'animazione filmato prodotta dall'utente che ha eseguito la funzione.
Va da sé che ogni animazione non può avere più di diecimila fotogrammi, oltre ogni umana ragionevolezza, capienza di dischi e/o tempo tollerabile di esecuzione, e non può essere elaborata da altri che non sia l'esecutore di questa funzione.
Il formato di default con cui vengono scritti i fotogrammi è il formato GIF, a meno che non sia definita nell'environment dell'utente una variabile di nome

PASSE_PAR_TOUT_TOGIF

e di valore NULLO. (cfr. a tal proposito quanto detto in m_save_pixmap); in tal caso i fotogrammi sono scritti in formato PPM, la qual cosa è più veloce ma occupa molto più spazio su disco e richiede molta più memoria disponibile all'atto del montaggio dell'animazione. Ciascuno si regoli come meglio gli aggrada.
Una volta generati tutti i fotogrammi l'animazione viene effettivamente realizzata tramite la funzione m_mount_film. All'uscita la funzione restituisce il valore fotogramma+1.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char
*u=const_cast<char *>(""),
*filmati[  ]=
{const_cast<char *>("film1"),
const_cast<char *>("film2")};
double xmin[2] = {-3.0, -1.0}, ymin[  ] = {-3.0, -1.0},
xmax[  ] = {3.0, 1.0}, ymax[  ] = {3.0, 1.0}, x[2];
int K[  ]={400, 80}, L[  ] = {400, 80}, i;
m_startg(u, &K[0], &L[0]),
K[0] = L[0] = 95;
for(i=0; i < 2; i++)
m_window(&K[i], &L[i]),
m_frame(&xmin[i], &ymin[i], &xmax[i], &ymax[i]);
i = 1,
x[0] = xmin[i], x[1] = ymin[i];
m_move(x),
x[0] = xmax[i], x[1] = ymax[i],
m_line(x),
i = 0,
x[0] = xmin[i], x[1] = ymin[i],
m_select(&i),
m_move(x),
x[0] = xmax[i], x[1] = ymax[i],
m_line(x),
m_flush(  );
for(i=0; i < 2; i++)
{m_redraw(&i), L[0] = 1;
while((L[0] = m_write_photogram(&i, filmati[i], L)) <= 5);}
K[0] = EVENTO_ENTER,
m_wait_for_events(&K[0]),
m_endg(  );}


Questo programma, tratto dall'esempio d'uso fornito per m_select, scrive 5 fotogrammi (inutili perché tutti uguali) per ognuna delle due finestre create. I due filmati sono chiamati rispettivamente "film1" e "film2". Si apprezzi l'uso del valore di ritorno della funzione per gestire l'uscita dal ciclo.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




























































m_show_pixmap(n)

Questa funzione copia una pixmap (nello stato in cui si trova al momento in cui è eseguita) sulla finestra che le è associata. Utile solo quando il primo argomento assegnato a m_use_as_pixmap è negativo (cfr.), altrimenti la libreria provvede da sé alla bisogna, ed efficace SOLO SE eseguita DOPO una delle funzioni di attesa eventi di questa stessa libreria. L'argomento n di tipo int/INTEGER*4 è, sostanzialmente, il valore assoluto del primo argomento di m_use_as_pixmap (e quindi è vietato attribuirgli valori negativi).

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=800, L = 800;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = -1, L = BLU,
m_use_as_pixmap(&K, &L),
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_show_pixmap(&(L=1)),
K = -1, L = 'B',
m_loop_for_events(&L, &K),
m_endg(  );}


Questo programma mostra come la pixmap blu "collegata" con la finestra non appaia visualizzata, nonostante la richiesta esplicita di esecuzione di m_redraw e di m_flush, fino a quando non si esegue m_show_pixmap (subito dopo l'uscita del programma da m_loop_for_events in seguito a digitazione della lettera 'A'; dopo di che il programma termina alla pressione della lettera 'B').

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































m_remove_pixmap(n)

È la controparte di m_show_pixmap e si usa, come dice il nome, per togliere da una finestra contenente una pixmap "residente sul server" la più recente realizzazione della pixmap medesima, visualizzata da m_show_pixmap stessa. Di utilità talmente rara che non si ritiene doverne dare un esempio d'uso; si sottolinea solamente che non è possibile usare per questo scopo la funzione m_clear_pixmap perché quest'ultima agisce direttamente sulla pixmap e non sulla sua immagine visualizzata. Il suo effetto sarebbe quindi il totale azzeramento della pixmap anziché la semplice "cancellazione" della finestra. L'argomento n ha tipo e significato identici a quelli dell'omonimo argomento di m_show_pixmap.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































































m_mount_film(filmato, output, fotogrammi)

Esegue il montaggio dell'animazione di nome filmato (cfr., per il significato e la collocazione su disco, m_write_photogram), argomento di tipo char*/CHARACTER*(*). L'animazione viene posta in un file il cui nome è ottenuto dall'argomento output (di tipo char*/CHARACTER*(*)) tramite il seguente procedimento:

nome_effettivo = output.suffisso

ove "suffisso" vale .gif (tale suffisso riflette il formato dell'animazione ottenuta utilizzando il generatore default della libreria).

I programmatori FORTRAN tengano conto di quanto detto altrove in merito al trasferimento di argomenti di tipo stringa.

L'argomento fotogrammi è un vettore di int/INTEGER*4 contenente i numeri di fotogramma (cfr. m_write_photogram) del filmato filmato che devono essere inseriti nella risultante animazione. La funzione riconosce da sé il formato di ogni singolo fotogramma e ammette anche formati misti per la stessa animazione.
Va tenuto presente quanto segue:

  1. Se fotogrammi è il puntatore nullo (per i programmatori C o C++) o se il suo primo elemento è >= 10000 (diecimila) (per tutti i programmatori) l'animazione risultante conterrà TUTTI i fotogrammi di filmato nel loro ordine naturale; nel primo caso, comunque, si ha implicita rimozione dei fotogrammi, mentre nel secondo i fotogrammi sono lasciati su disco.

  2. Se fotogrammi contiene valori >= 0 e < 10000 tutti i valori sono interpretati come numero esplicito di fotogramma da inserire nell'animazione nello stesso ordine in cui compaiono nel vettore. La lettura di fotogrammi termina quando si trova il primo valore negativo (eventuali valori > 10000 successivi al primo sono semplicemente ignorati); se tale valore negativo è > -1000000 (- un milione) TUTTI e SOLI i fotogrammi specificati sono rimossi dal disco, altrimenti sono lasciati intatti.

  3. Il limite di 10000 fotogrammi non significa che non possano essere prodotti filmati di maggiore lunghezza, ma questo viene lasciato all'arbitrio dell'utente, che può tranquillamente "concatenare" numerose animazioni prodotte da questa funzione facendo uso degli opportuni strumenti del sistema operativo.

Questa funzione è implementata, al presente, solo sulle piattaforme Linux e IRIX; su qualunque altra piattaforma si limita a "ritornare" il codice di insuccesso (0) senza fare nient'altro, a meno che non si fornisca un programma esterno di generazione di animazioni attraverso la variabile d'ambiente

PASSE_PAR_TOUT_COMANDO_MOVIE

il cui valore deve essere una stringa del tipo

"nome_programma %s %s"

con due "segnaposto" (%s) che servono alla funzione per ricopiarvi i nomi degli input files e dell'output file. La stessa variabile d'ambiente si può usare anche in ambito Linux e IRIX se si vuole sostituire il programma standard per la generazione delle animazioni.

Ad esempio ponendo nell'environment di una Silicon Graphics la variabile PASSE_PAR_TOUT_COMANDO_MOVIE come sopra indicato, uno script eseguibile chiamato nome_programma e col seguente contenuto

#! /bin/csh -f
set i=1
set args=""
while($i < $#argv)
set args=($args $argv[$i])
@ i = $i + 1
end
makemovie -o $argv[$#argv].qt -f qt -r 2 $args; \
dmconvert -f mpeg1v -p video $argv[$#argv].qt $argv[$#argv].mpeg; \
rm -f $argv[$#argv].qt


permette di ottenere, a partire dagli stessi fotogrammi, una animazione in formato mpeg.

Reciprocamente, se si volesse per qualsiasi ragione inibire l'esecuzione della presente funzione anche se ci si trova in ambito Linux e IRIX, è sufficiente aggiungere alle proprie variabili d'ambiente una di nome

PASSE_PAR_TOUT_ANIMAZIONI_VIETATE

con un valore arbitrario.

Data la natura delle operazioni coinvolte questa funzione può essere eseguita anche senza che sia stato inizializzato il server X11, ossia senza che sia stata eseguita m_startg. La produzione dell'animazione viene eseguita AUTOMATICAMENTE in BATCH, trattandosi di un processo abbastanza lento. Un e-Mail indirizzato all'utente lo avviserà dell'avvenuto completamento del processo medesimo.


Esempio d'uso:

#include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{int *ph = (int *)NULL;
m_mount_film(args[1], args[2], ph);}

Questo programma esegue il montaggio del filmato specificato dal primo argomento sulla linea comando e scrive l'animazione nel path specificato come secondo argomento. L'animazione contiene TUTTI i fotogrammi del filmato. Appare evidente che l'esecuzione del programma assomiglia a un comando di sistema del tipo

comando filmato animazione

così come si assomigliano due gocce d'acqua.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































































m_mount_owned_film(filmato, output, fotogrammi)

Questa funzione è l'omologa di m_mount_film (cui si rimanda per la descrizione generale e per il significato degli argomenti) distinguendosene solo per il fatto che i fotogrammi da montare nel filmato devono essere stati prodotti con m_write_owned_photogram piuttosto che con m_write_photogram. Ulteriori differenze rispetto a m_mount_film sono:



I fotogrammi da inserire nel filmato devono essere omogenei tra loro, ossia tutti provenienti dalla stessa finestra (vale a dire con un solo "sistema di riferimento" comune a tutti). Nessuna protezione è presa contro il tentativo di mescolare fotogrammi di diversa provenienza nello stesso filmato: sia il montaggio sia la riproduzione (qualora il montaggio andasse, in qualche modo, a completamento) NON SONO GARANTITI contro il rischio di malfunzionamento e/o di arresto del programma che li contenga.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{m_mount_owned_film(args[1], args[2], 0);}

Questo elementare programma monoriga, eseguito con la seguente linea comando

a.out film montaggio

"monta" nel file montaggio TUTTI i fotogrammi prodotti dal programma citato come esempio d'uso di m_mount_owned_photogram, nel loro ordine cronologico naturale.
Si noti come non sia affatto indispensabile "inizializzare" compiutamente la libreria tramite l'esecuzione di m_startg.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
















































































































La tastiera

La tastiera è una particolare finestra grafica che viene automaticamente visualizzata ogni volta che si invoca la funzione m_animate; NON entra a far parte del computo totale delle finestre grafiche correntemente aperte e resta indissolubilmente legata alla finestra cui si riferisce, anche nelle proporzioni e nel titolo (viene altresì rimossa dal monitor assieme alla propria finestra di riferimento).
Attraverso la tastiera è possibile gestire le eventuali animazioni successive alla prima, ovvero decidere anche la prima animazione qualora la funzione m_animate sia stata eseguita attribuendo al suo secondo argomento il valore (standard) ASPETTA_ORDINI.
La tastiera è "sensibile" tanto a pressioni di bottoni di mouse quanto a digitazioni di lettere (quelle che appaiono scritte sulla tastiera stessa al di sotto di ogni icona colorata, rappresentativa di pulsanti di un generico "player" di filmati). Al di sopra delle icone dei pulsanti si trova la classica barra orizzontale con cursore mobile, rappresentativa dello stato di avanzamento relativo della riproduzione; il numero del fotogramma correntemente proiettato appare anche nell'angolo inferiore sinistro della tastiera.

USO DELLA TASTIERA
Premendo (qualsiasi) bottone del mouse sopra una delle icone colorate, o digitando la corrispondente lettera dalla tastiera alfabetica, si attivano, come è intuitivo, le seguenti funzionalità:

  1. Tasto Play (terzo da destra) o lettera 'p' minuscola:
    Proiezione continua del filmato, nell'ordine naturale, dal fotogramma iniziale a quello finale;

  2. Tasto RePlay (terzo da sinistra) o lettera 'r' minuscola:
    Proiezione continua del filmato, nell'ordine inverso, dal fotogramma finale a quello iniziale;

  3. Tasto Frecce (al centro):
    Ripristino del fotogramma iniziale al primo fotogramma del filmato e di quello finale all'ultimo fotogramma del filmato, con conseguente proiezione continua dell'INTERO filmato nell'ordine naturale; se invece di usare il mouse si digita la lettera corrispondente ('f' minuscola) si ottiene un effetto diverso (in qualche modo opposto, ed è questa l'unica eccezione all'equivalenza tra pressione del mouse o uso della lettera in etichetta) ossia la richiesta di introduzione da standard input dei numeri dei fotogrammi da considerare iniziale e finale per le successive riproduzioni; l'intervallo dei numeri disponibili appare su standard output e se si digita il primo numero maggiore del secondo la funzione assume riproduzione a ritroso, che comunque avverrà sempre all'interno dell'intervallo specificato.

  4. Tasti moviole (il secondo e il penultimo) o lettere 'M' ed 'm' rispettivamente:
    funzionano come i tasti Play e RePlay sopra descritti per quanto attiene al verso, ma la riproduzione non avviene con continuità ma con avanzamento (o arretramento) di un SINGOLO fotogramma per ogni susseguente click di mouse in QUALSIASI posizione; la riproduzione si interrompe quando il click di mouse è compiuto col bottone CENTRALE: il fotogramma visualizzato in quel momento diventa il nuovo fotogramma finale (o iniziale, secondo il verso della riproduzione appena cessata) per le eventuali successive riproduzioni e la tastiera rientra nel modo di attesa. In un futuro si potrà prendere in considerazione la possibilità di variare la velocità di avanzamento delle moviole.

  5. Tasto X (l'ultimo) o lettera 'x' minuscola:
    Uscita definitiva dalla funzione m_animate, con chiusura e rimozione dallo schermo tanto della finestra grafica in cui avvenivano le riproduzioni quanto della finestra contenente la tastiera.

  6. Tasto stella (il primo) o lettera 's' minuscola:
    si tratta di un tasto "futuribile" che, nella mente dell'autore e secondo la sua voglia e il tempo disponibile, servirà alla gestione di opzioni MOOOOOOOOLTO più avanzate quali l'introduzione di bufferizzazioni dei dati, ritardi quantificabili nel passaggio da un fotogramma e l'altro, "editing" del filmato con eliminazioni e/o spostamenti di sequenze di fotogrammi e/o inserimenti di sequenze di fotogrammi provenienti da altri filmati (ovviamente compatibili) e quant'altro suggerisca la fantasia dell'autore (e soprattutto, repetita iuvant, la sua voglia).
    Attualmente effettua semplicemente una riproduzione in ordine casuale.



USO DELLA BARRA ORIZZONTALE
Premendo il bottone sinistro del mouse sulla barra orizzontale mentre la tastiera è in modo di attesa, si pone nella posizione in cui avviene il click il fotogramma iniziale per le successive riproduzioni (marcato con una sottile linea vericale); premendo invece il bottone destro si pone ivi la posizione del fotogramma finale (pure marcato come l'altro). Tali due operazioni sono "rifiutate" se implicano che il fotogramma finale si trovi a sinistra di quello iniziale.
L'effetto è dunque lo stesso ottenuto con la digitazione della lettera 'f' (cfr. sopra), salvo il riconoscimento automatico del verso della riproduzione e la minore precisione nella selezione dei fotogrammi.

Effettuando il "dragging" del cursore della barra orizzontale col bottone centrale del mouse si ottiene la riproduzione continua nel verso in cui avviene il "dragging" finché non si rilascia il bottone stesso; a quel punto la posizione di rilascio del bottone diventa, come nel caso dei tasti moviole (cfr. sopra), la nuova posizione limite (iniziale o finale, secondo il verso dell'ultimo "dragging" e le posizioni precedenti) per le successive proiezioni.

Non dovrebbe esserci chi non si accorga che, combinando opportunamente le varie funzionalità appena descritte, si ottiene un controllo piuttosto fine delle animazioni.

COLORI DELLA TASTIERA
Sono gestiti attraverso l'ultimo argomento (di tipo unsigned int/INTEGER*4) trasferito alla funzione m_animate; se tale argomento è il puntatore nullo si ottiene una colorazione "standard": per chi non si accontenta basta trasferire un puntatore che punti un numero arbitrario di elementi. La funzione ne utilizzerà, AL MASSIMO, i primi 15 qualora entro tale sequenza non vi sia alcun oggetto di valore zero.
Ognuno di tali valori "puntati" dal puntatore che sia riconoscibile come l'OR binario tra alcune costanti predefinite con le costanti rappresentative dei colori base della tavolozza attribuisce tale colore a un elemento della tastiera corrispondente alla costante.
Si fa prima a farlo che a dirlo; se, ad esempio, si desse come ultimo argomento di m_animate un array di unsigned int contenente i seguenti valori:

STELLA | ROSSO, PLAY | GIALLO, SFONDO | NERO, 0

la tastiera avrebbe uno sfondo nero e i bottoni "stella" e "play" sarebbero colorati rispettivamente in rosso e giallo, lasciando tutti gli altri colori al valore standard.

L'elenco completo delle costanti predefinite per identificare i singoli elementi della tastiera è reperibile qui

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
















































































































m_animate(film, modo, opzioni)

Questa funzione costituisce il "player" dei filmati di proprietà della libreria, generati attraverso le funzioni m_write_owned_photogram e m_mount_owned_film. Un semplice main scritto come segue (e che funge quindi da esempio d'uso):

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{int K = 500, L = 500;
unsigned int m = 0, *M = 0;
char z = 0;
m_startg(const_cast<char *>(""), &K, &L),
m_toggle_message(  ),
m_sound_message(&z),
m_animate(args[1], &m, M),
m_endg(  );}


sarà sufficiente a riprodurre il filmato contenuto nel file fornito come primo (e unico) argomento sulla linea comando (e che, come detto, dovrà essere stato generato da m_mount_owned_film).
Quanto appena detto spiega il tipo e il significato del primo argomento di questa funzione; il secondo argomento è di tipo int/INTEGER*4 e serve a stabilire la modalità di esecuzione della prima riproduzione del file; sono previste le seguenti modalità, per ognuna delle quali esiste predefinita un'opportuna costante intera da utilizzare per assegnarne il valore al secondo argomento:

Quando la prima riproduzione si è compiuta, in qualunque modalità tra quelle descritte sia stata eseguita, la funzione entra in un ciclo infinito gestito tramite la tastiera.

Il terzo argomento, di tipo unsigned int/INTEGER*4, è descritto alla voce tastiera.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
















































































































m_inquire_monitor_size(larghezza, altezza)

Funzione utile per decidere quali dimensioni assegnare alle finestre in base alle dimensioni dello schermo su cui si sta lavorando. Può essere eseguita in qualsiasi momento, in particolare anche prima di m_startg che quindi può utilizzarne le informazioni. Se il valore restituito dalla funzione è non nullo (a tal proposito i fortranisti non la usino come subroutine) i due puntatori int/INTEGER*4 larghezza e altezza contengono in uscita le omonime dimensioni dello schermo in pixels. Non si ritiene necessario fornire un esempio dell'ovvio funzionamento.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





































































































m_toggle_message(  )
minverti_messaggio(  )

Sono essenzialmente la stessa funzione chiamata con nomi diversi perché agisca rispettivamente a proposito delle funzioni grafiche a schermo e delle funzioni grafiche PostScript.

Entrambe senza argomenti disconnettono/riconnettono (alternativamente a ogni chiamata) i messaggi della libreria dal canale

stderr

su cui sono indirizzati per default. L'alternativa a stderr è

/dev/null

ovvero "messaggio soppresso".

Ciascuna funzione restituisce lo stato della connessione all'uscita dalla funzione stessa.

Questo comportamento è molto utile per poter ottenere con certezza la connessione (sconnessione) a stderr senza dover tener conto della parità delle chiamate (cfr. Esempio).

Per quanto riguarda la seconda funzione va tenuto conto che la chiamata di minizio_ps per l'apertura di un nuovo file PostScript e quella di minizia_bitmap per la creazione di una nuova bitmap implicano la riconnessione di stderr indipendentemente dallo stato precedente della connessione.

Esempio d'uso: (utilizzando la prima funzione)


# include <passe_par_tout.h>

int main(  )
{int i=100, j=100;
char *s[  ]=
{const_cast<char *>("disconnesso"),
const_cast<char *>("connesso")};
m_startg(const_cast<char *>(""), &i, &j);
printf("stderr inizialmente %s\n", s[m_toggle_message(  )]);
if(m_toggle_message(  ))
printf("stderr provvisoriamente %s\n", s[m_toggle_message(  )]);
if(!m_toggle_message(  ))
printf("stderr definitivamente %s\n", s[!m_toggle_message(  )]);
else printf("stderr definitivamente %s\n", s[1]);}


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































m_toggle_pointer_motion(n)

Questa funzione attiva/disattiva alternativamente, secondo lo stesso meccanismo di alternanza proprio di altre funzioni "toggle", il rilevamento degli eventi di movimento del mouse, all'interno della finestra di indice n (int/INTEGER*4, 0 <= n), da parte del gestore di eventi interno della libreria.

Se si attribuisce a n un valore negativo l'effetto di alternanza del rilevamento si applica a TUTTE le finestre correntemente aperte.

È in pratica, salva quest'ultima proprietà e la non dipendenza dell'effetto dall'input focus, l'equivalente dell'intervento manuale da parte dell'utente che digiti i caratteri '?' e '/' dalla tastiera.

Non si ritiene necessario un esempio d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































































m_toggle_mouse_save_right(n)

Questa funzione, il cui argomento di tipo int/INTEGER*4 rappresenta l'indice della finestra cui ci si riferisce (0 <= n) inibisce e ripristina alternativamente, per la finestra in questione (secondo lo stesso schema comportamentale di m_toggle_message, compreso il significato del valore restituito), il comportamento standard della libreria circa il salvataggio implicito su file PostScript del contenuto della finestra quando vi si opera un click del mouse col bottone destro (cfr. m_mouse, m_save_pixmap). Non si ritiene necessario fornire un esempio d'uso, rinviando gli utenti a quello fornito per m_toggle_message.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



































































































































































m_get_current_pointer_position(n, pos)

Questa funzione restituisce nell'argomento pos (array di almeno 4 int/INTEGER*4) la posizione istantanea del puntatore del mouse relativamente alla finestra di indice n (int/INTEGER*4, n >= 0).

A differenza di m_mouse e m_mouse_int questa funzione non blocca l'esecuzione del programma dato che non attende alcun intervento dell'utente.

I valori restituiti in pos vanno interpretati nel modo seguente: nei primi due elementi di pos sono inserite le coordinate orizzontale e verticale (rispettivamente) del puntatore del mouse rispetto al vertice superiore sinistro della finestra n; nelle successive due locazioni si trovano invece le coordinate orizzontale e verticale (rispettive) del puntatore del mouse relativamente al vertice sinistro superiore dello schermo.

La funzione restituisce un valore vero se nel momento in cui viene eseguita il puntatore del mouse si trova davvero entro la finestra n, altrimenti restituisce zero (falso).


In ogni caso i primi due valori di pos conservano il loro significato (in caso di restituzione di falso potrebbero essere negativi e/o maggiori delle dimensioni della finestra) consentendo comunque anche di conoscere la posizione attuale della finestra sullo schermo (usando le successive due locazioni di pos ed effettuando semplici operazioni di sottrazione).

Un esempio d'uso è dato in corrispondenza della descrizione delle funzioni m_move_pointer.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"























































































m_map_fonts(indici)

Raramente è necessario eseguire questa funzione; serve solo ad alterare l'ordine di ricerca del fonte di caratteri default sul server in uso, specialmente per la scrittura delle cifre delle quotature. Il fonte in questione appartiene sempre alla "family" fixed (presente su TUTTI i server) e il "pixelsize" usato si ottiene per ricerca dei "pixelsize" compresi tra 10 e 24 (almeno UNO di questi ci sarà pure) secondo il seguente ordine
14 15 16 17 13 12 11 10 18 19 20 21 22 23 24
L'argomento indici è per l'appunto un puntatore a int/INTEGER*4 che punta al massimo 15 valori che rappresentino una permutazione dei numeri tra 0 e 14 rispetto alla permutazione fondamentale che seleziona l'ordine "naturale" dei fonts ossia
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
(per intendersi, il valore di indici corrispondente alla situazione default è il seguente
4 5 6 7 3 2 1 0 8 9 10 11 12 13 14)
Non è necessario che indici punti TUTTI i 15 valori citati, perché la libreria smette di leggerlo appena incontra un valore negativo. Ad esempio, se si è certi di possedere il fonte fixed a 24 pixelsize e si desidera usarlo al posto del fonte default basta eseguire questa funzione con indici che punti i valori 14 e -1.
Non si ritiene necessario fornire ulteriori chiarificazioni e/o esempi d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"























































































m_move_pointer(n, x, i)
m_move_pointer_int(n, y)

Queste due funzioni sono utili solo in rare circostanze dato che, usualmente, lo spostamento del mouse dovrebbe essere lasciato alla discrezionalità dell'utente.

Servono infatti entrambe a collocare il puntatore del mouse all'interno della finestra di indice n (int/INTEGER*4, n >= 0), ovviamente aperta sul monitor.

Contestualmente attribuiscono anche a tale finestra l'input focus, di modo che il loro uso potrebbe essere raccomandabile in contesti in cui il window manager non assegna questa proprietà in seguito al semplice ingresso del puntatore del mouse entro una finestra (focus on enter).

Per la seconda funzione l'argomento y è un array di due int/INTEGER*4 che deve contenere i valori delle due coordinate orizzontale e verticale in cui si vuole posizionare il puntatore del mouse; tali coordinate sono intese in pixels misurati a partire dall'angolo superiore sinistro della finestra: se tali coordinate cadono al di fuori della finestra la funzione non ha alcun effetto (nemmeno l'attribuzione del focus).


Per la prima funzione x è un array di due double/REAL*8 contenente le coordinate utente del punto in cui si vuol collocare il puntatore del mouse e i è una variabile int/INTEGER*4 contenente l'indice del sistema di riferimento cui x si riferisce. L'esecuzione della funzione implica la selezione del sistema di riferimento (esecuzione implicita di m_select_frame). Per finestre per cui non sia stata eseguita la funzione m_multiframe la variabile i vale semplicemente 0.

Anche in questo caso, se le coordinate x cadono al di fuori dei limiti del sistema di riferimento la funzione non ha effetto.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double
x[22], rgb[  ][3]={1.0, 0.8, 0.8, 0.8, 0.5, 0.0},
frame[  ]={-1.0, -1.0, 1.0, 1.0, 0, 0,
-2.0, -2.0, 2.0, 2.0, 0, 0,
-3.0, -3.0, 3.0, 3.0, 0, 0,
-4.0, -4.0, 4.0, 4.0, 0, 0,
-5.0, -5.0, 5.0, 5.0, 0, 0,
-6.0, -6.0, 6.0, 6.0, 0, 0,
-7.0, -7.0, 7.0, 7.0, 0, 0,
-8.0, -8.0, 8.0, 8.0, 0, 0,
-9.0, -9.0, 9.0, 9.0, 0, 0};
int K=600, L = 600, i, M, II[  ]={0, -1}, IL[4], IO[  ]={50,50};
m_startg(u, &K, &L), K = L = 95, m_window(&K, &L),
K = 9, L = 3, m_multiframe(&K, &L, IO, frame),

K = 1, L = 7,

m_use_as_pixmap(&K, &L),
K = L = 95, m_window(&K, &L); IO[0] = IO[1] = 50, K = 9, L = 3,
m_multiframe(&K, &L, IO, frame);

for(i=0; i < 2; i++)

{m_select(&i);
for(M=0; M < 9; M++)
{II[0] = m_which_frame(&L),
L = 0,
m_select_frame(&L, II);
if(M < 7) L = M, m_color(&L);
else
L = m_new_color(&rgb[M-7][0], &rgb[M-7][1], &rgb[M-7][2]),
m_color(&L);
for(K=0; K < 3+M; K++)
x[2*K] = 0.5*frame[6*M+2]*cos(2.0*M_PI*K/(3.+M)),
x[2*K+1] = 0.5*frame[6*M+2]*sin(2.0*M_PI*K/(3.+M));
K = 3+M, L=0,
m_polygon(x, &K), II[0]++, m_select_frame(&L, II);}}
m_mouse(x),
m_redraw(&(L=0)), m_redraw(&(L=1)), K=1;
while(K <= 18)
{i = (K-1)%2, x[0] = frame[6*((K-1)%9)+2], x[1] = frame[6*((K-1)%9)+3],
L = (K-1)%9+1, m_move_pointer(&i, x, &L),
m_redraw(&(L=0)), m_redraw(&(L=1)), m_mouse(x),
cout << x[0] << ' ' << x[1] << '\n', cout.flush(  ),
m_get_current_pointer_position(&(i=m_which_window(&M)), IL),
cout << m_which_window(&i) << ' '
<< IL[0] << ' ' << IL[1] << ' ' << IL[2] << ' ' << IL[3] << '\n',
cout.flush(  ), K++;}
m_endg(  );}


N.B.:
il programma precedente, tratto dall'esempio d'uso di m_multiframe, mostra l'uso di m_move_pointer congiuntamente a quello di m_get_current_pointer_position. Si osservino le due esecuzioni di m_redraw prima di entrare nel ciclo
while(K <= 18)
che garantiscono che entrambe le finestre siano visibili e disegnate quando si esegue m_move_pointer. Si osservi anche che, in assenza dell'esecuzione di m_mouse nello stesso ciclo (o di qualsiasi altra funzione che "blocchi" l'esecuzione) non si avrebbe modo di apprezzare "a occhio nudo" l'azione di m_move_pointer, i cui effetti sarebbero percepibili solo attraverso i valori scritti su stdout.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



































































































m_sound_message(bell)
msuono_messaggio(bell)

Sono la stessa funzione, chiamata con nomi diversi perché agisca rispettivamente a proposito delle funzioni grafiche a schermo e delle funzioni grafiche PostScript.

Per entrambe l'argomento è di tipo char/CHARACTER (un puntatore a un singolo char, non necessariamente una stringa, per chi programm in C o C++).

Se bell vale 0 viene abolito il suono del campanello quando la libreria invia un messaggio; se invece bell ha qualsiasi valore non nullo il suono del campanello viene (eventualmente) ripristinato (sempre ammesso che il canale stderr sia connesso: cfr. m_toggle_message).

Non si ritiene necessario fornire un esempio dell'ovvio funzionamento.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































mversione_passe_par_tout(  )

Funzione senza argomenti che può essere eseguita in qualsiasi momento e che è stata introdotta nella libreria in data 27 giugno 2002. Scrive su stderr la seguente stringa

versione corrente libreria = [DD mmmmmm YYYY]

ove DD mmmmmm YYYY rappresenta la data (giorno, mese, anno) in cui la libreria è stata installata/aggiornata sul sistema in uso.
I programmatori C o C++ possono anche utilizzare, a scopo di controllo, il valore della stringa DD mmmmmm YYYY che viene restituito al programma chiamante.
Non si ritiene necessario fornire esempi d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































































m_prestartg(ALLOC)

serve a cambiare l'allocazione di memoria da parte della libreria.
Come dice il suo nome va chiamata (se occorre) solo una volta e solo PRIMA di m_startg. ALLOC è un INTEGER*4/int POSITIVO che indica il numero di blocchi, da 64 bytes ciascuno, che devono essere aggiunti alla memoria allocata ogni volta che risulta necessario estenderla. Il default è 1000 che è anche la memoria allocata (64 K) inizialmente per ogni finestra, a meno che non venga dedicata a una pixmap. Valori maggiori per ALLOC implicano spreco di memoria, ma minor tempo di esecuzione.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700, ALLOC = 10000;
m_prestartg(&ALLOC);
if(m_startg(u, &K, &L))
printf("programma riuscito\n");}


N.B.:
il programma precedente non fa assolutamente nulla di significativo, ma serve unicamente a mostrare una chiamata corretta della libreria. In un contesto reale non sarà obbligatorio "testare" il valore reso in uscita dalla libreria.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"











































































m_startg(stringa, LARG, ALT)

inizializzazione e definizione di tutti i defaults per la grafica a schermo. stringa è una stringa di caratteri che viene usata come titolazione default per tutte le finestre (completata con il numero della finestra).

Se si fornisce una stringa vuota il programma ripiega sull'uso della stringa "passe_par_tout" per il titolo delle finestre.

Naturalmente chi usa il FORTRAN dovrà tener conto di quanto detto a proposito delle stringhe (cfr. generalità e funzioni m_conv_string e m_conv_chars).

LARG e ALT sono variabili intere che indicano i lati della finestra fisica da aprire sullo schermo (espressi in pixels).

La libreria controlla internamente che non siano richieste finestre con lati maggiori delle dimensioni fisiche dello schermo, riportando entro tali limiti eventuali valori superiori. Le finestre, una volta aperte e realizzate sul DISPLAY non possono più essere ridimensionate con le tecniche standard di X11.

NESSUN'ALTRA FUNZIONE DELLA LIBRERIA CHE FACCIA ACCESSO A SCHERMO PUÒ ESSERE CHIAMATA PRIMA DI m_startg

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700;
if(m_startg(u, &K, &L))
printf("programma riuscito\n");}


N.B.:
il programma precedente non fa assolutamente nulla di significativo, ma serve unicamente a mostrare una chiamata corretta della libreria. In un contesto reale non sarà obbligatorio "testare" il valore reso in uscita dalla libreria.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































m_endg(  )

Funzione priva di argomenti in entrata provoca la chiusura totale della grafica a schermo e la distruzione di TUTTE le finestre aperte. Dopo aver chiamato m_endg può essere chiamata SOLO m_startg tra le funzioni che fanno accesso a schermo.
Per una corretta conclusione di un programma di grafica questa funzione deve essere eseguita, anche se in apparenza si esce ugualmente senza. Il fatto è che se un programma di grafica viene concluso senza aver eseguito questa funzione il server X11 potrebbe rimanere "ingombro" delle eventuali allocazioni compiute dal programma stesso e questo potrebbe comportare malfunzionamenti per i clienti che andassero in esecuzione successivamente, vuoi da parte di altri utenti vuoi da parte dello stesso utente che ha eseguito il programma di grafica "difettoso".

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700;
if(m_startg(u, &K, &L))
printf("start riuscita\n");

if(m_endg(  ))
printf("end riuscita\n");}



N.B.:
il programma precedente non fa assolutamente nulla di significativo, ma serve unicamente a mostrare una chiamata corretta della libreria. In un contesto reale non sarà obbligatorio "testare" il valore reso in uscita dalla libreria.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"













































































m_place_window(dove, titolo)

La libreria colloca sullo schermo le prime 6 finestre che è in grado di gestire secondo uno schema default fisso.
Precisamente la prima finestra è collocata accostata all'angolo superiore sinistro, la seconda all'angolo superiore destro, la terza e la quarta ai due angoli inferiori e le ultime due accostate rispettivamente ai margini sinistro e destro dello schermo al di sotto (rispettivamente) della prima e della seconda. Ferma restando la possibilità di spostare manualmente le finestre in qualsiasi posizione, questa funzione consente di dar loro una collocazione iniziale diversa da quella default. L'argomento dove è un array di due INTEGER*4/int che contiene i due offsets (orizzontale e verticale) dell'angolo superiore sinistro della finestra rispetto all'angolo superiore sinistro dello schermo.
Gli offsets sono espressi in pixels e la loro segnatura è utilizzata dalla libreria per decidere come comportarsi se questa funzione è invocata prima o dopo l'esecuzione di m_window relativa alla creazione della finestra cui deve riferirsi. Precisamente se entrambi gli elementi di dove sono positivi la libreria "capisce" che ci si vuol riferire a una finestra che non è ancora stata creata (alla prossima che sarà creata) per posizionarla e titolarla. Se invece almeno una delle componenti di dove è negativa la libreria "capisce" che ci si vuole riferire alla finestra correntemente destinataria di output grafico (in quanto tale già presente sullo schermo) per spostarla nella posizione data dai valori assoluti delle componenti di dove e rititolarla.
L'esecuzione di questa funzione con argomento dove negativo e nessuna finestra aperta sullo schermo è semplicemente ignorata.
L'argomento titolo è una stringa (i fortranisti tengano conto di quanto detto in proposito, cfr. generalità e funzioni m_conv_string e m_conv_chars) che, se non è nulla, viene usata dal Window manager come titolo della finestra in alternativa ai titoli default.

Dato che questa funzione interagisce direttamente col Window manager in uso, va osservato che qualcuno di essi potrebbe non onorarla, benché un caso del genere sia da considerare alquanto improbabile.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int i, K=100, L = 100, dove[  ]={800, 800}, size[2];
double x[  ]={0, 0, 100, 100};
m_startg(u, &K, &L);
K = L = 95;
m_place_window(dove, const_cast<char *>("questo titolo appare sulla finestra"));
m_window(&K, &L);
m_place_window(dove, const_cast<char *>("esecuzione \"sovrascritta\" dalla successiva"));
m_frame(x, x+1, x+2, x+3);
m_move(x), m_line(x+2),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_close(&(K=0));
K = 100, L = (100 << 24) + (200 << 11) + 200,
dove[0]=120, dove[1]=-120,
m_place_window(dove, const_cast<char *>("inefficace: non ci sono finestre")),
m_window(&K, &L);
x[2] = x[3] = 200,
m_frame(x, x+1, x+2, x+3);
m_place_window(dove, const_cast<char *>("esecuzione \"sovrascritta\" dalle successive")),
m_move(x), m_line(x+2), m_inquire_monitor_size(size, size+1), size[0] -= 200, size[1] -= 200;
for(i=0; i < 4; i++)
dove[0] = random(  )*(float)size[0]/0x7fffffff,
dove[1] = -random(  )*(float)size[1]/0x7fffffff,
m_place_window(dove, const_cast<char *>("saltello della finestra qua e là")),
m_wait_for_events(&(K=EVENTO_ENTER));
m_endg(  );}

N.B.:
il programma precedente mostra i possibili usi di questa funzione: le stringhe usate come argomento titolo sono autoesplicative.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"














































































m_window(Lx,Ly,...)

apre una finestra LOGICA di larghezza e altezza in pixels espresse rispettivamente da

DefaultX * Lx / 100 e DefaultY * Ly / 100

all'interno della finestra fisica predefinita da m_startg e inoltre la realizza sul DISPLAY. DefaultX e DefaultY sono i lati predeterminati con m_startg.

Lx e Ly sono interi (INTEGER*4/int) non negativi e minori o uguali a 100 (salvo il caso citato appresso).

È previsto il mantenimento della finestra default anche dando i due argomenti nulli (ciò equivale a Lx=Ly=100).

Non sono accettati valori di Lx e Ly positivi e minori di 51; la libreria "aggiusta" internamente eventuali valori inferiori che venissero forniti erroneamente.

Se il primo argomento Lx è > 100 viene interpretato come la codifica del valore "normale" dell'argomento nei primi 8 bits e come i valori rgb del colore da attribuire inizialmente allo sfondo nei successivi tre bytes rispettivamente. Tale colore è anche automaticamente aggiunto alla tavolozza. Ad esempio se

Lx = (90 << 24) + (255 << 16) + (112 << 8) + 112

(ossia Lx = 1526689904) allora viene aperta una finestra logica di dimensioni pari a quelle che avrebbe con Lx = 90 ma con uno sfondo di un bel colore rosa che occupa automaticamente l'indice 8 della tavolozza.

La libreria sceglie se disegnare in nero o in bianco il sistema di riferimento e le quotature (se presenti) secondo lo sfondo assegnato alla finestra, in modo da ottimizzare il contrasto. Qualora la scelta non risulti soddisfacente utilizzare la funzione m_color_frame.

Se il secondo argomento è > 100 si intende che si vuole attribuire alla finestra delle dimensioni individuali. In questo caso il valore "normale" di Ly è posto nuovamente negli 8 bits di sinistra mentre i valori richiesti per larghezza e altezza della finestra occupano rispettivamente i bitfields 21->12 e 10->1. In pratica

Ly = (normale << 24) + (Larghezza << 11) + Altezza

Si noti che sono utilizzate solo dimensioni che utilizzino un numero PARI di pixels, a causa della necessità di lasciare liberi i bit 11 e 0 in vista del loro uso in connessione con l'uso della trasparenza. In altre parole fornire una larghezza dispari equivale a fornire la larghezza pari immediatamente superiore, attivando nel contempo la trasparenza e fornire un'altezza dispari equivale a fornire l'altezza pari immediatamente superiore, rendendo nel contempo opaco lo sfondo.

L'ultima cosa da dire sull'argomento Ly riguarda la possibilità di fruire della proprietà di doublebuffering per la finestra: ciò si ottiene in modo assai semplice "accendendo" il bit numero 22 di Ly. In pratica è sufficiente eseguire l'OR binario di Ly con la costante FINESTRA_DOPPIA che è opportunamente definita nell'header file passe_par_tout.h

Una finestra aperta in modalità double buffer ha il pregio di non "soffrire" di sfarfallìi al momento della ridisegnatura e il difetto di occupare il doppio della memoria presso il server grafico.

nota: sui moderni server grafici in ambiente Linux quest'opzione appare sempre meno rilevante, se non addirittura tendente a divenire superflua; tuttavia viene mantenuta per compatibilità con programmi più antichi e perché, in fondo, male non fa.

La libreria non mantiene più di 32 finestre aperte simultaneamente su ciascun display (reale o virtuale) su cui vien fatta lavorare: se si prova a chiederne di più la richiesta viene ignorata.

Alla finestra aperta viene attribuito il numero più basso (preso nell'insieme degli interi [0:31]) non ancora assegnato a un'altra finestra già aperta. Tale numero, aumentato di 1, è anche il valore che la funzione restituisce al chiamante: ciò gli/le consente di mantenere traccia dei numeri assegnati alle finestre in un contesto a finestre multiple.

Una finestra appena aperta riceve automaticamente tutto l'output grafico susseguente, fino alla successiva chiamata di m_window o a una chiamata di m_select ovvero a una chiamata di m_mouse cui faccia seguito un click su una finestra diversa da quella che sta ricevendo input (m_select implicita).

Questa funzione, in realtà, è predisposta a ricevere un numero variabile di argomenti ed è questo il significato dei puntini di sospensione scritti nel prototipo. Tale possibilità ha la seguente implicazione:

Se il bit del segno dell'argomento Lx è ON, fermo restando quanto fin qui affermato sul contenuto dei bit rimanenti, la libreria viene istruita ad associare alla finestra appena aperta su schermo un "file PostScript ombra" che obbedisce a tutte le caratteristiche della libreria stessa e sarà riempito con lo stesso disegno che appare su schermo. Quanto detto è diverso e più efficace di un semplice salvataggio della figura su file PS come effettuato da altre funzioni (cfr. m_save_pixmap o m_mouse).
Nel caso presente il disegno PostScript viene effettuato esattamente come se, accanto a ogni chiamata di routine che effettua output grafico sulla finestra, venisse eseguita anche la chiamata corrispondente che genera output PostScript. Va tenuto presente che, coerentemente con quanto appena detto, ogni output grafico indirizzato a una finestra che sia stata aperta col bit del segno di Lx nello stato ON, IMPLICA ANCHE LA SELEZIONE DEL SUO FILE POSTSCRIPT OMBRA (cfr. mindirizza_ps). Questo è estremamente rilevante per programmi che abbiano aperto anche degli altri files PostScript per i quali siano eseguite esplicitamente le funzioni della libreria.
I files PostScript ombra si inseriscono nella cronologia degli eventuali altri files PS (cfr. minizio_ps) in modo del tutto naturale, nel momento stesso in cui viene eseguita m_window. Questo significa che il programma chiamante ha facoltà piena di indirizzarsi esplicitamente a un file PostScript ombra ed eseguire delle funzioni di libreria che non sarebbero implicate da quelle a schermo.

I nomi dei files PostScript ombra sono, per default,

implicito_PS_N

ove N è il numero della finestra che "ombreggiano", aumentato di 1 (e.g. finestra numero 0 <--> implicito_PS_1).
Se si desidera fornire nomi diversi è necessario porre nello stato ON anche il bit del segno dell'argomento Ly. In questo caso, fermo restando quanto detto sopra circa il significato del contenuto dei restanti bits di Ly, la libreria è istruita a richiedere il nome del file PostScript ombra come terzo argomento di chiamata, di tipo stringa. Tale argomento però DEVE ESSERE, IN QUESTO CASO, OBBLIGATORIAMENTE FORNITO, pena impredicibili errori di esecuzione. I fortranisti ricordino quanto altrove detto circa i modi per trasferire stringhe alla libreria (cfr. m_conv_string e m_conv_chars).
Le dimensioni dei disegni generati coi files PostScript ombra riflettono quelle della finestra ombreggiata, secondo la proporzione di 600 pixels / 14 cm.

È definita la costante OMBREGGIA_FINESTRA, utile sia per richiedere l'apertura di un file PostScript ombra sia per cambiargli nome rispetto alla denominazione standard; ciò si ottiene tramite gli OR binari rispettivamente con il primo e il secondo argomento da trasferire a questa funzione.


Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700;
m_startg(u, &K, &L);
K = L = 95;
if(m_window(&K, &L))
printf("window riuscita\n");

m_endg(  );}


N.B.:
il programma precedente non fa assolutamente nulla di significativo, ma serve unicamente a mostrare una chiamata corretta della libreria. In un contesto reale non sarà obbligatorio "testare" il valore reso in uscita dalla libreria.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


















































































































m_snap_shadow(finestra, estensione)

Funzione efficace solo per finestre grafiche associate a files PostScript ombra (se eseguita in ogni altro contesto equivale a "nessuna azione").
Il primo argomento, di tipo int/INTEGER*4, indica la finestra cui ci si riferisce (e che, quindi, deve essere "ombreggiata"); come sempre deve essere finestra >= 0.
Il secondo argomento, dello stesso tipo del primo, viene usato come suffisso aggiuntivo per il nuovo file PS ombra aperto. In altre parole, all'atto dell'esecuzione di questa funzione, il file PS ombra corrente viene chiuso e abbandonato dal programma nello stato in cui si trova, ed è pronto per la stampa.
Al suo posto viene aperto un nuovo file PS ombra che conterrà quanto verrà successivamente disegnato nella finestra ombreggiata e il cui nome sarà
RADICE+M
ove RADICE è il nome con cui era stato aperto il primo file ombra e M è il valore di estensione convertito in stringa, purché sia estensione >= 1.


Esempio d'uso:

#include <passe_par_tout.h>

int main(int argc, char **argv, char **env)
{int K, L;
double xsc[  ]={-1.0, -1.0, 1.0, 1.0}, poly[6];
m_startg(const_cast<char *>("ad_libitum"), &(K=600), &(L=600)),
L = 80, K = (80 << 24) + (255 << 8),
K |= OMBREGGIA_FINESTRA, L |= OMBREGGIA_FINESTRA,
m_window(&K, &L, "purupu"),
m_frame(xsc, xsc+1, xsc+2, xsc+3);
if(argc > 1) m_use_as_pixmap(&(K=1), &(L=4));
poly[0] = poly[1] = poly[2] = 0.5,
m_color(&(K = m_new_color(poly, poly+1, poly+2))),
poly[0] = xsc[0] + 0.3333 * (xsc[2] - xsc[0]),
poly[1] = xsc[1] + 0.1433 * (xsc[3] - xsc[1]),
poly[2] = poly[0] + 0.1433 * (xsc[2] - xsc[0]),
poly[3] = poly[1] + 0.5 * (xsc[3] - xsc[1]),
poly[4] = poly[0] + 0.5 * (xsc[2] - xsc[0]),
poly[5] = poly[3] - 0.25 * (xsc[3] - xsc[1]),
m_polygon(poly, &(K=3)),
m_snap_shadow(&(K=0), &(L=1)),
poly[0] = 0.5 * (xsc[2] + xsc[0]),
poly[1] = 0.5 * (xsc[3] + xsc[1]),
poly[2] = 0.5 * (xsc[2] - xsc[0]),
poly[3] = 0.5 * (xsc[3] - xsc[1]),
m_color(&(L=ROSSO)),
m_ellipse(poly, poly+2, &L),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}

N.B.:
il programma precedente mostra l'uso della presente routine, unitamente ad alcune opzioni avanzate della libreria. La funzione m_window, ad esempio, è eseguita con tre argomenti invece di due, il terzo essendo il nome con cui si vuole aprire il primo file ombra.
Tale argomento viene "capito" perché è stato acceso il bit del segno in L e la finestra viene "ombreggiata" perché anche K ha il bit del segno acceso.
Il contenuto dei rimanenti bits di K fa sì che la finestra abbia uno sfondo verde.
Di seguito, se sulla linea comando viene fornito un argomento qualsiasi, la finestra viene associata a una pixmap di sfondo giallo, altrimenti resta una finestra "normale".
Viene poi tracciato un triangolo di colore grigio (per l'esecuzione di m_new_color) dopo di che si esegue m_snap_shadow e si copre il triangolo grigio con un cerchio rosso.
L'effetto complessivo è che, mentre sullo schermo rimarrà solo il cerchio rosso, si avranno nella cartella corrente due files PS ombra, di nomi purupu e purupu+1, il secondo dei quali conterrà il cerchio rosso mentre il primo conterrà il triangolo grigio.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































m_save_window(i, file)

permette di scrivere su file (in un formato riconoscibile dalla libreria) quanto contenuto nella finestra. In questo modo è possibile esportare dei disegni X11 tra diverse piattaforme o inviarli a qualche altro fruitore della libreria.

Il primo argomento è un INTEGER*4/int che indica la finestra da salvare (0<=i); il secondo argomento è una stringa che contiene il nome del file da scrivere.
Per i fortranisti vale quanto detto a proposito delle stringhe (cfr. generalità e funzioni m_conv_string e m_conv_chars).

Se la finestra indicata non è aperta non produce alcun effetto.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2];
int K=700, L = 700, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1,
m_how_clip(&K),
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x);
for(i=0; i < 1001; i++)
x[0] = xmin + (double)i*(xmax-xmin)/500.0, x[1] = pow(10.0, x[0]),
m_line(x);
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
K = 0,
m_save_window(&K, const_cast<char *>("save_window"));
m_endg(  );}

N.B.:
il programma precedente è identico a quello fornito come esempio d'uso di m_line, salvo l'aggiunta della creazione di un file di nome save_window (nella cartella corrente) causata dall'esecuzione di m_save_window immediatamente prima di m_endg.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"











































































m_load_window(i, file)

È la controparte di m_save_window e ha gli stessi argomenti con lo stesso significato. Serve ovviamente a "caricare" in una finestra quanto salvato in precedenza in un file.

La finestra di indice i non deve necessariamente essere già stata aperta con una chiamata a m_window anzi è preferibile che non lo sia se si intendono conservare le proprietà che la finestra possedeva quando era stata salvata (colore di sfondo, proporzioni e quant'altro).
Se la finestra di indice i è già aperta sullo schermo viene "caricata" con quanto estratto da file; ciò significa anche che non occorre comunque chiamare né m_frame né (eventualmente) m_use_as_pixmap perché le chiama implicitamente la libreria se il contenuto di file lo richiede. Tuttavia se c'è discrepanza tra il contenuto di file e le proporzioni e dimensioni con cui la finestra è stata aperta potrebbe accadere che risultino visibili solo alcune parti della figura ed esattamente quelle che cadono entro la regione di clipping (cfr. m_how_clip).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{char *u=const_cast<char *>("");
int K = 500, L = 500;
double x[2];
m_startg(u, &K, &L),
K = 0,
m_load_window(&K, args[1]),
m_mouse(x),
printf("%g %g\n", x[0], x[1]),
x[0] = 0.0, x[1] = 1.0,
m_move(x),
x[0] = 5.0, x[1] = 1.0e4,
m_line(x),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Per poter eseguire con successo il programma precedente bisogna prima aver eseguito quello riportato come esempio d'uso della funzione m_save_window oppure avere comunque nella cartella corrente un file generato dalla citata funzione: infatti il nome di tale file deve essere fornito come primo argomento sulla linea comando. Si osservi la voluta discrepanza fra gli argomenti qui forniti a m_startg rispetto a quelli forniti nel programma-esempio di m_save_window e il fatto che non sono state chiamate né m_windowm_frame. Questo presuppone, ovviamente, che si conosca il sistema di coordinate contenute nel file letto da m_load_window, tanto che, dopo un'esecuzione di m_mouse che potrebbe eventualmente, in coppia con una seconda chiamata, servire a ricavarlo, si procede al tracciamento di una nuova linea (con le chiamate alla coppia m_move, m_line) senza tener conto dei valori restituiti da m_mouse.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































m_wait_for_microseconds(microseconds)

Questa funzione si limita a sospendere l'esecuzione e a riprenderla quando sono trascorsi non meno di microseconds (INTEGER*4/int) microsecondi (e non più di tale valore aumentato del tempo necessario a eseguire una divisione e due addizioni floating_point).
Utile per adattare finemente gli intervalli di refresh durante eventuali animazioni. Non si ritiene indispensabile fornire un esempio del suo funzionamento.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

























































































m_wait_for_events(modo)

Funzione fornita per simulare, in forma semplificata, la XtAppMainLoop dell'intrinsic Toolkit di X11.

Serve a gestire gli eventi più rilevanti per gli scopi della libreria.

modo è una variabile intera (INTEGER*4/int): al momento gli unici valori riconosciuti sono modo=0 modo=999 e modo < 0.

modo = 0:
il programma va in loop infinito interrotto solo da un click del mouse su una qualsiasi finestra grafica. Al rilevamento del click il programma prosegue come se nulla fosse.

modo=999:
il programma va in loop infinito interrotto solo dalla pressione del tasto return sulla tastiera; tutte le finestre correntemente aperte vengono in questo caso "rinfrescate".

modo < 0:
il programma va in loop infinito interrotto solo da un click del mouse su una qualsiasi finestra grafica (come per modo=0). Dopo di che se abs(modo) <= 60 va in pausa per abs(modo) secondi al termine dei quali la finestra grafica su cui è stato fatto il click viene chiusa; se invece è abs(modo) > 60 si fa una pausa di 10 secondi dopo di che tutte le finestre grafiche vengono chiuse (eseguendo implicitamente una chiamata di m_endg).


Sono definite le costanti simboliche EVENTO_MOUSE ed EVENTO_ENTER da usare rispettivamente per i valori 0 e 999. Tale beneficio non è disponibile per i fortranisti.


Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = EVENTO_MOUSE,
m_wait_for_events(&K),
m_endg(  );}

N.B.:
In questo esempio di programma si vedrà apparire sullo schermo una finestra (vuota) che scomparirà al click del mouse al suo interno.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































































m_string_for_events(stringa, numfin)

Questa routine è funzionalmente analoga a m_loop_for_events con cui condivide tipo e significato dell'argomento numfin.
Il primo argomento è una stringa di char (regolarmente "terminata", i fortranisti tengano conto di quanto detto qui).
La funzione si interrompe solo quando si digita da tastiera uno dei caratteri che si trovano in stringa, restituendolo al chiamante come valore di ritorno.
In questo modo il chiamante può prendere decisioni diverse secondo il carattere digitato.

Qualora si inserisca nella posizione di stringa immediatamente precedente il terminatore il carattere ASCII di valore 1 (NON digitabile da tastiera) e siano in esercizio diversi DISPLAY la funzione "ritorna" quando l'evento di digitazione di uno dei caratteri di stringa avviene in uno qualsiasi dei DISPLAY collegati, altrimenti l'evento viene rilevato solo se avviene nel DISPLAY correntemente attivo.
Inoltre, sempre quando si pone il valore 1 immediatamente prima del valore 0, al ritorno dalla funzione l'argomento numfin è volontariamente modificato e assume il valore dell'indice del DISPLAY che ha ricevuto l'evento nei bit dal numero 4 in su e l'indice della finestra in cui l'evento è avvenuto nei bit 0-3.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 0,
cout << m_string_for_events(const_cast<char*>("cucu"), &K) << endl,
m_endg(  );}

N.B.:
In questo esempio di programma si vedrà apparire sullo schermo una finestra (gigantesca e vuota) che scomparirà quando si digiti o una 'c' o una 'u' che successivamente compare su standard output.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




























































































m_modified_key_events(elenco, numfin)

Questa funzione estende il comportamento di m_string_for_events ammettendo anche l'uso dei tasti modificatori: sono riconosciuti i tasti CONTROL (di sinistra e di destra) e i tasti ALT (di sinistra e di destra). L'argomento numfin ha lo stesso tipo e significato dell'omonimo argomento di m_string_for_events, compreso l'effetto di "modifica in uscita" colà descritto. L'argomento elenco, diversamente da quanto avviene per m_string_for_events, deve essere un puntatore a int/INTEGER*4 il cui ultimo elemento puntato deve valere zero (simulando in tal modo il carattere terminatore delle stringhe). Gli elementi precedenti puntati da evento hanno il significato di codici ASCII di caratteri (compresi quelli "speciali" ed esclusi ovviamente il codice nullo e il codice ASCII 1 se posto in penultima posizione [che, in tal caso, viene usato con lo stesso significato datogli da m_string_for_events]) eventualmente modificati con l'OR binario con le costanti predefinite

CONTROL_A
CONTROL_L
CONTROL_R
ALT_A
ALT_L
ALT_R

Quando la funzione viene invocata si innesca, come per le altre funzioni di "arresto esecuzione", un ciclo infinito interrotto solo dalla pressione di una combinazione di tasti compresa in elenco. Il valore numerico di tale combinazione è anche restituito al programma chiamante, che può così proseguire con diverse possibili strategie. È (o dovrebbe essere) del tutto intuitivo che, se nessuno degli elementi puntati da elenco effettua l'OR binario con le costanti suddette, l'esecuzione di questa funzione equivale a quella di m_string_for_events. Le costanti CONTROL_A e ALT_A sono, a loro volta, gli OR binari rispettivamente di CONTROL_L e CONTROL_R e di ALT_L e ALT_R; il loro uso implica pertanto la volontà del programmatore di NON distinguere i modificatori di sinistra da quelli di destra.

Esempio d'uso:

# include <passe_par_tout.h>
int main(int narg, char ** args, char ** env)
{double xmin = 0.0, ymin = 0.0, xmax = 2.0, ymax = 1.0, x[2], r[  ] = {0.02, 0.02};
int K, L, LL[  ]={0, 0, 0, 0, 0, 0};
char *V;
if(narg < 2) cout << "occorre un nome di display\n", exit(255);
m_startg(const_cast<char *>(""), &(K=800), &(L=400)),
cout << (V = m_which_display(&(K=0))) << endl << flush,
m_open_display(args[1]),
m_window(&(K=0), &(L=FINESTRA_DOPPIA)),
m_frame(&xmin, &ymin, &xmax, &ymax),
m_select_display(V, (int *)NULL);
m_window(&(K=0), &(L=FINESTRA_DOPPIA)),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin+r[0], x[1]=0.5*(ymin+ymax);
while(x[0] <= xmax-r[0])
m_clear(&(L=0)),
m_redraw(&(L=0)),
m_color(&(L=ROSSO)),
m_ellipse(x, r, &(L=1)),
m_redraw(&(L=0)), x[0] += 0.25*r[0],
m_wait_for_microseconds(&(L=30000));
m_wait_for_events(&(L=EVENTO_ENTER)),
cout << m_string_for_events(const_cast<char*>("abcde\001"), &(K=-1)) << endl,
cout << K << endl << flush,
m_loop_for_events(&(L=FRECCIA_SINISTRA), &(K=-1)),
m_loop_for_events(&(L='x'), &(K=-1)),
LL[0] = 'a' | CONTROL_L,
LL[1] = 'e' | CONTROL_R,
LL[2] = 't' | ALT_L,
LL[3] = 'Z',
LL[4] = 1,
cout << m_modified_key_events(LL, &(K=-1)) << endl,
cout << "K = " << K << endl,
m_endg(  );}

N.B.:
questo programma esemplifica non solo la presente funzione, ma anche le altre funzioni di attesa evento e perfino la loro interazione con l'uso di display multipli; vengono aperte due finestre, ciascuna su un potenzialmente diverso display. Nella seconda viene tracciata una pallina mobile che raggiunge il lato destro della finestra e si ferma.
Dopo ciò si eseguono in successione praticamente tutte le funzioni di "blocco" (eccettuate quelle che coinvolgono il mouse). Si osservino i valori restituiti da questa funzione e da m_string_for_events, inviati su standard output per opportuna conoscenza.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

























































































m_loop_for_events(modo, numfin)

Consente una gestione degli eventi X11 assai più sofisticata rispetto a m_wait_for_events.

In sostanza consiste in un loop infinito che contiene a ogni giro una chiamata a m_wait_for_events e può essere interrotto SOLO e SOLTANTO da un particolare evento a scelta tra il click del mouse e la pressione di UN PARTICOLARE TASTO della tastiera.

Inoltre, nel caso che siano in uso contemporaneamente più finestre, permette di scegliere se accettare eventi da una qualsiasi di esse o SOLAMENTE da una certa finestra selezionata.

I due argomenti sono interi (int/INTEGER*4).

modo indica il tipo di evento che interrompe il loop

modo = 0
click del mouse su una finestra grafica; (indifferentemente con quale bottone)

modo = n
pressione sulla tastiera del tasto (n > 0) numero n.
Qui n è da interpretare come il codice ASCII del carattere corrispondente.
Sono riconosciuti solo i caratteri ALFABETICI (maiuscoli .ne. minuscoli) e numerici della tastiera centrale (in tutto 62 possibilità).
PRATICAMENTE, per chi programma in C, è sufficiente chiamare la funzione con n uguale al carattere interessato scritto tra singoli apici (meraviglia), mentre per chi programma in FORTRAN n è il risultato della funzione ICHAR

modo = EVENTO_ENTER
pressione del tasto Return della tastiera centrale.

Il secondo argomento indica quale finestra è selezionata per l'interruzione del loop infinito da parte dell'evento prescelto col primo argomento.


numfin >= 0
Il loop si interrompe SOLTANTO quando l'evento selezionato si verifica col puntatore del mouse all'interno della finestra numero numfin (numfin = 0 indica "passe_par_tout 1" etc.)

numfin < 0
Il loop si interrompe quando avviene l'evento selezionato, indipendentemente dalla finestra in cui accade.


NESSUN TEST VIENE FATTO SUI VALORI IN INPUT DI modo e numfin

Se durante l'esecuzione di questa funzione con modo = n si preme da tastiera il carattere '!' (punto esclamativo) la funzione non esce (a meno che, coerentemente, non sia stato posto proprio modo = '!') ma effettua una chiamata implicita a m_save_pixmap per la finestra che ha ricevuto l'input; sarà prodotto un file PostScript di nome
passe_par_tout%d.ps,
con %d sostituito dal valore di numfin, che conterrà uno "snapshot" della finestra.

Quando si hanno DISPLAY multipli e si fornisce modo aumentato di 1000 significa che si ammette che la funzione sia "interrotta" e "ritorni" da qualunque DISPLAY abbia ricevuto l'evento; altrimenti la funzione ritorna solo se l'evento avviene nel DISPLAY correntemente attivo.
Se si accetta l'interruzione da qualunque DISPLAY la funzione modifica, al ritorno, l'argomento numfin allo stesso modo di m_string_for_events.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Con questo programma si vedrà apparire sullo schermo una finestra (gigantesca e vuota) che scomparirà solamente se si digiterà una A (maiuscola) da tastiera mentre il mouse è al suo interno.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"








































































m_flush(  )

Funzione senza argomenti; serve a svuotare la coda degli eventi ancora pendenti (non processati da parte del server X11), in modo da "sincronizzarla" con gli eventi che si intende generare successivamente. Raramente necessaria.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































m_redraw(n)

Provoca la ridisegnatura immediata di tutta la finestra numero n (int/INTEGER*4). n = 0 indica la finestra passe_par_tout 1 e così via. Raramente è necessaria perché in genere la libreria provvede da sé a una simile bisogna in seguito alle chiamate di m_wait_for_events o di m_loop_for_events.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"










































































m_frame(xmin, ymin, xmax, ymax)

Stabilisce la trasformazione tra le proprie coordinate e quelle di schermo e disegna un riferimento cartesiano in forma di quadrato attorno alla finestra logica definita da m_window.

I quattro argomenti sono REAL*8/double e hanno un significato parlante.

Le quotature sono poste solo alle estremità degli assi.

Per il trattamento di ciò che cade al di fuori del contorno riferirsi alla funzione m_how_clip.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Con questo programma si realizza la connessione tra una finestra e una regione del piano reale: il quadrato di lato 1 con un vertice nell'origine.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"










































































































m_reset_frame(frame, modo, param)

Questa funzione permette di modificare il sistema di riferimento della finestra corrente (quella che sta ricevendo output) conservando, su richiesta e in determinate condizioni, i disegni già fatti in modo che possano essere visualizzati da un diverso punto di vista. Inoltre è possibile, in determinate condizioni, far in modo che la transizione tra il sistema originario e quello finale avvenga con continuità (con progressione scelta dal programmatore) così che si possano vedere i disegni già fatti spostarsi diligentemente nelle loro nuove posizioni apparenti.

Il primo argomento, frame, di tipo REAL*8/double, deve puntare 4 elementi che rappresentano, nel consueto ordine (cfr. m_frame), i nuovi limiti del sistema di riferimento.
NON SONO CONSENTITE (almeno per ora) modifiche alla natura lineare/logaritmica degli assi.

Il secondo argomento, modo, di tipo stringa (ricordino i fortranisti come si trasmettono le stringe (cfr. m_convert_string)), rappresenta il modo operativo della funzione. Il contenuto della stringa è (almeno per ora) irrilevante: la funzione discrimina solo il valore booleano del puntatore associato. Se modo è il puntatore NULLO la transizione avviene SENZA CONSERVARE i disegni precedenti ed è, a QUASI tutti gli effetti, come se si aprisse una nuova finestra: la differenza consiste nel fatto che sono comunque CONSERVATI gli attributi della finestra (colori, tratteggi e quant'altro). Lo stesso effetto di PERDITA dei disegni precedenti, INDIPENDENTEMENTE dal valore di modo, si ha quando la finestra è dedicata a una pixmap (cfr. m_use_as_pixmap) e questo per l'ovvia ragione che, per conservare i disegni già fatti, occorrerebbe riscalare la pixmap e ciò provoca senz'altro risultati di qualità pessima. Un discorso simile si applica anche a tutti i disegni che siano frutto di esecuzioni di funzioni rasterizzate: questi, in seguito all'esecuzione della presente funzione, non vanno persi, ma restano INCOLLATI ai pixel in cui erano stati disegnati, senza subire alcun ridimensionamento (a ben vedere è la cosa giusta che deve succedere).
Nelle finestre NON dedicate a pixmap un valore non nullo del puntatore associato a modo attua la già citata transizione continua. In tal caso...

...entra in gioco l'ultimo argomento, param, di tipo INTEGER*4/int, che deve puntare 3 valori, dei quali SOLO il primo viene usato se modo è NULLO e SOLO se la finestra è ombreggiata (in tal caso lavora esattamente come il secondo argomento di m_snap_shadow cui si rimanda); il secondo e il terzo elemento puntati da param indicano rispettivamente il numero di passi discreti da usare per la transizione al nuovo sistema di riferimento e il numero di microsecondi di attesa tra un passo e l'altro della transizione. Ognuno si arrangi in base all'effetto che vuol ottenere, alla velocità della propria macchina e alla complessità del proprio disegno.

NOTA BENE: L'eventuale file PostScript che ombreggiasse la finestra NON SA NULLA di transizioni continue: dal suo punto di vista questa funzione agisce ESATTAMENTE come m_snap_shadow, chiudendo e lasciando pronto per la stampa il file ombreggiante relativo al vecchio sistema di riferimento (coi SUOI disegni) e disponendosi a continuare a ombreggiare la finestra con un file nuovo in cui finiranno solo i disegni successivi.
Del resto, per fare della cinematografia con i fogli di carta stampata, occorrerebbe un eccellente croupier, che l'autore della libreria non è affatto.

NOTA BENE: L'uso del double buffering (cfr. m_window) è tanto più auspicabile quanto maggiore è la complessità del disegno da trattenere (se lo si vuole, o lo si può, trattenere).

NOTA BENE: NON È CONSENTITO (almeno per ora) tentare di usare questa funzione AL POSTO di m_frame o di m_multiframe, ossia per stabilire il PRIMO sistema di riferimento della finestra; NEPPURE È CONSENTITO (almeno per ora) tentare di usare questa funzione in finestre che abbiano più di UN SOLO sistema di riferimento (cfr. ancora m_multiframe); la libreria NON HA alcuna protezione interna contro questi tentativi illeciti e chi ci prova si assume la responsabilità di MOLTO VEROSIMILI MALFUNZIONAMENTI E/O INTERRUZIONI ANOMALE del proprio programma.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char*>("");
double xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0, x[4];
int K=700, L = 700, l[  ]={1,300,100000};
m_startg(u, &K, &L),
K = L = 95,
K |= OMBREGGIA_FINESTRA, L |= FINESTRA_DOPPIA,
m_window(&K, &L),
m_use_as_pixmap(&(K=1), &(L=BIANCO)),
m_frame(&xmin, &ymin, &xmax, &ymax),
m_color(&(L=ROSSO)),
x[0] = xmin, x[1] = ymin,
m_move(x),
x[2] = x[3] = 1.0,
m_line(x+2),
K = -1,
m_loop_for_events(&(L='A'), &K),
x[2] = x[3] = 4.0, m_reset_frame(x, const_cast<char*>("a"), l),
m_loop_for_events(&(L='a'), &K),
x[1] = ymax,
m_move(x),
x[2] = 1.0, x[3] = 0.0,
m_line(x+2),
L = 'b',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma modifica il riferimento della finestra dalla box [0,0] - [1,1] alla [0,0] - [4,4].
Nel primo riferimento viene tracciata la diagonale y=x e nel secondo l'antidiagonale y=1-x. Il primo disegno permane se si omette l'invocazione di m_use_as_pixmap e la transizione tra i due sistemi avviene con continuità e risulta visibile sullo schermo.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































































m_color_frame(finestra, colore)

Funzione utile per stabilire con quale colore vada disegnato il riferimento della figura e i valori della scala, specialmente quando si utilizzano finestre con sfondi colorati (cfr. m_window). Non ha una controparte per grafica PostScript dato che si suppone che i supporti cartacei siano sempre costituiti da pagine di colore bianco (fino a prova contraria).
I due argomenti sono entrambi di tipo int/INTEGER*4: il primo rappresenta l'indice della finestra cui la funzione deve riferirsi e deve essere non negativo; il secondo rappresenta l'indice del colore che si vuole usare per tracciare il riferimento (preso nella tavolozza corrente) e deve essere quindi non superiore al numero totale di colori allocati al momento dell'esecuzione della funzione, diminuito di 1 (cfr. m_color, m_new_color, m_new_color_hcv).
Eventuali valori illegali di uno o entrambi gli argomenti comportano semplicemente l'invio di un messaggio sul canale stderr (se connesso, cfr. m_toggle_message) e il fatto che la funzione venga ignorata.
Peraltro ogni eventuale esecuzione di questa funzione con colori diversi per la stessa finestra implica che il colore del riferimento cambi effettivamente a ogni successiva ridisegnatura.

Se questa funzione non viene mai chiamata la libreria sceglie da sola se disegnare il riferimento in nero o in bianco secondo un predeterminato schema di colorazione connesso con la scelta del colore di sfondo.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{char *u=const_cast<char *>("");
int K=600, L = 600;
double x[  ]={-1.0, -1.0, 1.0, 1.0};
if(narg < 4) printf("voglio 3 argomenti\n"), exit(1);
m_startg(u, &K, &L);
L = 95, K = (95 << 24) + (atoi(args[1]) << 16) + (atoi(args[2]) << 8) + atoi(args[3]);
m_window(&K, &L),
m_color(&(K=VERDE)),
m_frame(x, x+1, x+2, x+3),
m_flush(  ),
m_redraw(&(K=0)),
m_flush(  ),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_color_frame(&(K=0), &(L=GIALLO)),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_move(x),
m_line(x+2),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}

N.B.:
Questo programma richiede sulla linea comando tre numeri interi compresi tra 0 e 255 che sono utilizzati come codifiche rgb dello sfondo da attribuire alla finestra. Si osservi come la libreria scelga di conseguenza il colore del riferimento. Successivamente l'esecuzione esplicita di m_color_frame implica che la scelta compiuta dalla libreria sia "contraddetta" e che il riferimento sia disegnato in giallo (nella tavolozza standard), mentre la linea diagonale resta colorata in verde (nella stessa tavolozza)

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



































































































m_multiframe(quanti, colonne, bordi, frames)

Consente di specificare un numero arbitrario di sistemi di riferimento (entro una doverosa ragionevolezza) nella medesima finestra (cfr. m_window).
Le proprietà della finestra quali il colore di tracciamento, (m_color), i simboli usati per disegnare punti (m_symbol), il tipo e lo spessore dei tratteggi delle linee (m_dash) e simili non diventano proprietà individuali dei sistemi di riferimento singoli, ma restano proprietà GLOBALI della finestra.
I primi due argomenti sono di tipo int/INTEGER*4, il terzo è un array/puntatore al tipo int/INTEGER*4 mentre l'ultimo argomento è un array/puntatore al tipo double/REAL*8.

quanti indica il numero di sistemi di riferimento richiesti: se è strettamente maggiore di zero (quanti = 0 è l'unico valore inaccettabile per questo argomento; se viene fornito tale valore la funzione restituisce un valore di ritorno nullo e non esegue alcun'altra azione, il che comporterebbe, con probabilità 1, l'interruzione anormale del programma) i quanti sistemi di riferimento sono TUTTI "geometricamente" identici, ossia occupano tutti lo stesso spazio all'interno della finestra. In questo caso colonne indica il numero di colonne in cui i sistemi di riferimento vanno disposti e il numero di righe ne consegue tramite una normale operazione di divisione con resto; i sistemi sono disposti ordinatamente da sinistra a destra e dall'alto al basso. bordi è un array di lunghezza 3 che contiene ordinatamente, nelle prime due locazioni, le spaziature orizzontali e verticali (in pixels) tra i sistemi di riferimento e nella terza locazione un valore intero che serve a decidere se e come disegnare i contorni di ognuno dei sistemi di riferimento. La spaziatura tra i sistemi di riferimento laterali e i bordi della finestra resta determinata dalla scelta operata tramite gli argomenti forniti a m_window all'atto della creazione della finestra medesima.
Se il terzo elemento di bordi vale 0 tutti i sistemi di riferimento richiesti sono contornati e quotati; se vale 1 sono contornati, ma non quotati (opzione utile se tutti sono uguali per non avere inutili "ripetizioni" della stessa quotatura); se è > 1 i sistemi di riferimento sono quotati, ma non contornati; se è negativo non sono né contornati né quotati. frames è un array di double/REAL*8 che serve a specificare le coordinate di ciascun sistema di riferimento (ordinatamente); l'array è organizzato in "sestetti", uno per ciascun sistema di riferimento, secondo il seguente schema:

frames{1} = valore minimo della coordinata orizzontale
frames{2} = valore minimo della coordinata verticale
frames{3} = valore massimo della coordinata orizzontale
frames{4} = valore massimo della coordinata verticale
frames{5} = se non nullo scala orizzontale logaritmica
frames{6} = se non nullo scala verticale logaritmica

Si possono fornire meno elementi di frames rispetto ai 6*quanti necessari: non appena la funzione trova il terzo componente di un "sestetto" uguale al primo componente dello stesso "sestetto" smette di cercare valori in frames e attribuisce al sistema di riferimento corrente e a tutti i successivi gli stessi valori dell'ultimo "sestetto" completamente fornito.
Questo significa che se tutti i riferimenti sono uguali basta fornire un solo "sestetto" seguito da tre numeri reali uguali.

Va notato che la seguente chiamata di questa funzione

m_multiframe(1, 1, m, frames)

equivale alla chiamata della coppia

m_log_scales(  )
m_frame(  )

con gli argomenti per m_frame tratti dalle prime 4 locazioni di frames e quelli per m_log_scales tratti dalle successive 2 locazioni. In questo caso il contenuto dell'array m è irrilevante.

Va altresì notato che la funzione corregge (ponendolo = 1) il valore di colonne nella seguente chiamata

m_multiframe(1, 5, m, frames)

Ciò potrebbe avere qualche rilievo per il programma chiamante che, come si sa, trasferisce per indirizzo alla funzione il valore di colonne.

Se il valore dell'argomento quanti è invece strettamente negativo il numero di sistemi richiesti è inteso come il valore assoluto dell'argomento, ma, in questo caso, la forma di ognuno degli abs(quanti) riferimenti deve essere specificata individualmente e può quindi essere del tutto conforme alla volontà del programmatore.
Per ottenere ciò l'interpretazione dei restanti argomenti cambia radicalmente.
L'argomento colonne perde ogni significato e si riduce a un semplice segnaposto.
L'argomento bordi NON DEVE PIÙ contenere solo tre valori, ma ne DEVE contenere 6*abs(quanti), ossia 6 per ciascun riferimento. Ogni "sestetto" di valori DEVE essere COMPLETO (si sottolinea che la funzione NON EFFETTUA ALCUN TEST SUGLI ARGOMENTI E SUL LORO VALORE) e contiene, nell'ordine:

L'argomento frames conserva la sua interpretazione.

Quando quanti è negativo la libreria esegue anche una quotatura più "raffinata" degli assi, non limitandosi a quotare solo minimo e massimo della scala. Più precisamente, su assi logaritmici sono quotate tutte le decadi e tutte le tacche interne di ogni decade; su assi lineari sono quotate un numero di suddivisioni che può essere scelto dall'utilizzatore (cfr. funzione m_quote).


La finestra per cui viene eseguita questa funzione conserva la sua caratteristica per quanto concerne la sua destinazione a pixmap (cfr. m_use_as_pixmap).

Un discorso a parte riguarda l'eventuale "ombreggiatura" della finestra su un file PostScript quando sia stata eseguita la presente funzione con quanti>1. In tal caso l'ombreggiatura avviene comunque come bitmap PostScript, indipendentemnete dalla natura della finestra in rapporto a m_use_as_pixmap.

All'uscita con successo dalla presente funzione il programma chiamante riceve un valore di ritorno non nullo e l'output grafico è automaticamente indirizzato al sistema di riferimento posto in alto a sinistra (eventualmente l'unico presente); cfr. m_select_frame.

Esempio d'uso, con primo argomento positivo:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double x[22], rgb[  ][3]={1.0, 0.8, 0.8, 0.8, 0.5, 0.0},
frame[  ]=
{-1.0, -1.0, 1.0, 1.0, 0, 0,
-2.0, -2.0, 2.0, 2.0, 0, 0,
-3.0, -3.0, 3.0, 3.0, 0, 0,
-4.0, -4.0, 4.0, 4.0, 0, 0,
-5.0, -5.0, 5.0, 5.0, 0, 0,
-6.0, -6.0, 6.0, 6.0, 0, 0,
-7.0, -7.0, 7.0, 7.0, 0, 0,
-8.0, -8.0, 8.0, 8.0, 0, 0,
-9.0, -9.0, 9.0, 9.0, 0, 0};
int K=700, L = 700, M, II[  ]={0, -1}, IO[  ]={50,50,0};
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_use_as_pixmap(&(K=1), &(L=7)),
m_multiframe(&(K=9), &(L=3), IO, frame);
for(M=0; M < 9; M++)
{II[0] = m_which_frame(&L),
m_select_frame(&(L=0), II);
if(M < 7) m_color(&(L=M));
else m_color(&(L = m_new_color(&rgb[M-7][0], &rgb[M-7][1], &rgb[M-7][2])));
for(K=0; K < 3+M; K++)
x[2*K] = 0.5*frame[6*M+2]*cos(2.0*M_PI*K/(3.+M)),
x[2*K+1] = 0.5*frame[6*M+2]*sin(2.0*M_PI*K/(3.+M));
m_polygon(x, &(K=3+M));
II[0]++,
m_select_frame(&(L=0), II);}
m_flush(  ),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
questo programma esemplifica simultaneamente l'uso della presente funzione e della funzione m_select_frame (cfr.). Disegna una finestra con 9 sistemi di riferimento tutti diversi tra loro in ciascuno dei quali viene disegnato un poligono di diverso colore e di numero di lati crescente (da un triangolo equilatero a un "endecagono").
Si notino, per inciso, la presenza e l'uso di m_polygon, di m_new_color (perché i colori iniziali sono solo 8, uno dei quali serve per lo sfondo) e di m_which_frame (che è stata inserita a titolo di esempio del suo uso, benché, nel caso presente, se ne potesse tranquillamente fare a meno).

Esempio d'uso, con primo argomento negativo:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double x[8],
frame[  ]=
{0.8, 0.8, 110, 110, 1, 1,
-2.0, -2.0, 2.0, 2.0, 0, 0};
int K=800, L = 800, M, II[  ]={0, -1}, IO[  ]={1, 1, 0, 0, 600, 700, 0, 1, 630, 0, 80, 700};
m_startg(u, &K, &L),
K = L = 95,
K |= OMBREGGIA_FINESTRA,
m_window(&K, &L),
m_use_as_pixmap(&(K=1), &(L=7)),
m_multiframe(&(K=-2), &(L=3), IO, frame);
for(M=0; M < 2; M++)
{II[0] = m_which_frame(&L),
m_select_frame(&(L=0), II);
m_color(&(L=M+3));
if(M) for(K=0; K < 3+M; K++)
x[2*K] = 0.5*frame[6*M+2]*cos(2.0*M_PI*K/(3.+M)),
x[2*K+1] = 0.5*frame[6*M+2]*sin(2.0*M_PI*K/(3.+M));
else x[0] = x[1] = 1.0, x[2] = x[3] = 100., x[4] = 10.0, x[5] = 1.0;
m_polygon(x, &(K=3+M));
II[0] ++,
m_select_frame(&(L=0), II);}
m_flush(  ),
K = -1, L = 'a',
m_loop_for_events(&L, &K),
m_endg(  );}

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































































m_select_frame(quale_finestra, quale_frame)

Serve a indirizzare output grafico a una finestra e/o a un particolare sistema di riferimento di una finestra a sistemi multipli (cfr. m_multiframe). Il primo argomento ha lo stesso significato dell'unico argomento di m_select cui questa funzione è totalmente equivalente qualora la finestra "destinataria" abbia un solo sistema di riferimento.
In caso contrario, oltre alla selezione della finestra, si ha anche la selezione di un particolare sistema di riferimento secondo i valori forniti nell'array di int/INTEGER*4 quale_frame. Tale array deve contenere 2 valori (se il secondo di essi è negativo) oppure 3 valori (se il terzo è negativo).
Nel primo caso il primo valore di quale_frame rappresenta l'indice assoluto del sistema di riferimento scelto, numerando con 1 (uno) il primo in alto a sinistra e crescendo verso destra e (poi) verso il basso.
Nel secondo caso i primi due valori di quale_frame indicano rispettivamente la riga e la colonna del sistema di riferimento in questione, numerando con 1 (uno) la riga superiore e con 1 (uno) la colonna di sinistra.
Eventuali valori fuori intervallo fanno sì che l'esecuzione di questa funzione sia irrilevante.
Per un esempio d'uso si rinvia a m_multiframe.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_log_scales(s)

Permette di introdurre scale logaritmiche; s è un array (INTEGER*4/int) di due elementi, il primo per l'asse orizzontale e il secondo per l'asse verticale; il valore 0 (default) di ciascuna componente indica che il corrispondente asse è lineare, mentre qualsiasi valore non nullo lo fa diventare logaritmico.

La funzione è efficace SOLO SE chiamata prima di m_frame relativamente alla stessa finestra.

I valori degli argomenti successivamente trasferiti a m_frame devono continuare a essere quelli naturali (e NON I LORO LOGARITMI se sono state chieste scale logaritmiche).

È RESPONSABILITÀ DEL PROGRAMMA CHIAMANTE CHE LE COORDINATE PLOTTATE SU UN ASSE LOGARITMICO SIANO SEMPRE POSITIVE. NESSUN TEST VIENE FATTO A TAL PROPOSITO.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 1.0, ymin = 0.0, xmax = 100000.0, ymax = 1.0;
int K=700, L = 700, s[  ]={1,0};
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}


N.B.:
Con questo programma si definisce una scala semilogaritmica sull'asse x.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




































































m_how_clip(modo)

Seleziona il modo in cui viene effettuato il clipping su una finestra a schermo;

modo è un intero (INTEGER*4/int).

Quando modo=1 (default) si ha un clipping duro: ciò significa che quel che cade fuori degli assi non viene disegnato;

Quando modo=0 (clipping morbido) ciò che cade al di fuori del sistema di assi viene disegnato, anche qualora cadesse nei bordi esterni (se presenti) della finestra; ciò non si applica a un'eventuale pixmap, che NON ha bordi esterni.

Se modo=-1, quando si eseguirà m_line la linea richiesta NON sarà tracciata affatto se anche solo una sua minima parte cadesse al di fuori del sistema di riferimento. Ciò può risultare utile (senza la pretesa di prevedere tutti i casi possibili) per prevenire "incidenti" di quelli che accadono se si traccia un grafico prelevando dati da un puntatore o da un banco di memoria senza fermarsi quando i dati perdono di significatività rispetto al grafico in questione.
Nell'esempio d'uso sotto riportato si sfrutta questa caratteristica: l'ultima coppia di coordinate trasmessa a m_line è volutamente estranea al grafico del coseno; si osservi il diverso comportamento del programma fornendo 0, 1 o 2 argomenti supplementari sulla linea di esecuzione (il che comporta l'esecuzione della presente funzione trasmettendole rispettivamente per il proprio argomento i valori 1, -1 e 0).
È comunque sempre preferibile non incorrere in simili patologie e mantenere il clipping default, specialmente se i disegni "escono" dal sistema di riferimento per diversi ordini di grandezza: in tal caso, oltre ai rischi di overflow numerico, contro cui la libreria non ha alcuna protezione, si può anche incorrere, se non si usa il clipping default, nella sindrome del superamento del massimo intero rappresentabile (un pixel teoricamente lontanissimo, e lontanissimo oltre il lecito), con conseguente comparsa di tratti disegnati che nulla c'entrano col disegno effettivo.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, const char ** args)
{char *u=const_cast<char*>("linea");
double xmin = 0.0, ymin = -1, xmax = 6.28, ymax = 1, x[2];
int K=800, L = 800, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = (narg<=2) - 2*(narg==2),
m_how_clip(&K);
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = cos(x[0]), m_move(x);
for(i=0; i < 501; i++) x[0] = xmin + (double)i*(xmax-xmin)/500.0,
x[1] = cos(x[0]), m_line(x);
x[0] = -2, x[1] = -6, m_line(x),
K = -1, L = 'a',
m_flush(  ),
m_loop_for_events(&L, &K),
m_endg(  );}


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"











































































m_move(x)

Sposta il punto corrente (senza tracciare nulla) ponendolo nella posizione indicata dal vettore x (REAL*8/double) di lunghezza 2, dato in coordinate utente.

Serve a inizializzare una nuova linea ed è analoga del comando PostScript moveto

Esempio d'uso: cfr. esempio fornito in m_line.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
















































































m_line(x)

traccia una linea (nel tratteggio corrente: default = linea continua) che congiunge il punto corrente col punto x (vettore REAL*8/ double di lunghezza 2).
Il punto x diventa altresì il nuovo punto corrente.

Può essere chiamata SOLO dopo un'altra chiamata di m_line o dopo una chiamata a m_move o a m_point.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2];
int K=700, L = 700, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1,
m_how_clip(&K),
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x);
for(i=0; i < 1001; i++)
x[0] = xmin + (double)i*(xmax-xmin)/500.0, x[1] = pow(10.0, x[0]),
m_line(x);
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Con questo programma si realizza un grafico effettivo come esempio simultaneo d'uso delle funzioni m_line e m_move: si plotta in scala semilogaritmica (sull'asse y) la funzione 10^x con 0<=x<=5.
I dati in eccesso rispetto alla scala stabilita con m_frame sono tagliati via dal grafico grazie alla funzione m_how_clip. Si osservi che m_move deve essere eseguita prima del loop che disegna la curva. Per avere visione effettiva del disegno occorre evitare che m_loop_for_events ritorni prima che lo si desideri: ciò si ottiene digitando da tastiera tutto tranne una 'A' maiuscola che farebbe terminare il programma. La chiamata di m_flush è opzionale e serve ad avere la curva immediatamente visualizzata senza dover attendere il rilevamento del primo evento da parte di m_loop_for_events.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"













































































primitive rasterizzate

Si tratta di una collezione di funzioni che, se non fosse necessaria la compatibilità col Fortran, potrebbero essere un semplice overload delle funzioni omologhe rispettive, ossia di m_line, m_move, m_point, m_vector, m_text, m_ellipse, m_arc m_target e m_polygon. Invece sono implementate come funzioni distinte, appendendo ai nomi il suffisso _int (e.g. m_line --> m_line_int). Si comportano esattamente come le loro omologhe, cui si rimanda per il significato, con queste sole differenze (oltre l'evidenza del nome):



Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = -10.0, ymin = -10.0, xmax = 10.0, ymax = 10.0, x[2], t[2], sec[  ]={0, 270, 30};
int K=600, L = 600, s[2], as[2], isec[  ]={0, 270, 30};
m_startg(u, &K, &L), K = L = 95, m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax);
x[0] = x[1] = 0.0, t[0] = 6.0, t[1] = 3.0, m_arc(x, t, sec, &(K=0)),
K = -1, L = 'a', m_flush(  ), m_loop_for_events(&L, &K),
m_clear(&(K=0)),
x[0] = x[1] = 0.0, t[0] = 6.0, t[1] = 3.0, m_arc(x, t, sec, &(K=1)),
K = -1, L = 'b', m_flush(  ), m_loop_for_events(&L, &K),
m_clear(&(K=0)),
s[0] = s[1] = 300, as[0] = 60, as[1] = 30, m_arc_int(s, as, isec, &(K=0)),
K = -1, L = 'c', m_flush(  ), m_loop_for_events(&L, &K),
m_clear(&(K=0)),
s[0] = s[1] = 300, as[0] = 60, as[1] = 30, m_arc_int(s, as, isec, &(K=1)),
K = -1, L = 'd', m_flush(  ), m_loop_for_events(&L, &K), m_endg(  );}


Questo programma, utilizzando m_arc e m_arc_int come prototipi, illustra la differenza di comportamento tra le due famiglie di funzioni. Si osservi come m_arc tracci successivamente due settori ellittici inclinati di 30 gradi e di ampiezza pari a 3/4 di angolo giro (uno vuoto e uno pieno) usando le coordinate poste da m_frame e come successivamente m_arc_int ne disegni altri due (sempre uno vuoto e uno pieno e con la stessa inclinazione) usando direttamente coordinate intere corrispondenti ai pixels della finestra.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"







































































m_point(x)

Marca un punto con un simbolo default (cfr. m_symbol).

Le coordinate utente del punto sono nel vettore di lunghezza 2 (REAL*8/double) x. Il punto x diventa altresì il nuovo punto corrente.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2];
int K=700, L = 700, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1,
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x);
for(i=0; i < 51; i++)
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
m_point(x);
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma è identico a quello fornito come esempio di m_line che è sostituita con m_point. Inoltre m_flush è stata sostituita con m_redraw (opzionale) ed è stata abolita la chiamata di m_how_clip.
Contestualmente il numero di dati è stato riportato al valore necessario e sufficiente.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































m_mouse(x)
m_mouse_from_any(x)

Si tratta della stessa funzione: la descrizione della differenza tra le due è rinviata alla fine del corrente capitolo.
Restituisce nel vettore REAL*8/double x (di lunghezza 2) le coordinate utente (rispetto al riferimento stabilito da m_frame) del punto su cui è stato portato (e attivato) il cursore.

Ciò implica anche una chiamata di m_select per quella finestra.

Per far eseguire effettivamente la lettura del punto basta premere un bottone qualsiasi del mouse; tuttavia la pressione del bottone destro ha un effetto collaterale non trascurabile: in tal caso, oltre a restituire le coordinate del punto cliccato, si effettua anche una chiamata implicita a m_save_pixmap per la finestra che ha ricevuto il click; sarà prodotto un file PostScript di nome passe_par_tout%d.ps, con %d sostituito dal valore del numero della finestra su cui è stato prodotto il click, che conterrà uno "snapshot" della finestra stessa.

Occorre prestare molta attenzione a non "oscurare" parti della finestra quando si prema il bottone destro del mouse altrimenti il programma ABORTISCE. La libreria provvede da sé a "innalzare" la finestra al di sopra di tutte le altre, ma non può essere protetta contro azioni compiute "manualmente" dall'utilizzatore.

La funzione restituisce 1,2 o 3 secondo il bottone premuto (sinitro, centrale o destro rispettivamente)

NOTA BENE: quando si esegue il click del mouse su una finestra per cui sia stata eseguita la funzione m_multiframe le coordinate restituite in x sono relative al sistema di riferimento entro il quale il click ha avuto luogo.
Qualora il click avvenga entro le spaziature tra un sistema di riferimento e un altro, o al di fuori di tutti i sistemi di riferimento, i valori restituiti in x non sono attendibili.
Se il click del mouse avviene all'interno di uno dei sistemi di riferimento si ha come effetto collaterale un'esecuzione implicita di m_select_frame per quel sistema di riferimento; se invece il click avviene nelle spaziature tra un sistema di riferimento e l'altro oppure nella bordatura esterna il sistema di riferimento corrente resta invariato.

Se si effettua il click del mouse su una finestra dedicata a un istogramma tridimensionale (m_use_as_lego) i valori restituiti in x sono del tutto inattendibili e la funzione ha come solo effetto la ridisegnatura della finestra e la restituzione del valore del bottone del mouse che è stato cliccato.

La variante m_mouse_from_any permette, nel caso siano connessi almeno due DISPLAY, di accettare eventi di click di mouse da uno qualsiasi dei DISPLAY connessi, mentre la variante m_mouse accetta eventi provenienti solo dal DISPLAY correntemente attivo. Con lo stesso meccanismo proprio di m_mouse anche m_mouse_from_any rende automaticamente attivo il DISPLAY su cui è stato effettuato il click e la finestra che lo ha ricevuto.
L'informazione contenuta nel valore restituito dalla funzione conserva il numero del bottone premuto nei quattro bit meno significativi, l'indice del DISPLAY selezionato a partire dal bit numero 4 e l'indice della finestra su cui il click è avvenuto a partire dal bit numero 8.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = -3.0, ymin = -3.0, xmax = 3.0, ymax = 3.0, x[2], z[2],
frame[  ]={-1.0, -1.0, 1.0, 1.0, 0, 0, -2.0, -2.0, 2.0, 2.0, 0, 0, -3.0, -3.0, 3.0, 3.0, 0, 0, -4.0, -4.0, 4.0, 4.0, 0, 0};
int K=600, L=600, i, IO[  ]={20,20};
m_startg(u, &K, &L);
for(i=0; i < 2; i++)
K = 95, L = i*((95<<24) + (200<<11) + 200)+95*(1-i), m_window(&K, &L);
m_use_as_pixmap(&(K=1), &(L=1));
if(!m_frame(&xmin, &ymin, &xmax, &ymax)) exit(0);
m_select(&(i=0));
if(!m_multiframe(&(K=4), &(L=2), IO, frame)) exit(0);
i = 1, m_select(&i),
x[0] = xmin, x[1] = ymin, m_move(x), x[0] = xmax, x[1] = ymax, m_line(x),
i = 0, x[0] = frame[0], x[1] = frame[1], m_select(&i), m_move(x),
x[0] = frame[2], x[1] = frame[3], m_line(x), m_flush(  );
for(i=0; i < 2; i++) m_redraw(&i);
K = EVENTO_ENTER, m_wait_for_events(&K),
printf("sulla finestra attuale è attivo il frame %d\n", m_which_frame(&K));

while(1)
{i = m_mouse(x),
printf("lette coordinate %g %g\n", x[0], x[1]);

if(m_which_window(&K) && x[0] < xmin || !m_which_window(&L) && i == 3) break;
if(i == 2 && !m_which_window(&K))
i = 6*(m_which_frame(&K)-1), z[0] = frame[i], z[1] = frame[3+i], m_move(z), m_line(x);
printf("sulla finestra attuale è attivo il frame %d\n", m_which_frame(&K));}
m_endg(  );}

N.B.:
Questo programma mostra le proprietà di questa funzione congiuntamente ad alcune altre, come m_multiframe, m_which_frame, m_which_window, ... Si noti che il programma contiene un ciclo infinito che può essere interrotto in due soli modi:

  1. o cliccando con qualsiasi bottone del mouse entro il margine esterno sinistro della finestra più piccola

  2. o cliccando col bottone destro all'interno della finestra più grande. In questo caso, prima di uscire, il programma produce un'immagine PostScript della finestra.

Si osservi il diverso comportamento del programma quando si effettuano click col bottone sinistro o col bottone centrale nella finestra grande. Se si usa il bottone sinistro il programma si limita a scrivere le coordinate lette, come quando si clicca sulla finestra piccola. Se invece si usa il bottone centrale si cambia il sistema di riferimento attivo, come è testimoniato dal tracciamento di una linea che congiunge il punto cliccato col vertice superiore sinistro del sistema di riferimento.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































m_mouse_int(x)
m_mouse_int_from_any(x)

Questa funzione si comporta esattamente come m_mouse (e come m_mouse_from_any) sotto tutti i punti di vista, eccettuati i seguenti tre fatti:

  1. l'argomento    x   è un array di due INTEGER*4/int anziché di due REAL*8/double (come suggerito dal nome stesso)

  2. l'argomento    x   contiene in uscita dalla funzione le due coordinate del punto su cui è stato effettuato il click espresse in pixels (ossia in coordinate X11) a partire dall'origine posta nel vertice superiore sinistro della finestra (e non nelle coordinate dell'utente).

  3. le coordinate così riportate non dipendono neppure dal sistema di riferimento entro cui è stato effettuato il click (qualora sulla finestra che lo riceve sia stata eseguita la funzione m_multiframe); tuttavia la selezione implicita del sistema di riferimento ha luogo ugualmente (come sottinteso nelle prime due righe della presente spiegazione).

Non si ritiene necessario fornire un esempio d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




































































m_clear(n)

permette la cancellazione di tutto quanto contenuto nella finestra numero n (INTEGER*4/int); 0<=n.
Ciò implica anche la "liberazione" completa di tutta la memoria impegnata per il refresh della finestra, che torna quindi a essere completamente disponibile.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2];
int K=700, L = 700, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1,
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x);
for(i=0; i < 51; i++)
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
m_point(x);
K = 0,
m_redraw(&K),
L = EVENTO_ENTER,
m_wait_for_events(&L),
m_clear(&K),
x[0] = xmin, x[1] = pow(10.0, xmax),
m_move(x);
for(i=0; i < 51; i++)
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, xmax-x[0]),
m_line(x);
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma riprende quello fornito come esempio di m_point. Dopo la realizzazione dello stesso disegno si esegue m_clear preceduta da m_wait_for_events che chiede la pressione del tasto <Return> da tastiera. Dopo ciò viene fatto un altro disegno sulla diagonale opposta.

Nel codice seguente uno pseudo-pianeta compie un'orbita circolare "accompagnato" da un ancor più pseudo-satellite che gli ruota attorno violando vergognosamente le leggi di Keplero.
I due presunti "corpi celesti", che in realtà sono inizialmente neri, mutano il loro colore con continuità durante la rivoluzione, virando verso un indecoroso "rossiccio".
Si invitano gli studenti a sperimentare in che modo cambiare il programma per rendere più dignitosi sia la dinamica sia la colorazione.

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char*>("");
double
xmin = -10.0, ymin = -10.0, xmax = 10.0, ymax = 10.0,
x[2], phi = 0, t[2], r, g = 0, b = 0;
int K=900, L = 900, conta = 0;
m_startg(u, &K, &L),
K = L = 0, L |= FINESTRA_DOPPIA,
m_window(&K, &L),
K = 1,
m_frame(&xmin, &ymin, &xmax, &ymax);
t[0] = 0.6, t[1] = 0.6;
while(phi <= 2.0*M_PI)
++ conta,
r = phi / (2.5*M_PI),
m_symbol(&(L=3)),
m_clear(&(L=0)),
m_redraw(&L),
conta % 10 ? 0 : m_color(&(L=m_new_color(&r, &g, &b))),
x[0] = 7.0*cos(phi), x[1] = 7.0 * sin(phi),
m_ellipse(x, t, &K),
x[0] += 2 * t[0] * cos(3*phi),
x[1] += 2.5 * t[0] * sin(3*phi),
m_point(x),
m_flush(  ),
phi += 0.02,
m_wait_for_microseconds(&(L=50000)),
m_redraw(&(L=0));
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"














































































m_color(n)

dopo questa chiamata ogni cosa viene disegnata nel colore numero n (INTEGER*4/int) di una tavolozza predefinita.

I valori di n inizialmente accettabili (cfr. m_new_color) sono compresi tra 0 e 7 (inclusi) e rappresentano gli otto colori fondamentali della tavolozza standard: (nero, rosso, verde, blu, giallo, cyan, magenta, bianco).

Se si fornisce un valore negativo nell'intervallo
-N <= n <= -1
ove N è il numero corrente di colori nella tavolozza (inizialmente 8) il colore abs(n)-1 viene attribuito allo sfondo (cfr. anche m_window e m_use_as_pixmap)

Se si fornisce un valore fuori intervallo non ha alcun effetto.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2];
int K=700, L = 700, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1,
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x);
for(i=0; i < 51; i++)
K = i % 8,
m_color(&K),
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
m_line(x);
K = 0,
m_redraw(&K),
L = EVENTO_ENTER,
m_wait_for_events(&L),
m_endg(  );}

N.B.:
Questo programma è identico a quello fornito come esempio di m_line, ma i tratti sono ciclicamente disegnati con tutti i colori della tavolozza default.
Al termine la pressione di <Return> richiesta da m_wait_for_events provoca l'uscita dal programma.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































































m_get_color(n, x, s, r, g, b)

Permette di ottenere il colore posto in un determinato pixel della finestra grafica; i fortranisti usino questa funzione come function piuttosto che come subroutine (cfr. generalità), poiché l'indice del colore presente nel pixel viene restituito come valore di uscita del programma (ed è quindi utilizzabile come argomento per la funzione m_color).

Negli argomenti REAL*8/double r, g, b sono invece restituite le componenti RGB del colore del pixel (utilizzabili come argomenti per altre funzioni della libreria che richiedano tale input).

L'argomento n, di tipo INTEGER*4/int, è l'indice della finestra in cui va letto il colore (0<= n < 32, come d'abitudine; cfr. m_window);

Gli argomenti x e s, rispettivamente di tipo REAL*8/double e INTEGER*4/int, sono arrays di due elementi e contengono:

x:
le coordinate utente del pixel da leggere, relative al sistema di riferimento stabilito con m_frame;
s:
la posizione del pixel da leggere entro la finestra, misurate, secondo le regole del server X11, partendo dall'angolo superiore sinistro della finestra (posizione [0,0]).

La funzione usa i valori dell'array s per localizzare il pixel da leggere, a meno che almeno una delle componenti di s sia negativa: in questo caso si utilizzano i valori dell'array x.

Se per qualsiasi ragione il pixel non può essere localizzato (valori fuori scala o qualsiasi altro problema) il programma restituisce un valore negativo e invia un messaggio di avvertimento su stderr (purché connesso, cfr. m_toggle_message); in tal caso anche i valori resi in r, g, b sono del tutto inaffidabili.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2], r, g, b;
int K=600, L = 600, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1,
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x);
for(i=0; i < 51; i++)
s[1] = i % 8,
m_color(s+1),
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
m_point(x);
K = 0,
m_redraw(&K),
s[1] = -1;
for(i=0; i < 51; i++)
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
printf("il colore con cui è stato disegnato il %i-esimo punto ha indice %d\n",
i+1, m_get_color(s+0, x, s, &r, &g, &b)),
printf("e le seguenti componenti RGB: %g %g %g\n", r, g, b);
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma è identico a quello fornito come esempio d'uso di m_point, salvo il fatto che i punti sono disegnati variando ciclicamente il colore; al termine del disegno le esecuzioni di m_get_color inviano su stdout le informazioni relative ai colori dei punti disegnati.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
















































































m_new_color(r, g, b)

Questa funzione serve ad aggiungere (quando il server X11 lo consente) un nuovo colore alla tavolozza.

I tre argomenti sono dei REAL*8/double compresi tra 0.0 e 1.0 e indicano rispettivamente la quantità di rosso, verde e blu del colore da aggiungere.
La funzione restituisce (se ha successo) un intero da usare successivamente come argomento per m_color.

Se invece non ha successo restituisce 0 (zero), che comunque rappresenta il colore default (nero).

Questo è rilevante per chi programma in FORTRAN e usa le chiamate di subroutines anziché di functions (e.g. call m_new_color(r, g, b)); un tale utente dovrà tener conto che ogni chiamata efficace di m_new_color assegna il nuovo colore a un indice di tavolozza incrementato di una unità e che m_new_color è chiamata implicitamente una volta da m_window qualora si utilizzi la proprietà di tale funzione di inizializzare la finestra con un colore di sfondo diverso da quello default.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2],
r, g, b;
int K=700, L = 700, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1,
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax), x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x);
for(i=0; i < 26; i++)
K = i % 8,
m_color(&K),
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
m_line(x);
for(i=26; i < 51; i++)
r = (double)i/50.0, g = r * 0.75, b = g * 0.75,
K = m_new_color(&r, &g, &b),
m_color(&K),
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
m_line(x);
K = 0,
m_redraw(&K),
L = EVENTO_ENTER,
m_wait_for_events(&L),
m_endg(  );}

N.B.:
Questo programma è identico a quello fornito come esempio di m_color, ma la seconda metà della linea è disegnata con 25 nuovi colori diversi che sfumano dal marrone scuro all'arancio chiaro.
Al termine la pressione di <Return> richiesta da m_wait_for_events provoca l'uscita dal programma.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































m_new_color_hcv(h, c, v, flag, rgb)

Questa funzione è un cosiddetto "wrapper" della funzione m_new_color quando l'argomento flag (INTEGER*4/int) è non nullo.

Consente di aggiungere alla tavolozza un nuovo colore specificato in modo HCV (Hue, Chroma, Value).

I tre valori HCV sono ovviamente forniti nei primi tre argomenti (rispettivamente) di tipo REAL*8/double.

L'intervallo significativo è [0,1] per tutti e tre.

L'ultimo argomento rgb è un array di REAL*8/double di lunghezza 3 che contiene in uscita i valori RGB corrispondenti ai valori HCV forniti. È questa altresì l'unica azione compiuta dalla funzione quando l'argomento flag è nullo.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{int K, L, M, N, O, P = 256, Q;
double
x[  ]={0.0, 0.0, 16.0, 16.0, 0.0, 0.0, 0.0, 0.0},
dx = 1.0, h0 = 0.0, h1 = 1.0, h, c, v, cc, vv;
unsigned char b, bb;
if(narg < 3)
cout <<
"fornire crominanza e luminanza tra -1 e 1;\
opzionalmente seguono hue_iniziale hue_finale\n",

exit(1);
switch(narg) {case 5: h1 = atof(args[4]); case 4: h0 = atof(args[3]);}
c = fabs(cc = atof(args[1])), v = fabs(vv = atof(args[2])),
bb = cc < 0.0, b = bb || vv < 0.0, Q = 8*bb,
m_startg(const_cast<char *>(""), &(K=600), &(L=600)),
m_toggle_message(  ), m_window(&(K=0), &(L=0)), m_frame(x, x+1, x+2, x+3);
if(!bb) for(M=7; M >= 0; M--) m_remove_color(&M); else P = 128;
for(M=Q; M < P+Q; M++)
h = h0 + (h1-h0)*(M-Q)/(P-1.0),
m_new_color_hcv(&h, &c, &v, &(L=1), x);

N = (16 << (4*b))/(1+bb), O = 16 >> (4*b), dx /= (16.0*b + 1.0 - b);
for(M=0; M < N; M++)
{x[0] = 0.0, x[1] = x[3] = M*dx*(1 + bb);
for(L=0; L < O; L++)
x[6] = x[0], x[2] = x[4] = x[0] + dx*(256.0*b + 1.0 - b),
x[5] = x[7] = x[1] + dx * (1 + bb),
m_color(&(K = ((M*16+L)*!b + M*b) + Q)),
m_polygon(x, &(K=4)),
x[0] += (dx * (1+bb));}
m_redraw(&(K=0)),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}

N.B.:
Questo breve programma, secondo i valori assegnati sulla linea comando, disegna un'intera tavolozza di 256 colori, tutti ottenuti con la presente funzione oppure realizza gradevoli "sfondi sfumati" per le finestre.
Si osservi, a tal proposito, che gli otto colori iniziali possono opzionalmente essere rimossi attraverso la funzione m_remove_color, a meno che non si fornisca per la crominanza un valore negativo di cui sarà utilizzato il valore assoluto.
Il programma richiede obbligatoriamente sulla linea comando i valori di crominanza e luminanza: se si fornisce per entrambi il massimo (1) si ottiene una tavolozza di colori completamente saturi e con tutte le possibili tonalità di colore, separate ciascuna di un "quanto" pari a 1/255. Viene lasciata agli utenti la sperimentazione di diversi valori di crominanza e luminanza, così come l'esplorazione fine delle diverse tonalità fornendo anche intervalli "ristretti" di hue sulla linea comando.
Al termine la pressione di <Return> richiesta da m_wait_for_events provoca l'uscita dal programma.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"








































































































m_insert_color(r, g, b, indice)

Questa funzione lavora come m_new_color di cui è un semplice involucro. Gli argomenti r, g, b hanno lo stesso significato colà stabilito e valgono tutte le indicazioni date per quella funzione.
L'argomento aggiuntivo indice (di tipo int/INTEGER*4) fa però sì che il nuovo colore (qualora disponibile) sia aggiunto nella posizione indice della tavolozza.
Tutti gli altri colori (di posizione più alta) già presenti nella tavolozza si spostano diligentemente per far posto al nuovo colore e quindi cambiano indice e vanno quindi "cercati" con un valore aumentato di 1 rispetto a prima che la presente funzione venisse eseguita con successo.
Va da sé che indice deve essere non negativo e non maggiore del numero N di colori precedentemente presenti nella tavolozza e che l'esecuzione di
m_insert_color(r, g, b, N)
equivale in toto a quella di m_new_color(r,g,b).
Se la funzione ha successo restituisce in uscita il valore
indice + 1
mentre se fallisce (lasciando la tavolozza intatta) restituisce 0.
Per l'esempio d'uso si rimanda alla funzione m_remap_colors.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






























































































m_insert_color_hcv(h, c, v, indice, flag, rgb)

Questa funzione è identica a m_insert_color con la sola differenza che i primi tre argomenti rappresentano le componenti hue, chroma e value del colore da inserire mentre gli ultimi due hanno lo stesso tipo, significato e funzionalità degli ultimi due argomenti di m_new_color_hcv.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





































































































































































































m_remove_color(indice)

Questa funzione elimina dalla tavolozza il colore di posizione indice (int/INTEGER*4). Il valore di indice deve ovviamente essere non negativo e minore strettamente del numero totale di colori presenti nella tavolozza. La tavolozza viene ricompattata, così che i colori di posizione più alta rispetto a indice diminuiscono di una unità la loro posizione entro la tavolozza medesima.
Dopo questa funzione il colore rimosso di fatto non esiste più, ma i disegni fatti in precedenza con quel colore lo conservano.
La funzione restituisce, se ha successo, indice +1, altrimenti 0.
Per l'esempio d'uso si rimanda alla funzione m_remap_colors.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































































m_replace_color(indice_vecchio, indice_nuovo, r, g, b)

Questa funzione sostituisce un colore della tavolozza lasciando inalterato il numero totale di colori presenti. I due argomenti indice_vecchio e indice_nuovo sono di tipo int/INTEGER*4; se almeno uno di essi è negativo i restanti tre argomenti sono irrilevanti: in questo caso si ha semplicemente lo scambio di indice tra i colori posti nelle posizioni
abs(indice_vecchio)
e
abs(indice_nuovo)

Se i due citati argomenti sono entrambi non negativi il secondo (indice_nuovo) diventa irrilevante e assumono invece rilevanza gli ultimi tre argomenti, tutti di tipo double/REAL*8.
In questo caso la funzione si riduce a un semplice involucro per la coppia
m_remove_color,(indice_vecchio) m_insert_color(r, g, b, indice_vecchio)

Non esiste una variante di questa funzione per il modo HCV (cfr. m_new_color_hcv).

In ogni caso i valori degli argomenti r, g, b sono modificati all'uscita dalla funzione e contengono le componenti di colore che vengono a trovarsi nella posizione abs(indice_vecchio)

Per l'esempio d'uso si rimanda alla funzione m_remap_colors.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































































m_remap_colors(mappa)

Questa funzione consente di stravolgere o ripristinare l'ordine naturale dei colori nella tavolozza.
L'argomento mappa deve essere di tipo unsigned char/CHARACTER e quindi indirizza per "natura" dei valori interi compresi tra 0 e 255.
I valori contenuti ordinatamente in mappa sono per l'appunto utilizzati per indirizzare i colori della tavolozza di modo che, dopo questa chiamata, l'esecuzione di m_color(i) seleziona di fatto il colore di posizione mappa{i}.
I valori contenuti in mappa sono utilizzati fino a che se ne trova uno maggiore o uguale al numero totale di colori presenti nella tavolozza; da quel punto in poi viene ripetuto l'ultimo valore legittimo presente in mappa.
Ad esempio, facendo riferimento alla tavolozza originale di soli 8 colori, fornendo mappa coi seguenti valori

2 8 .....

si ottiene una tavolozza da cui è selezionabile solo il colore verde.
L'esecuzione di questa funzione cui si trasferisca come argomento il puntatore nullo (per chi programma, mal per lui, in FORTRAN l'indirizzo della costante 0) implica il ripristino dell'ordine naturale dei colori.
In nessun caso questa funzione implica perdita di colori presenti o aggiunta di colori nuovi.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
unsigned char mappa[  ]={4,9};
double xmin = -10.0, ymin = -10.0, xmax = 10.0, ymax = 10.0, x[2], t[2], r, g, b;
int K=600, L = 600, s[  ]={-1,-1};
m_startg(u, &K, &L), L = 95,
K = (95 << 24) + (255 << 8) + 255, K |= OMBREGGIA_FINESTRA,

m_window(&K, &L), m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = x[1] = 0.0, t[0] = 3.0, t[1] = 3.0, m_ellipse(x, t, &K),
m_mouse(x),
printf("colore %i ", m_get_color(&(K=0), x, s, &r, &g, &b)),
printf("di componenti %g %g %g\n", r, g, b),
r = 1.0, g = b = 0.6,
m_replace_color(&(K=0), &(L=90), &r, &g, &b),
m_color(&(K=0)),
x[0] = x[1] = 0.0, t[0] = 0.8, t[1] = 0.8, m_ellipse(x, t, &(K=1)),
m_mouse(x),
printf("colore %i ", m_get_color(&(K=0), x, s, &r, &g, &b)),
printf("di componenti %g %g %g\n", r, g, b),
r = g = 0.5, b = 0.0,
m_insert_color(&r, &g, &b, &(L=m_remove_color(&(K=8)))),
m_color(&(K=8)),
x[0] = x[1] = 0.0, t[0] = 3.4, t[1] = 3.4, m_ellipse(x, t, &(K=1)),
m_mouse(x),
printf("colore %i ", m_get_color(&(K=0), x, s, &r, &g, &b)),
printf("di componenti %g %g %g\n", r, g, b),
K = -1, L = 'A', m_flush(  ), m_loop_for_events(&L, &K),
m_remap_colors(mappa),
m_color(&(K=0)),
x[0] = x[1] = 0.0, t[0] = 4.4, t[1] = 4.4, m_ellipse(x, t, &(K=1)),
m_redraw(&(K=0)),
m_mouse(x),
printf("colore %i ", m_get_color(&(K=0), x, s, &r, &g, &b)),
printf("di componenti %g %g %g\n", r, g, b),
m_endg(  );}

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"










































































































m_symbol(n)

Dopo questa chiamata i punti disegnati da m_point sono marcati col simbolo numero n (INTEGER*4/int) scelto in un insieme di simboli predefiniti.

I valori di n accettabili vanno da 0 a 31 (inclusi). Se si fornisce un valore fuori intervallo viene trattato alla stessa stregua di quanto fa in simili occasioni msimbolo_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>(""), numero[3];
const char *nomi[  ]=
{"PUNTINO", "PUNTONE",
"TONDINO_VUOTO", "TONDINO_PIENO",
"QUADRETTO_VUOTO",
"QUADRETTO_PIENO",
"ROMBETTO_VUOTO", "ROMBETTO_PIENO",
"ASTERISCO",
"STELLINA_VUOTA",
"STELLINA_PIENA", "CROCETTA",
"CROCE_S_ANDREA", "QUADRO_E_CROCE",

"TRIANGOLO_VUOTO", "TRIANGOLO_PIENO",
"NABLA_VUOTO", "NABLA_PIENO",
"PENTAGONO_VUOTO",
"PENTAGONO_PIENO",
"PENTAGONO_DRITTO_VUOTO", "PENTAGONO_DRITTO_PIENO",

"ESAGONO_VUOTO", "ESAGONO_PIENO",
"ESAGONO_RUOTATO_VUOTO", "ESAGONO_RUOTATO_PIENO",

"OTTAGONO_VUOTO", "OTTAGONO_PIENO",
"STELLA_DI_DAVIDE_VUOTA", "STELLA_DI_DAVIDE_PIENA",

"NIDO_D_APE_VUOTO", "NIDO_D_APE_PIENO"};
double xmin = 0.0, ymin = 0.0, xmax = 5.0, ymax = 5.0, x[2];
int K=600, L = 800, i;
m_startg(u, &K, &L), K = L = 0, m_window(&K, &L), K = 1,
m_font_by_name(&(K=0), const_cast<char *>("-*-fixed-*-*-*-*-10-100-*-*-*-*-*-*")),
m_frame(&xmin, &ymin, &xmax, &ymax), x[0] = xmin, x[1] = 1.3*x[0],
m_move(x); for(i=1; i < 33; i++) K = i - 1, m_symbol(&K),
x[0] = xmin + (double)i*(xmax-xmin)/42.5, x[1] = 1.3*x[0], m_point(x), x[0] += 0.2,
x[1] -= 0.05, sprintf(numero, "%i\0", K), m_text(numero, x), x[0] += 0.15,
m_text(const_cast<char *>(nomi[K]), x);
K = 0, m_redraw(&K), K = -1, L = 0, m_loop_for_events(&L, &K), m_endg(  );}

N.B.:
Questo programma è simile a quello fornito come esempio di m_point ma i punti disegnati sono esattamente 32 e ciascuno è disegnato con uno dei 32 simboli predefiniti, nell'ordine dal basso a sinistra all'alto a destra. Ogni simbolo è accompagnato dal proprio numero ordinale e dalla propria costante rappresentativa predefinita.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































m_set_size_symbol(n)

Questa funzione imposta un valore iniziale di riferimento per la grandezza dei simboli utilizzati nella finestra corrente. Se non viene mai eseguita la grandezza iniziale dei simboli è quella descritta in m_symbol. L'argomento n, di tipo int/INTEGER*4, rappresenta il "raggio" del simbolo, in unità di pixels.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, K, L;
double y[  ]={0,0,1,1};
m_startg(const_cast<char *>(""), &(K=700), &(L=700)),
m_window(&(K=95), &(L=95)),
m_frame(y, y+1, y+2, y+3),
m_color(&(i=MAGENTA)),
m_set_size_symbol(&(i=340)),
m_symbol(&(i=ASTERISCO)),
y[0] = y[1] = 0.5,
m_point(y),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}


Questo programma disegna un gigantesco asterisco color magenta; si lascia all'estro dell'utente utilizzare proficuamente la presente funzione per disegnare in un colpo solo, ad esempio, un riferimento di assi cartesiani.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






















































































m_reset_size_symbol(  )

Questa funzione priva di argomenti ripristina la grandezza dei simboli per la finestra corrente al suo valore iniziale (l'ultimo eventualmente impostato da m_set_size_symbol), annullando l'effetto di qualsiasi precedente sequenza di esecuzioni della funzione m_size_symbol. Non si ritiene necessario fornire un esempio d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






















































































m_size_symbol(n)

Permette di modificare la grandezza del simbolo corrente definito da m_symbol.

n è un valore (REAL*8/double) positivo per cui viene moltiplicata la grandezza attuale dei simboli.

La grandezza di default è di 10 pixels, vale a dire che il simbolo cerchio ha un raggio di 5 pixels. Il limite inferiore per la grandezza è di 2 pixels.

Questa funzione può essere usata per disegnare forme geometriche semplici (cerchi, quadrati et similia) con un solo token memorizzato per il refresh. Le dimensioni di tali forme geometriche rispetto alla scala della figura sono a carico dell'utente.

INEFFICACE SUI SIMBOLI DI INDICI 0 e 1 e su quelli numerici.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 1.0, xmax = 5.0, ymax = 100000.0, x[2];
int K=700, L = 700, s[  ]={0,1}, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_log_scales(s),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, x[0]),
m_move(x),
x[0] = 3.0,
m_size_symbol(&x[0]);
for(i=5; i < 31; i++)
K = i - 5,
m_symbol(&K),
x[0] = xmin + (double)i*(xmax-xmin)/50.0, x[1] = pow(10.0, x[0]),
m_point(x);
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma è identico a quello fornito come esempio di m_symbol ma in questo caso i punti sono ingranditi di un fattore 3 rispetto alle dimensioni default (per i simboli "sensibili" all'ingrandimento).

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"












































































m_dash(n)

Dopo questa chiamata le linee disegnate da m_line sono tracciate nel tratteggio numero n (INTEGER*4/int) scelto in un insieme di tratteggi predefiniti.
I valori di n accettabili vanno da 0 a 15 (inclusi).

Se il valore contenuto in n è fuori intervallo e diverso da -1 significa che si vuole fornire la codifica di un proprio tratteggio personalizzato.

Il tratteggio personalizzato si ottiene facendo in modo che n "punti" un intero array di valori interi; il primo valore, come già detto, deve essere fuori dall'intervallo [-1, 15] e il suo valore assoluto rappresenta il numero di elementi che seguono (quindi "almeno" 2 elementi successivi al primo).
Ciascuno di questi deve essere strettamente positivo e minore di 128 (un controllo di positività interno fa interrompere la lettura del puntatore alla prima eventuale occorrenza di uno zero) e rappresenta la lunghezza (in pixels) dei tratti "on" e "off" del tratteggio (alternativamente).

Un solo tratteggio personalizzato è disponibile per ciascuna finestra e, una volta definito, può essere riutilizzato chiamando la funzione con n = 16.

Chiamandola invece con n = -1 si "svuota" il tratteggio personalizzato (qualora definito) che cessa di esistere e dovrà essere ricreato, ovviamente anche diverso da prima, richiamando la funzione come sopra esposto. In un caso simile tutte le linee tracciate col tratteggio personalizzato appariranno nel tratteggio definito per ultimo.
La chiusura di una finestra tramite m_close per la quale sia stato definito un tratteggio personalizzato NON implica la perdita del tratteggio stesso.

È superfluo (???) osservare che i punti tracciati devono distare tra loro più della lunghezza totale del tratteggio affinché questo risulti visibile, altrimenti tutti i tratteggi appariranno come linee continue. Ne segue che le linee tratteggiate sono raccomandate solo per curve abbastanza "lisce" da poter essere tracciate con un numero relativamente piccolo di punti.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 0.0, xmax = 5.0, ymax = 5.0, x[2];
int K=700, L = 700, i;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax);
for(i=0; i <= 8; i++)
x[0] = xmin, x[1] = ymin + ((double)i + 2.0)*(ymax - ymin) / 20.0,
m_move(x),
m_dash(&i),
x[0] = xmax,
m_line(x);
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma mostra nell'ordine dal basso in alto 9 diversi tipi di tratteggio previsti dalla libreria.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































m_thickness(n)

Dopo questa chiamata le linee tracciate con m_line hanno lo "spessore" n (INTEGER*4/int) espresso in pixels.
Il valore default è 1 e i valori accettati sono positivi. Non c'è alcun limite imposto a n eccetto il buon senso. Una chiamata di m_move ripristina implicitamente il valore default dello spessore.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = 0.0, ymin = 0.0, xmax = 5.0, ymax = 5.0, x[2];
int K=700, L = 700, i = 3;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax);
for(i=0; i <= 8; i++)
x[0] = xmin, x[1] = ymin + ((double)i + 2.0)*(ymax - ymin) / 20.0,
m_move(x),
L = i+1,
m_thickness(&L),
m_dash(&i),
x[0] = xmax,
m_line(x);
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma, identico a quello proposto come esempio per m_dash, mostra gli stessi tratteggi disegnati con spessore via via crescente.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































m_how_join_lines(n, modo)

Questa funzione è utile solo nel caso si traccino linee con spessore maggiore di quello standard (cfr. m_thickness). In tal caso la libreria utilizza uno stile default per realizzare la "giunzione" tra due segmenti di linea consecutivi, ossia la coppia CapButt, JoinBevel per gli argomenti cap_style e join_style del contesto grafico in esercizio (per conoscere il significato delle citate costanti consultare il manuale di X).
I due argomenti sono interi: n serve, come per numerose altre funzioni, a identificare la finestra per cui si vuole modificare lo stile di giunzione (0 <= n); modo indica lo stile richiesto: sono accettati i valori compresi tra 0 e 15 (inclusi). Il rapporto modo/4 (compreso tra 0 e 3) seleziona il valore di cap_style dal seguente insieme

CapButt CapRound CapProjecting CapNotLast

mentre il valore di modo % 3 (compreso tra 0 e 2) seleziona il valore di join_style dal seguente insieme

JoinBevel JoinRound JoinMiter

Per quanto già detto il default si ripristina eseguendo questa stessa funzione con modo = 0 e con n pari al valore richiesto per la finestra coinvolta.
Non si ritiene necessario fornire un esempio d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

































































































m_vector(x, t, l)

Disegna un vettore applicato nel punto di coordinate x (vettore REAL*8/double di lunghezza 2); il vettore ha versore t (vettore REAL*8/double di lunghezza 2) e modulo l[0] (REAL*8/double).

Nessun test viene compiuto sul fatto che t sia davvero un versore.

Il terzo argomento deve puntare tre valori REAL*8/double: il primo svolge il ruolo già detto; gli altri due, se non sono negativi, sono usati rispettivamente per indicare il numero di pixels per lunghezza e semilarghezza della freccia che costituisce la "punta" del vettore.
I valori default di questi due parametri sono rispettivamente 10 e 5. Gli utenti tengano dovuto conto di ciò specialmente in relazione alle dimensioni delle finestre, alle lunghezze dei vettori e all'"intelligibilità" del disegno.

NOTA BENE: La funzione omologa che produce codice PostScript (mfreccia_ps) usa una diversa interpretazione dei suoi argomenti.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = -10.0, ymin = -10.0, xmax = 10.0, ymax = 10.0, x[2], t[2], *l;
int K=700, L = 700, i;
l = (double *)malloc(3*sizeof(double)),
*l = 1.0, *(l+1) = *(l+2) = -1.0,
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax);
for(i=0; i < 10; i++)
x[0] = 4.0*cos(M_PI*0.2*(double)i),
x[1] = 4.0*sin(M_PI*0.2*(double)i),
t[0] = -x[1]/4.0, t[1] = x[0]/4.0,
m_vector(x, t, l);
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma disegna un campo vettoriale unitario tangente al cerchio di raggio 4.0.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
































































































m_ellipse(x, ax, modo)

Serve a disegnare su schermo un'ellisse di centro x (vettore di due double/REAL*8) e di semiassi ax (vettore di due double/REAL*8). Entrambi i vettori sono in coordinate utente e le due componenti di ax DEVONO essere positive.

L'argomento modo è un intero (int/INTEGER*4): se vale 0 si traccia solo il perimetro dell'ellisse, utilizzando il tipo di tratteggio e lo spessore correnti, altrimenti si traccia un'ellisse piena.

CON QUESTA FUNZIONE NON È POSSIBILE DISEGNARE ELLISSI CON SEMIASSI OBLIQUI. SE SI PRESENTASSE TALE NECESSITÀ OCCORREREBBE USARE LA FUNZIONE m_arc, pagando il prezzo di un'occupazione di memoria (nel caso di finestre non dedicate a pixmap) di circa duecento volte tanto.

È ACCETTATA, PER RAGIONI STORICHE, ANCHE LA FORMA m_ellypse

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = -10.0, ymin = -10.0, xmax = 10.0, ymax = 10.0, x[2], t[2];
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax);
x[0] = x[1] = 0.0,
t[0] = 6.0, t[1] = 3.0,
m_ellipse(x, t, &K),
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma disegna un'ellisse piena centrata nella finestra e con semiassi nel rapporto di 2:1.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"











































































































m_arc(x, ax, s, modo)

Questa funzione è complementare a m_ellipse e serve a disegnare un settore ellittico anziché un'ellisse intera.
Gli argomenti x, ax e modo hanno tipo e significato identici a quelli degli omonimi argomenti forniti a m_ellipse (cui si rinvia per la spiegazione); l'argomento aggiuntivo s, inserito in penultima posizione, è un array di almeno tre double/REAL*8. Il primo elemento dell'array indica l'angolo iniziale del settore ellittico, misurato a partire da un'origine posta nella direzione "orizzontale destra" rispetto al centro del settore; il secondo elemento dell'array indica l'ampiezza angolare del settore ellittico da tracciare (si presti attenzione al diverso significato attribuito a s da parte dell'omologa funzione PostScript marco_ps); l'ultimo elemento di s serve a dare un'inclinazione all'ellisse (in senso antiorario, e con valori ESCLUSIVAMENTE positivi: per intendersi l'angolo di inclinazione nullo va dato come 360, NON come 0). L' unità da utilizzare per tutti gli elementi di s è il grado sessagesimale (e le frazioni di grado sono decimali, nel senso che un valore 30.5 indica un angolo di trenta gradi e trenta primi di grado).

È del tutto intuitivo che ogni esecuzione di questa funzione con un valore del secondo elemento di s pari o maggiore di 360 equivale in toto all'esecuzione di m_ellipse con gli altri tre argomenti uguali.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = -10.0, ymin = -10.0, xmax = 10.0, ymax = 10.0, x[2], t[2], s[  ]={70, 90, 360};
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = x[1] = 0.0,
t[0] = 3.0, t[1] = 4.0,
m_arc(x, t, s, &(K=0)),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma disegna un settore ellittico vuoto di 90 gradi sessagesimali di ampiezza a partire dall'angolo di 70 gradi (nel primo quadrante) e appartenente a un'ellisse centrata nella finestra e con semiassi nel rapporto di 3:4.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































m_polygon(x, n)

Serve a tracciare una poligonale chiusa che sarà "riempita" col colore attualmente in uso (m_color).
Non è prevista una funzione apposita per tracciare una poligonale vuota perché questa equivarrebbe a un opportuno "loop" di chiamate alla funzione m_line.

L'argomento x è un array di double/REAL*8 contenente le coordinate (in unità utente) dei vertici della poligonale secondo lo schema x{2*k-1}, x{2*k} = coppia ordinata di coordinate del k-esimo vertice.

L'argomento n è un int/INTEGER*4 che rappresenta il numero di vertici (così che x deve contenere 2*n valori in tutto).

I valori limite di n sono: 3 e il minore tra quanto consente il server X11 locale e 32767. NESSUN CONTROLLO viene compiuto sulla congruenza dei parametri forniti.

Se viene usata in presenza di assi logaritmici SOLO i vertici della poligonale sono riportati sulla scala, NON l'interno dei lati; il che significa che i vertici della poligonale sono comunque uniti con segmenti di retta le cui coordinate NON SONO RIFERIBILI alla scala della figura.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin = -3.0, ymin = -3.0, xmax = 3.0, ymax = 3.0, x[6];
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax);
x[0] = x[1] = x[2] = 1.0,
x[3] = x[4] = x[5] = 2.0,
K = 3,
m_polygon(x, &K),
K = -1, L = 'A',
m_flush(  ),
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma disegna un triangolo rettangolo pieno con i vertici citati nel programma stesso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


























































































































m_which_frame(i)

Funzione omologa di m_which_window si comporta esattamente allo stesso modo relativamente al sistema di riferimento che sta correntemente ricevendo output se la finestra attiva è una finestra con sistemi di riferimento multipli (cfr. m_multiframe).
Se non fosse tale restituisce comunque il valore dell'indice per l'unico sistema di riferimento presente.
Non si ritiene necessario fornire un esempio d'uso, rimandando a quelli presenti nelle descrizioni di m_which_window e di m_multiframe.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"













































































































m_which_window(i)

Restituisce nel puntatore i (INTEGER*4/int) (0<=i) quale finestra sta correntemente ricevendo l'output. Lo stesso valore è anche posto come valore di ritorno della funzione. Tale valore (o una sua funzione) può essere utilizzato come argomento di ingresso per m_select.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin[2] = {-3.0, -1.0}, ymin[2] = {-3.0, -1.0},
xmax[2] = {3.0, 1.0}, ymax[2] = {3.0, 1.0}, x[2];
int K[2]={400, 80}, L[2] = {400, 80}, i;
m_startg(u, &K[0], &L[0]),
K[0] = L[0] = 95;
for(i=0; i < 2; i++)
m_window(&K[i], &L[i]),
m_frame(&xmin[i], &ymin[i], &xmax[i], &ymax[i]);
printf("sta ricevendo output la finestra %d\n", m_which_window(&i)),
m_flush(  ),
m_mouse(x),
printf("sta ricevendo output la finestra su cui hai cliccato\
(la numero %d)\npeccato che a questo punto il programma termini.\n", m_which_window(&i)),
m_endg(  );}

N.B.:
Questo programma apre due finestre con sistemi di riferimento diversi e segnala quale finestra sta correntemente ricevendo output.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"








































































































m_close(i)

Chiude la finestra numero i; i è un INTEGER*4/int (0<=i);
Se la finestra in questione ha connesso un file PostScript "ombra" (cfr. m_window), eseguire la funzione con argomento negativo comporta la chiusura della finestra di indice abs(i) -1, ma non quella del file PostScript ombra.
Se tale finestra non è stata aperta la richiesta è ignorata.
Tutto il contenuto grafico della finestra è perduto definitivamente.
Se la finestra chiusa da questa funzione era la finestra che riceveva correntemente l'output il programma si trova, immediatamanete dopo che sia stata eseguita m_close,
SENZA FINESTRA
destinataria di output: occorre tenerne conto per evitare comportamenti "inattesi" del programma. In un caso simile, prima di rieffettuare qualsiasi operazione grafica che produca output, è assolutamente consigliabile ripristinare una "finestra corrente", o eseguendo m_window o eseguendo m_select o m_mouse sulle eventuali finestre rimaste sullo schermo.
La libreria provvede, da parte sua, a far diventare "corrente" la finestra di indice più alto tra quelle superstiti (probabilmente quella aperta più di recente) per evitare che il programma addirittura si interrompa, ma questo potrebbe non essere quello che l'autore del codice desidera...

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin[2] = {-3.0, -1.0}, ymin[2] = {-3.0, -1.0},
xmax[2] = {3.0, 1.0}, ymax[2] = {3.0, 1.0}, x[2];
int K[2]={400, 80}, L[2] = {400, 80}, i;
m_startg(u, &K[0], &L[0]),
K[0] = L[0] = 95;
for(i=0; i < 2; i++)
m_window(&K[i], &L[i]),
m_frame(&xmin[i], &ymin[i], &xmax[i], &ymax[i]);
x[0] = xmin[m_which_window(&i)], x[1] = ymin[i];
m_move(x),
x[0] = xmax[i], x[1] = ymax[i],
m_line(x),
K[0] = EVENTO_ENTER,
m_wait_for_events(K),
m_close(&i),
m_wait_for_events(K),
m_endg(  );}

N.B.:
Questo programma apre due finestre con sistemi di riferimento diversi, traccia la diagonale della seconda finestra e, alla pressione di <Return> chiude la prima finestra creata; alla successiva pressione di <Return> sulla finestra superstite (quella con la diagonale) il programma esce.
Si noti anche l'uso della funzione m_which_window.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"













































































m_select(i)

Indirizza l'output grafico alla finestra numero i; i è un INTEGER*4/int (0<=i); se la finestra non è stata aperta la richiesta è ignorata: in tal caso l'output grafico CONTINUA A ESSERE INDIRIZZATO sulla finestra precedentemente in uso.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double xmin[2] = {-3.0, -1.0}, ymin[2] = {-3.0, -1.0},
xmax[2] = {3.0, 1.0}, ymax[2] = {3.0, 1.0}, x[2];
int K[2]={400, 80}, L[2] = {400, 80}, i;
m_startg(u, &K[0], &L[0]),
K[0] = L[0] = 95;
for(i=0; i < 2; i++)
m_window(&K[i], &L[i]),
m_frame(&xmin[i], &ymin[i], &xmax[i], &ymax[i]);
i = 1,
x[0] = xmin[i], x[1] = ymin[i];
m_move(x),
x[0] = xmax[i], x[1] = ymax[i],
m_line(x),
i = 0,
x[0] = xmin[i], x[1] = ymin[i],
m_select(&i),
m_move(x),
x[0] = xmax[i], x[1] = ymax[i],
m_line(x),
m_flush(  );
for(i=0; i < 2; i++) m_redraw(&i);
K[0] = EVENTO_ENTER,
m_wait_for_events(&K[0]),
m_endg(  );}

N.B.:
Questo programma apre due finestre con sistemi di riferimento diversi, traccia le diagonali di entrambe le finestre e, alla pressione di <Return> esce. Si noti l'azione di m_select per indirizzare la finestra aperta per prima. Si sarebbe anche potuto, ovviamente, utilizzare un "loop" discendente da 1 a 0.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































m_text_ext(s, data)

Misura quanto spazio occuperà la stringa s (CHARACTER*(*)/char *) quando fosse scritta sulla finestra corrente usando il fonte di caratteri attualmente in uso in quella finestra (cfr m_font). NULLA è effettivamente scritto. L'occupazione viene restituita (in pixels, NON in coordinate utente) nel secondo argomento data, che deve "puntare" 4 (quattro) valori di tipo int/INTEGER*4. Come è consuetudine in casi simili i primi due valori reperibili in data sono ordinatamente lo scostamento orizzontale e verticale del vertice superiore sinistro del rettangolo minimale che contiene la stringa dalla posizione in cui venisse collocato il carattere iniziale della medesima; gli altri due elementi di data sono ordinatamente larghezza e altezza dello stesso rettangolo. Nell'esempio d'uso fornito per m_font si esemplifica anche l'uso della presente funzione.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































m_quote(finestra, quote, formato, cifre, fonte)

La chiamata di questa funzione consente di modificare il comportamento standard della libreria per quanto attiene alla scrittura delle quotature del disegno. Se questa funzione non viene mai chiamata la libreria funziona quindi ugualmente, ma l'esecuzione di questa funzione, specialmente in connessione con l'esecuzione di m_multiframe col primo argomento negativo, consente una gestione estremamente raffinata della quotatura.

Gli argomenti hanno il significato seguente:

LA LIBRERIA NON EFFETTUA ALCUN TEST SUI VALORI TRASFERITI PER GLI ARGOMENTI DI QUESTA FUNZIONE: SE NON SI OTTEMPERA A QUANTO QUI DESCRITTO I RISULTATI SONO IMPREVEDIBILI E SOTTO LA TOTALE RESPONSABILITÀ DEL PROGRAMMATORE.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
char quote[  ]={3,3,0,0}, cifre[  ]={3,3,1,1}, formato[  ]={'e', 'e', 'f', 'f'};
double x[22], rgb[  ][3]={1.0, 0.8, 0.8, 0.8, 0.5, 0.0},
frame[  ]=
{0.8, 0.8, 110, 110, 1, 1,
-2.0, -2.0, 2.0, 2.0, 0, 0,
-3.0, -3.0, 3.0, 3.0, 0, 0,
-4.0, -4.0, 4.0, 4.0, 0, 0,
-5.0, -5.0, 5.0, 5.0, 0, 0,
-6.0, -6.0, 6.0, 6.0, 0, 0,
-7.0, -7.0, 7.0, 7.0, 0, 0,
-8.0, -8.0, 8.0, 8.0, 0, 0,
-9.0, -9.0, 9.0, 9.0, 0, 0};
int K=800, L = 800, M, II[  ]={0, -1}, IO[  ]={1, 1, 0, 0, 600, 700, 0, 1, 630, 0, 80, 700};
m_startg(u, &K, &L),
K = L = 95,
K |= OMBREGGIA_FINESTRA,
m_window(&K, &L),
m_use_as_pixmap(&(K=1), &(L=7)),
m_multiframe(&(K=-2), &(L=3), IO, frame);
m_quote(&(K=0), 0, 0, 0, &(L=18));
for(M=0; M < 2; M++)
{II[0] = m_which_frame(&L),
m_select_frame(&(L=0), II);
if(M < 7) m_color(&(L=M+3));
else m_color(&(L = m_new_color(&rgb[M-7][0], &rgb[M-7][1], &rgb[M-7][2])));
if(M) for(K=0; K < 3+M; K++)
x[2*K] = 0.5*frame[6*M+2]*cos(2.0*M_PI*K/(3.+M)),
x[2*K+1] = 0.5*frame[6*M+2]*sin(2.0*M_PI*K/(3.+M));
else x[0] = x[1] = 1.0, x[2] = x[3] = 100., x[4] = 10.0, x[5] = 1.0;
m_polygon(x, &(K=3+M));
II[0] ++,
m_select_frame(&(L=0), II);}
while(1)
{if(m_mouse(x) == 2) break;
cout << x[0] << ' ' << x[1] << '\n';}
m_flush(  ),
K = -1, L = 'a',
m_loop_for_events(&L, &K),
m_endg(  );}


Questo programma è identico a quello fornito come esempio d'uso della funzione m_multiframe, con la sola aggiunta dell'invocazione di questa funzione con tre puntatori nulli forniti per quote, formato e cifre e con la sola richiesta di usare un font di 18 pxlsize. Gli utenti possono sbizzarrirsi a sostituire uno o più dei puntatori nulli con gli array omonimi già inizializzati all'interno del codice (eventualmente anche modificando i valori) per scoprire le differenze di comportamento che ne conseguono.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






























































































m_text(s, x)

Scrive la stringa s (CHARACTER*(*)/char *) a partire dalla posizione x (vettore REAL*8/double lungo 2) data in coordinate utente.

Le stringhe possono essere scritte SOLO orizzontalmente da sinistra a destra (cfr. invece l'omologa funzione PostScript mscrivi_ps).

La lunghezza di s non può superare 42 caratteri. NESSUN test viene compiuto sulla lunghezza di s.

Chi programma in FORTRAN deve tener conto di quanto detto a proposito delle variabili stringa (cfr. Generalità, m_conv_string e m_conv_chars).

Questa funzione può essere usata dai volenterosi e/o dagli eterni scontenti come base per realizzare una propria routine di quotatura degli assi qualora non sia appagante quella fornita dalla libreria.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>(""),
*v=const_cast<char *>("tanto va la gatta al lardo che ci lascia l");

double xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0, x[2];
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = 0.1, x[1] = 0.5,
m_text(v, x),
m_flush(  ),
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma scrive la stringa indicata partendo dalla posizione (0.1, 0.5) ed esce alla pressione del tasto 'z'.
Si noti il troncamento del celebre proverbio per evitare di eccedere la lunghezza accettabile per la stringa: se si fosse troncato a "lo" il programma avrebbe potuto causare "Segmentation fault".

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
































































































m_map_font(mappa)

Questa funzione, di rarissima utilità, serve a modificare l'ordine di preferenza di undici fonti standard che la libreria utilizza esclusivamente per scrivere le quotature sulla finestra grafica.
mappa è, per l'appunto, un vettore di int/INTEGER*4 contenente un'arbitraria permutazione dei numeri da 0 a 10 inclusi che servono a indicizzare i fonts che hanno pxlsz da 10 a 24 e che sono presenti sulla maggioranza dei server X11.
Questa funzione potrebbe tornare utile a chi lavorasse con un server X11 cui manchi la maggior parte di questi fonts e quindi potrebbe trovar giovamento nel privilegiare e mettere in alta priorità quelli di cui dispone.
La mappatura iniziale è
4, 5, 6, 7, 3, 2, 1, 0, 8, 9, 10

e gli undici font standard sono, nell'ordine,

-*-*-*-*-*-*-10-*
-*-*-*-*-*-*-11-*
-*-*-*-*-*-*-12-*
-*-*-*-*-*-*-13-*
-*-*-*-*-*-*-14-*
-*-*-*-*-*-*-15-*
-sony-*-*-*-*-*-16-*
-adobe-*-*-r-*-*-17-*
-*-*-*-*-*-*-18-*
-*-*-*-*-*-*-20-*
-sony-*-*-*-*-*-24-*

Non si ritiene indispensabile fornire un esempio dell'ovvio utilizzo.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
































































































m_reset_font(n)

Questa funzione serve a riportare il fonte corrente dei caratteri di scrittura per la finestra numero n (argomento di tipo INTEGER*4/int; cfr. m_window) al suo valore iniziale.
Se per tale finestra il fonte non è stato mai cambiato l'esecuzione di questa funzione è irrilevante e si limita a inviare un messaggio informativo su stderr (purché connesso, cfr. m_toggle_message).

Esempio d'uso: cfr m_font.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"































































































































m_recover_font(n, indice)

Questa funzione consente di "riutilizzare" nella finestra di indice n (int/INTEGER*4), n >= 0, un fonte di caratteri che sia già stato usato in precedenza sulla stessa finestra, senza bisogno di eseguire nuovamente m_font o m_font_by_name. indice (int/INTEGER*4), numero_totale > indice >= 0, infatti rappresenta il numero ordinale del fonte che si vuole riutilizzare e numero_totale indica il numero di fonti già caricati nella finestra numero n. (coincide in sostanza con la somma delle esecuzioni di m_font e m_font_by_name già effettuate per la finestra in questione).

Ogni valore illecito di uno qualsiasi dei due argomenti comporta semplicemente che la funzione non abbia alcun effetto (con invio su stderr, purché connesso, di un adeguato messaggio).

Esempio d'uso:

#include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{double xmin = 0.0, ymin = 0.0, xmax = 900, ymax = 800, coord[2];
int K=900, L = 800, nn = 1, M, loaded_fonts = 0, i;
const char *ctext[  ] = {"18", "8"},
*cfc[  ] = {
"adobe",
"courier",
"bold",
"r",
"*", "1"};
char * fc[  ] = {
const_cast<char *>(cfc[0]),
const_cast<char *>(cfc[1]),
const_cast<char *>(cfc[2]),
const_cast<char *>(cfc[3]),
const_cast<char *>(cfc[4]),
const_cast<char *>(cfc[5])
}, *text[  ] =
{const_cast<char *>(ctext[0]),
const_cast<char *>(ctext[1])};
m_startg(const_cast<char *>(""), &K, &L);
K = L = 100;
K |= OMBREGGIA_FINESTRA,
m_window(&K, &L),
m_toggle_mouse_save_right(&(M=0)),
m_frame(&xmin, &ymin, &xmax, &ymax);
loaded_fonts += m_font(&(K=0), &(L=2), &(M=14),fc[0], fc[1], fc[2], fc[3],
fc[4], fc[4], text[0], fc[4], fc[4], fc[4], fc[4], fc[4], fc[4], fc[5]),
loaded_fonts += m_font(&(K=0), &(L=2), &(M=14),fc[0], fc[1], fc[2], fc[3],
fc[4], fc[4], text[1], fc[4], fc[4], fc[4], fc[4], fc[4], fc[4], fc[5]),
while(nn == 1 && loaded_fonts == 2)
{m_clear(&(L=0)), m_flush(  ),
m_recover_font(&(L=0), &(K=0));
for(i=0 ; i < 500; i++)
coord[0] = (20*i)%900, coord[1] = (20*i)%800, m_text(text[0], coord);
m_flush(  ),
m_wait_for_microseconds(&(L=5000000)),
m_redraw(&(L=0)),
nn = m_mouse(coord);
if(nn > 1) break;
m_clear(&(L=0)), m_flush(  ),
m_recover_font(&(L=0), &(K=1));
for(i=0 ; i < 500; i++)
coord[0] = (20*i)%900, coord[1] = (20*i)%800, m_text(text[1],coord);
m_wait_for_microseconds(&(L=5000000)),
m_redraw(&(L=0)),
nn = m_mouse(coord);}}

N.B.:
Questo programma, scritto dallo studente Manuel Wieider durante l'A.A. 2005-2006, alterna, ad ogni click del mouse col pulsante sinistro, la scrittura di numerose "repliche" del valore del "corpo" di due fonti caricati all'inizio con due esecuzioni di m_font.
Si noti che se anche una sola di queste fallisse il programma non farebbe assolutamente nulla.
Per uscire dal programma occorre cliccare con uno degli altri due bottoni.
Si osservi che se al posto di m_recover_font si fosse usata m_font all'interno del ciclo, l'effetto grafico sarebbe stato lo stesso, ma si sarebbe ben presto "saturata" la capienza dei fonti utilizzabili nella finestra. In questo modo invece, se il programma non terminasse all'uscita dal ciclo, ci sarebbe disponibilità per ulteriori 33 fonti, come è giusto che sia.
Si osservino anche le esecuzioni di m_wait_for_microseconds (opzionale, serve solo a non "stressare" l'utente con richieste di click troppo pressanti) e di m_toggle_mouse_save_right (essenziale per evitare che cliccando il bottone destro si inneschi il processo di salvataggio della figura, del tutto inutile nel presente contesto, [cfr. m_mouse]): si noti infatti che il programma genera anche un file PostScript ombra che riproduce fedelmente quanto disegnato su schermo.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"































































































m_font_by_name(n, nomefonte)

Funzione analoga a m_font da cui si distingue per quanto segue:

  1. Il secondo argomento è una stringa e rappresenta la maschera con cui un certo fonte è conosciuto dal server.

  2. Usando questa funzione è possibile introdurre uno e un solo fonte in più rispetto al limite di 13 imposto da m_font.



Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{char *u=const_cast<char *>(""),
*v=const_cast<char *>("tanto va la gatta al lardo");
const char *vv[  ]={
"charter",
"clean",
"courier",
"fixed",
"helvetica",
"lucida",
"lucidabright",
"lucidatypewriter",
"new century schoolbook",
"symbol",
"terminal",
"times",
"utopia",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente"
}, *aster="*", *ww = "i", *pxls = "33";
char
* Aster = const_cast<char *>(aster),
*WW = const_cast<char *>(ww),
*PXLS = const_cast<char *>(pxls);
double xmin = 0.0, ymin = 0.0, xmax = 600.0, ymax = 600.0, x[2];
int K=600, L = 600, i, IN[  ]={0, 0, 0, 0};
m_startg(u, &K, &L),
K = L = 0,
m_window(&K, &L);
if(narg > 1) m_use_as_pixmap(&(K=1), &(L=7));
m_frame(&xmin, &ymin, &xmax, &ymax);
for(L=0; L < 18; L++)
{x[0] = 60.0, x[1] = (0.95-L*0.07)*600.0;
if(m_font(&(K=0), &L, &(i=0)))
m_text_ext(const_cast<char *>(vv[L]), IN),
m_color(&(K=L%7)),
m_text(const_cast<char *>(vv[L]), x),
x[0] += IN[0], x[1] += IN[1], m_move(x),
x[0] += IN[2], m_line(x), x[1] -= IN[3], m_line(x),
x[0] -= IN[2], m_line(x), x[1] += IN[3], m_line(x);
m_flush(  );}
for(L=18; L < 36; L++)
{x[0] = 0.6, x[1] = 0.95-(L-18)*0.15;
if(L < 35) i = m_font(&(K=0), &L, &(i=0));
else
i = m_font(&(K=0), &L, &(i=7),
Aster, const_cast<char *>("utopia"), Aster, WW, Aster, Aster, PXLS, Aster,
Aster, Aster, Aster, Aster, Aster, Aster);
if(i)
m_text_ext(const_cast<char *>(vv[L]), IN),
m_color(&(K=L%7)),
m_text(const_cast<char *>(vv[L]), x),
x[0] += IN[0], x[1] += IN[1], m_move(x),
x[0] += IN[2], m_line(x), x[1] -= IN[3], m_line(x),
x[0] -= IN[2], m_line(x), x[1] += IN[3], m_line(x);
m_flush(  );}
x[1] = (0.95-(L-18)*0.05)*600.0 - 12.0;
m_font_by_name(&(K=0), const_cast<char *>("-*-courier-bold-r-*-*-18-*-*-*-*-*-*-*")),
m_text_ext(const_cast<char *>(v), IN),
x[0] = 300.0 - IN[2] * 0.5,
m_text(const_cast<char *>(v), x),
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}


N.B.:
Questo programma è identico a quello presentato come esempio d'uso di m_font salva la sostituzione della chiamata di m_reset_font con m_font_by_name.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





































































































m_font(n, index, numargs, ...)

Funzione con numero di argomenti variabile che serve a scegliere con quale fonte di caratteri saranno scritte le stringhe sulla finestra numero n (INTEGER*4/int; cfr. m_window). L'argomento index (INTEGER*4/int) deve essere compreso tra 0 e 12 (inclusi) perché altrettante sono le famiglie di fonti selezionabili attraverso appunto il valore di index. L'elenco (ordinato) delle famiglie è il seguente:


All'interno di ogni famiglia selezionata tramite index si usa di fatto il fonte che, sul server X11 in esercizio, ha il maggiore pxlsize (vedi appresso).
L'argomento numargs (INTEGER*4/int) deve valere 0 (zero) se non è seguito da alcun altro argomento, altrimenti deve essere seguito da tanti argomenti di tipo stringa (CHARACTER*(*)/char *) quanto è il suo valore. In tal caso il valore dell'argomento index diviene irrilevante e funge solo da segnaposto. Ognuno degli argomenti opzionali può essere specificato allo stesso modo in cui appare nel programma di sistema xfontsel e nello stesso ordine.
Ogni argomento che si vuol lasciare al valore di default deve essere specificato come "segnaposto" e col valore "*" (che funge da "wildchar"). La disponibilità di valori dettagliati per le specifiche del fonte richiesto dipende dal server X11 su cui si lavora; ad ogni modo se si richiede un fonte inesistente la funzione non fa niente e restituisce un valore di ritorno nullo.
Non è possibile richiedere l'uso di più di 13 fonti diversi sulla stessa finestra, considerando diversi anche due fonti della stessa famiglia che differiscano anche solo per la grandezza. Ogni richiesta eccedente il limite appena citato viene semplicemente ignorata lasciando quindi in vigore il fonte correntemente in uso.
Le quotature attorno alla figura sono sempre realizzate usando il fonte introdotto per ultimo per cui occorre tener presente di non utilizzare per ultimi dei fonti la cui metrica sia imprecisa e/o incompleta (a tal proposito la miglior guida è farsi un minimo di ossa col programma xfontsel); per evitare spiacevolezze si consiglia in ogni caso di usare, alla fine di tutte le operazioni, la funzione m_reset_font. (a meno che, sapendo quel che si fa, non si voglia proprio ottenere delle quotature personalizzate).
Se la finestra coinvolta dalla chiamata di questa funzione ha un file PostScript ombra (cfr. m_window) la corrispondente chiamata implicita viene fatta a mcercafonte_per_nome_ps cercando il più possibile di mantenere la congruenza col fonte scelto.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{char
*u=const_cast<char *>(""),
*v=const_cast<char *>("tanto va la gatta al lardo");
const char *vv[  ]={
"charter",
"clean",
"courier",
"fixed",
"helvetica",
"lucida",
"lucidabright",
"lucidatypewriter",
"new century schoolbook",
"symbol",
"terminal",
"times",
"utopia",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente",
"fonte inesistente"
}, *aster = "*", *ww = "i", *pxls = "33";
char
*Aster = const_cast<char *>(aster),
*WW = const_cast<char *>(ww),
*PXLS = const_cast<char *>(pxls);
double xmin = 0.0, ymin = 0.0, xmax = 600.0, ymax = 600.0, x[2];
int K=600, L = 600, i, IN[  ]={0, 0, 0, 0};
m_startg(u, &K, &L),
K = L = 0,
m_window(&K, &L);
if(narg > 1) m_use_as_pixmap(&(K=1), &(L=7));
m_frame(&xmin, &ymin, &xmax, &ymax);
for(L=0; L < 18; L++)
{x[0] = 60.0, x[1] = (0.95-L*0.07)*600.0;
if(m_font(&(K=0), &L, &(i=0)))
m_text_ext(const_cast<char *>(vv[L]), IN),
m_color(&(K=L%7)),
m_text(const_cast<char *>(vv[L]), x),
x[0] += IN[0], x[1] += IN[1], m_move(x),
x[0] += IN[2], m_line(x), x[1] -= IN[3], m_line(x),
x[0] -= IN[2], m_line(x), x[1] += IN[3], m_line(x);
m_flush(  );}
for(L=18; L < 36; L++)
{x[0] = 0.6, x[1] = 0.95-(L-18)*0.15;
if(L < 35) i = m_font(&(K=0), &L, &(i=0));
else
i = m_font(&(K=0), &L, &(i=7),
Aster, const_cast<char *>("utopia"), Aster, WW, Aster, Aster, PXLS, Aster,
Aster, Aster, Aster, Aster, Aster, Aster);
if(i)
m_text_ext(const_cast<char *>(vv[L]), IN),
m_color(&(K=L%7)),
m_text(const_cast<char *>(vv[L]), x),
x[0] += IN[0], x[1] += IN[1], m_move(x),
x[0] += IN[2], m_line(x), x[1] -= IN[3], m_line(x),
x[0] -= IN[2], m_line(x), x[1] += IN[3], m_line(x);
m_flush(  );}
x[1] = (0.95-(L-18)*0.05)*600.0 - 12.0;
if(narg > 2) m_reset_font(&(K=0));
m_text_ext(const_cast<char *>(v), IN),
x[0] = 300.0 - IN[2] * 0.5,
m_text(const_cast<char *>(v), x),
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}


N.B.:
Questo programma mostra una stringa scritta in un esemplare di fonte tratto da ciascuna famiglia accessibile e in diversi colori. Il valore della stringa è il nome stesso della famiglia di fonti.
Si noti che per le prime due esecuzioni non è stato fornito alcun argomento aggiuntivo alla funzione, mentre nell'ultima si dà un esempio di citazione di tutti i possibili argomenti (di cui sono effettivamente utilizzati solo i primi 7) e si noti che quest'ultimo fonte introdotto sarebbe anche quello con cui sono scritte le quotature (se non si esegue m_reset_font.) Ogni stringa rappresentativa del nome di un fonte è "racchiusa" nel rettangolo determinato tramite le esecuzioni della funzione m_text_ext. Si osservi anche che il programma effettua un buon numero di chiamate "a vuoto" della funzione per mostrare come ciò non pregiudichi l'esecuzione.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































m_use_as_pixmap(i, color)

Serve a destinare la finestra numero i (INTEGER*4/int) a essere utilizzata come una pixmap. i, diversamente da quanto avviene per altre funzioni (m_which_window, m_clear, m_select, m_close) deve essere compreso tra 1 e 32 (inclusi), salvo quanto detto qui appresso.

L'argomento color (INTEGER*4/int), compreso tra 0 e N (inclusi), ove N+1 è il numero attuale di colori contenuti nella tavolozza, inizializza tutti i pixels della pixmap al colore numero color (cfr. m_color e m_new_color).

Questa funzione non può essere chiamata prima dell'apertura della finestra cui la pixmap si riferisce (cfr. m_window).

Quando viene chiamata, ogni disegno che sia stato eventualmente già tracciato nella finestra va definitivamente perso; se, per giunta, la chiamata avviene dopo quella di m_frame, e la funzione m_window non ha riservato al disegno il 100% dell'area disponibile sulla finestra, la pixmap risulta "amputata" del suo contorno. Ne consegue che il punto d'elezione in cui eseguire questa funzione si trova IMMEDIATAMENTE DOPO la richiesta di esecuzione di m_window, come appare del tutto plausibile che debba essere.

Tutte le funzioni della libreria possono essere indifferentemente utilizzate anche su una finestra dedicata a una pixmap.

Se il primo argomento ha un valore negativo, fermo restando il significato del valore assoluto descritto sopra, la pixmap associata alla finestra non viene visualizzata ma resta "nella mente del server" ove avvengono e sono mantenute tutte le operazioni di disegnatura. Lo stato corrente della pixmap, nel caso in discussione, appare solo quando si esegua la funzione m_show_pixmap, dopo di che la finestra torna a essere "orfana" di qualsiasi operazione di aggiornamento, comprese quelle che un utente avesse previsto in una propria eventuale funzione di ridisegnatura. Il comportamento appena descritto può risultare molto utile nel caso di disegni molto complessi e che richiedano molto tempo di elaborazione: neppure si immagina quanto tempo si riesce a risparmiare eseguendo i disegni, come si usa dire, "off-line"; inoltre questo può risultare di gran lunga la scelta migliore quando si volessero realizzare animazioni composte da un gran numero di fotogrammi: la cattura dei fotogrammi avviene direttamente dal server e nel frattempo si può tranquillamente continuare a lavorare ad altro sul proprio Desktop senza doversi preoccupare di lasciare "scoperta" la finestra da cui i fotogrammi debbono essere catturati.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
int K=700, L = 700;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
K = 1, L = 3,
m_use_as_pixmap(&K, &L),
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma apre una finestra dedicata a pixmap ed esce alla pressione del tasto 'A'.
Si notino i valori della variabile K e il colore attribuito allo sfondo della pixmap.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































m_fill_int_pixmap(i, x, color)
m_fill_pixmap(i, x, color)

Queste due funzioni hanno nomi diversi solo per mantenere la compatibilità con il FORTRAN '77: in realtà si tratterebbe di due overload della stessa funzione, differendo solamente il tipo dell'argomento centrale.
Gli argomenti i e color hanno lo stesso significato degli omonimi argomenti di m_use_as_pixmap.

L'argomento x è un vettore di due elementi (REAL*8/double) che contiene le coordinate utente del punto il cui pixel va acceso col colore numero color, nel caso la funzione sia invocata col nome m_fill_pixmap, mentre è un vettore di due elementi (INTEGER*4/int) contenente le coordinate intere, secondo le regole del server grafico, se l'invocazione viene fatta col nome m_fill_int_pixmap.

Tali coordinate sono quelle che l'utente ha stabilito tramite la normale chiamata alla funzione m_frame (che pertanto deve sempre precedere qualsiasi chiamata di m_fill_pixmap) ovvero sono la posizione del pixel interessato rispetto all'origine del sistema di riferimento corrente, posta come sempre nell'angolo superiore sinistro (m_fill_int_pixmap). Nel secondo caso, qualora non sia stata eseguita m_multi_frame, non è neppure necessario che esista un sistema di riferimento definito dall'utente per la pixmap corrente; si tenga però presente che la mancanza di un sistema di riferimento influenza negativamente un eventuale file PostScript ombreggiante (cfr. funzioni raster).

Quantunque la libreria abbia capienza per pixmaps di oltre 3 Mbytes e quindi capaci di un numero di colori addirittura superiore a quello disponibile via hardware, è internamente limitata a gestire inizialmente i soli 8 colori della tavolozza fondamentale e,in aggiunta, quelli eventualmente creati tramite chiamate di m_new_color.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double x[2], xmin = 0.0, ymin = 0.0, xmax = 1000.0, ymax = 1000.0;
int K=700, L = 700, i, c = 7;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
K = 1, L = 3,
m_use_as_pixmap(&K, &L);
for(i=0; i < 500; i++) for(L=0; L < 100; L++)
x[0] = (double)i, x[1] = (double)L,
m_fill_pixmap(&K, x, &c);
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma apre una finestra dedicata a una pixmap di sfondo blu, riempie col colore bianco la metà del quinto inferiore della pixmap ed esce alla pressione del tasto 'A'.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"























































































m_clear_pixmap(i, color)

Ha gli stessi argomenti di m_use_as_pixmap e lo stesso effetto di porre il colore numero color in tutti i pixels della pixmap; l'unica differenza è che non effettua l'associazione finestra <-> pixmap in quanto presume che sia già stata effettuata da una chiamata di m_use_as_pixmap.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double x[2], xmin = 0.0, ymin = 0.0, xmax = 1000.0, ymax = 1000.0;
int K=700, L = 700, i, c = 7;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
K = 1, L = 3,
m_use_as_pixmap(&K, &L);
for(i=0; i < 500; i++) for(L=0; L < 100; L++)
x[0] = (double)i, x[1] = (double)L,
m_fill_pixmap(&K, x, &c);
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
K = L = 1,
m_clear_pixmap(&K, &L),
m_flush(  ),
K = 0,
m_redraw(&K),
m_mouse(x),
m_endg(  );}

N.B.:
Questo programma apre una finestra dedicata a una pixmap di sfondo blu, riempie col colore bianco la metà del quinto inferiore della pixmap e, alla pressione del tasto 'A', cancella l'intera pixmap portandola al colore rosso; dopo di che esce al click del mouse.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































m_change_pixmap_background(i, col)

Funziona come m_clear_pixmap, ma conserva il disegno limitandosi a cambiare (come dice il nome) solo il colore dei pixels di sfondo. Va notato che tutti i pixels che hanno il colore di sfondo sono modificati, anche quelli che avessero quel colore pur appartenendo a disegni successivi.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double x[2], xmin = 0.0, ymin = 0.0, xmax = 1000.0, ymax = 1000.0;
int K=700, L = 700, i, c = 7;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
K = 1, L = 3,
m_use_as_pixmap(&K, &L);
for(i=0; i < 500; i++) for(L=0; L < 100; L++)
x[0] = (double)i, x[1] = (double)L,
m_fill_pixmap(&K, x, &c);
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
K = L = 1,
m_change_pixmap_background(&K, &L),
m_flush(  ),
K = 0,
m_redraw(&K),
m_mouse(x),
m_endg(  );}

N.B.:
Questo programma è identico a quello fornito come esempio d'uso di m_clear_pixmap, ma, alla pressione del tasto 'A', cambia solo lo sfondo della pixmap portandolo al colore rosso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































m_save_pixmap(i, file)

Serve a salvare su disco il contenuto attuale della pixmap. L'argomento i ha lo stesso significato e lo stesso tipo dell'omonimo argomento di m_fill_pixmap, m_clear_pixmap e m_use_as_pixmap.
L'argomento file è una stringa di caratteri (cfr. quanto detto circa le stringhe per chi programma in FORTRAN) che contiene il nome del file su cui si vuole salvare la pixmap.

Tale stringa DEVE OBBLIGATORIAMENTE contenere almeno un carattere "." (punto).
Sulle Silicon Graphics e sui PC Linux la libreria produce un file di tipo GIF il cui nome sarà il prefisso di file completato col suffisso

.gif

Tale file viene ottenuto utilizzando programmi esterni normalmente residenti sulle piattaforme citate (purché l'ambiente Linux sia stato ben configurato).
Su ogni altra piattaforma la libreria produce un file di nome file e di formato "portable pixmap format" (ppm) (per completezza di informazione si aggiunge che, qualora l'iniziale di file sia il segno di sottolineatura, il documento prodotto sarà in formato pgm, ossia un ppm monocromatico) che risulta MOLTO più grande di un file GIF, a meno che non venga fornito un programma esterno di conversione a GIF attraverso una variabile d'ambiente di nome

PASSE_PAR_TOUT_TOGIF

il cui valore deve essere una stringa del tipo

"nome_del_programma %s %s"

con due "segnaposto" %s che la funzione utilizza per ricopiarvi input e output files.
Va da sé che la sintassi del programma fornito deve rispettare la stringa.
La variabile d'ambiente può ovviamente essere introdotta anche sulle piattaforme Silicon Graphics e Linux se si preferisce "sostituire" i programmi di conversione standard con dei propri metodi.
In particolare si può perfino "inibire" la conversione ppm->GIF specificando esplicitamente la variabile d'ambiente, ma fornendole come valore la stringa nulla.

Se l'argomento i viene sottratto dalla costante -MASSIMO_NUMERO_FINESTRE (1--> -MASSIMO_NUMERO_FINESTRE-1, 2--> -MASSIMO_NUMERO_FINESTRE-2, etc.) la funzione, chiamata con un tale valore di i, produce uno "snapshot" della finestra su un file PostScript impaginabile di nome file e questo anche quando la finestra non è stata dedicata a una pixmap.
In tal caso l'associazione di i sarà (0--> 0, 1--> -1,etc.).

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
double x[2], xmin = 0.0, ymin = 0.0, xmax = 1000.0, ymax = 1000.0;
int K=700, L = 700, i, c = 7;
m_startg(u, &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
K = 1, L = 3,
m_use_as_pixmap(&K, &L);
for(i=0; i < 500; i++) for(L=0; L < 100; L++)
x[0] = (double)i, x[1] = (double)L,
m_fill_pixmap(&K, x, &c);
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
K = L = 1,
m_save_pixmap(&K, "pippo."),
m_change_pixmap_background(&K, &L),
m_save_pixmap(&K, "pluto."),
m_flush(  ),
K = 0,
m_redraw(&K),
m_mouse(x),
m_endg(  );}

N.B.:
Questo programma è identico a quello fornito come esempio d'uso di m_change_pixmap_background.
Prima e dopo il cambio di sfondo si effettuano dei salvataggi su due diversi files
pippo.gif
pluto.gif
(per questo è più lento).

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































m_save_pixmap_to_load(i, nome, opz)

Questa funzione è solo un semplice "wrapper" di m_save_pixmap utile per produrre files adatti a essere riutilizzati come sorgente di immagine per m_load_external_pixmap.
L'argomento i (di tipo int/INTEGER*4) ha lo stesso significato del primo argomento di ogni funzione legata alla gestione di pixmap (cfr. m_use_as_pixmap); l'argomento opz ha lo stesso tipo e significato dell'omonimo argomento di m_load_external_pixmap; infine l'argomento nome (di tipo char* [fortranisti avvisati]) contiene il nome del file in cui la figura va salvata (e da cui eventualmente m_load_external_pixmap potrà ricuperarla).
Va osservato, oltre a quanto già detto circa l'iniziale di nome nella descrizione di m_save_pixmap, che, se l'ultimo carattere di nome è il carattere di sottolineatura, il contenuto di opz viene "appeso" alla fine del file e m_load_external_pixmap ce lo ritroverà alla rilettura del file.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{double x[8];
const char *ff = "_PAPPO.ppm_";
int k, K = atoi(args[2]), l, opz[  ]={0,0,0,0,0,0,1};
if(narg > 3) ff = args[3];
x[0] = x[1] = 0, x[2] = (double)K, x[3] = (double)K,
m_startg(const_cast<char *>("rete"), &K, &K),
m_toggle_message(  ),
m_window(&(k=0), &(l=0)),
m_frame(x, x+1, x+2, x+3),
m_use_as_pixmap(&(k=1), &(l=7)),
m_toggle_mouse_save_right(&(k=0)),
m_load_external_pixmap(&(l=1), args[1], opz);
while((l = m_mouse_int(opz)) != 2)
{m_mouse_int(opz+2);
switch(l)
{case 1:
m_color(&(l=BIANCO)),
x[0] = x[6] = (double)opz[0], x[2] = x[4] = (double)opz[2],
x[1] = x[3] = (double)(K-opz[1]), x[5] = x[7] = (double)(K-opz[3]),
m_polygon(x, &(l=4));
break;
case 3:
m_color(&(l=NERO)), x[0] = (double)opz[0], x[1] = (double)(K-opz[1]),
m_move(x), x[0] = (double)opz[2], x[1] = (double)(K-opz[3]), m_line(x);}}
memset((void *)opz, 0, 6*sizeof(int)),
m_save_pixmap_to_load(&(l=1), const_cast<char *>(ff), opz), m_endg(  );}



# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{double x[8];
const char *ff = "_PAPPO.ppm_";
int k, K = atoi(args[1]), l, opz[  ]={0,0,0,0,0,0,0};
x[0] = x[1] = 0, x[2] = (double)K, x[3] = (double)K,
m_startg(const_cast<char *>("rete"), &K, &K),
m_toggle_message(  ),
m_window(&(k=0), &(l=0)),
m_frame(x, x+1, x+2, x+3),
m_use_as_pixmap(&(k=1), &(l=7)),
m_toggle_mouse_save_right(&(k=0)),
m_load_external_pixmap(&(l=1), const_cast<char *>(ff), opz);
for(k=0; k < 7; k++) cerr << opz[k] << endl;
m_wait_for_events(&(k=EVENTO_ENTER)),
m_endg(  );}

N.B.:
I due programmi forniti lavorano in sinergia l'uno dopo l'altro: il primo carica una pixmap dal file fornito come primo argomento sulla linea comando e consente all'utente di modificarla apponendovi delle "pezze" bianche e/o tracciandovi sopra delle linee nere.
Al termine del ciclo while la funzione m_save_pixmap_to_load salva la figura modificata nel file _PAPPO.ppm_ da cui il secondo programma la ricarica.
La pixmap viene prodotta in modo monocromatico (sottolineatura iniziale) e nel file sono aggiunti i valori di opz (sottolineatura finale).

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






























































































m_load_external_pixmap(i, file, opz)

Questa funzione permette di usare qualsiasi figura, anche di origine estranea alla libreria, come sfondo di una pixmap, anche per una finestra NON deputata a tale uso (cfr. m_use_as_pixmap).
I due primi argomenti hanno lo stesso tipo e significato degli omonimi argomenti di m_save_pixmap, salvo il caso in cui i sia negativo: allora l'indice della finestra viene preso come |i| - 1 e consente di eseguire questa funzione su finestre non dedicate a pixmaps (finestre "normali"); in tal caso però l'argomento opz (descritto appresso) non potrà valere NULL dovendo per forza avere l'ultimo elemento uguale a 1 affinché l'esecuzione di questa funzione abbia qualche efficacia (cfr. appresso). Nel caso presente file deve indicare il pathname di un file già esistente e contenente un'immagine nel formato PPM (Portable PixMap Format) a colori.
Nessun altro formato è accettato dalla libreria per cui eventuali immagini GIF o JPG vanno prima convertite nel formato citato prima di poter essere usate con questa funzione (esistono alla bisogna numerosissimi convertitori).
L'ultimo argomento opz è di tipo intero (int/INTEGER*4) e, se non è NULL (nel senso dell'indirizzo: i fortranisti prestino attenzione), deve contenere ("puntare") 7 valori interi: i secondi due sono gli scostamenti (x e y) dell'angolo superiore sinistro della "sotto_immagine" che verrà ricopiata sulla pixmap misurati a contare dall'angolo superiore sinistro dell'intera immagine; i primi due sono gli scostamenti (x e y) del "sotto_rettangolo" della pixmap che riceverà la predetta "sotto_immagine", ancora misurati a contare dall'angolo superiore sinistro dell'intera pixmap; gli ulteriori due (il quinto e il sesto), quando non valgono zero, sono interpretati rispettivamente come larghezza e altezza della "sotto_immagine" che deve essere ricopiata.
L'ultimo elemento, se non vale zero, fa sì che l'immagine funga da "sfondo permanente" per la finestra.
Quando opz è trasferito come puntatore NULL i 7 valori standard per le predette quantità sono 0 0 0 0 L A 0, con L e A rispettivamente pari a larghezza e altezza dell'intera immagine.
Se l'immagine è più grande della pixmap viene "tagliata"; se è più piccola resta visibile lo sfondo normale (non ricoperto) della pixmap.

N.B.:
Quando la pixmap caricata attraverso questa funzione va intesa come uno "sfondo permanente" (vedi sopra) una esecuzione di m_clear_pixmap NON cancella anche la figura caricata con questa funzione. In caso contrario la figura, per essere ripristinata, dovrà essere ricaricata ex-novo eseguendo ancora la funzione presente.

N.B.:
Non è possibile passare a questa funzione i files prodotti con m_save_pixmap, i quali vanno recuperati con m_load_window salvo i casi in cui sia esplicitamente generato un file in formato PPM.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("computelena.ppm");
int K=1046, L = 708, *aa = new int[7];
double *x = new double[4];
x[0] = x[1] = 0.0, x[2] = x[3] = 1.0,
m_startg(u, &K, &L),
K = L = 90,
m_window(&K, &L),
K = 1, L = 3,
m_use_as_pixmap(&K, &L),
aa[0] = aa[1] = 0, aa[2] = aa[3] = 200, aa[4] = aa[5] = 0, aa[6] = 1,
m_load_external_pixmap(&(K=1), u, (int*)NULL),
m_flush(  ),
m_frame(x, x+1, x+2, x+3),
m_color(&(K=BIANCO)),
m_move(x),
m_line(x+2),
K = 0,
m_redraw(&K),
K = -1, L = 'B',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=2)),
K = -1, L = 'A',
m_loop_for_events(&L, &K),
m_endg(  );}

N.B.:
Questo programma visualizzerebbe (se il citato file fosse disponibile) l'immagine della bisnipotina dell'autore della libreria all'età di sette mesi (la bisnipotina, non l'autore), mentre gioca con la tastiera di un computer (buon sangue non mente). In base ai valori attribuiti al puntatore aa sarebbe "caricata" solo la parte di pixmap che inizia al pixel (200,200), ma poiché nell'esecuzione si mette il puntatore NULL si carica in effetti l'intera pixmap.
Naturalmente per poter eseguire con successo questo esempio occorre avere a disposizione il file computelena.ppm.
Si osservi il diverso effetto dell'esecuzione di m_clear_pixmap qualora la presente funzione venisse eseguita con l'argomento aa e con il valore 1 assegnato ad aa[6].

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_load_diaphanous_tiles(i, files, opzs, modo, funzioni)

Questa funzione agisce esattamente come m_load_tiles, cui si rimanda anche per quanto riguarda la descrizione dei primi tre argomenti; l'unica differenza rispetto a quella funzione consiste nel fatto, insito nel nome stesso, che le pixmaps caricate con questa sono rese trasparenti rispetto a un colore considerato come "colore di sfondo".
Il penultimo argomento serve appunto a stabilire un criterio per definire il tipo di trasparenza; modo è una VALIDA stringa di caratteri: se vale "auto" la funzione si ingegna da sola a determinare il colore di sfondo esaminando quello dei pixels che formano il perimetro della pixmap; se invece ha il seguente contenuto, escluse le virgolette,
"rgb:xxxx/xxxx/xxxx_n"

in cui i caratteri rgb, il carattere ':', i caratteri '/' e '_' sono obbligatori nella posizione in cui si trovano, mentre le xxxx vanno sostituite con quattro cifre esadecimali rappresentanti rispettivamente le componenti di rosso, verde e blu del colore di sfondo e n con qualsiasi numero intero decimale non negativo, ALLORA la funzione attribuisce a ogni pixel della pixmap che abbia colore xxxx/xxxx/xxxx entro n (in difetto o eccesso su ogni componente cromatica) la qualifica di pixel di sfondo. Ad esempio, se il contenuto di modo fosse rgb:ffff/0000/0000_0 tutti i pixel ROSSI della pixmap saranno considerati appartenere allo sfondo.
L'effetto del penultimo argomento è COMPLETAMENTE SOSTITUITO dall'ultimo argomento, qualora non si tratti di un puntatore nullo: in tal caso dev'essere un array di puntatori a funzioni void (tante quante sono le pixmap da caricare, con facoltà che alcuni di questi puntatori siano nulli) che ricevano, nell'ordine, un puntatore a int e un puntatore a char. Tali funzioni dovranno essere scritte dal fruitore della libreria, che le eseguirà aspettandosi che esse restituiscano, nel puntatore a char, l'equivalente booleano del fatto che il pixel le cui coordinate assolute si trovano puntate dal primo argomento sia o non sia da considerare un pixel di sfondo. In effetti la libreria pone nell'indirizzo di memoria puntato dal primo argomento quattro valori interi: oltre alle due coordinate assolute del pixel, agli offsets 0 e 1, anche le dimensioni della pixmap agli offsets 2 e 3. Appare evidente che l'uso dell'ultimo argomento consente di determinare uno sfondo non tanto in base al colore della pixmap quanto in base alla forma che le si vuol dare, indipendentemente dal colore.
Appare altresì evidente che, mentre l'argomento modo agisce globalmente, per tutte le pixmap caricate, l'argomento funzioni permette una gestione individuale delle singole pixmap.
Le pixmap sono considerate trasparenti nel senso che, ovunque vengano poste entro la finestra, i loro pixel di sfondo saranno sostituiti da quelli che si trovano già nella finestra, nella stessa posizione.

Esempio d'uso:

# include <passe_par_tout.h>

void funza(int *d, char *c)
{*c = d[0] <= d[1];}

int main(  )
{char *b = const_cast<char *>("board.ppm");
const char *u[  ]=
{"TNb.ppm",
"CNn.ppm",
"ANb.ppm",
"DNn.ppm",
"RNb.ppm",
"ANn.ppm",
"CNb.ppm",
"TNn.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"TBn.ppm",
"CBb.ppm",
"ABn.ppm",
"DBb.ppm",
"RBn.ppm",
"ABb.ppm",
"CBn.ppm",
"TBb.ppm",
"\0"};
void (*gunza[  ])(int*, char*)
{funza, funza, funza, funza,
funza, funza, funza, funza,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0};
int i, K=560, L = 560, **aa = new int*[32],
a[  ]={0,0,0,0,560,560,1}, dove[2],
quali[  ]{20,-1};
for(i=0; i < 32; i++)
aa[i] = new int[7], memset((void *)aa[i], 0, 7*sizeof(int));
for(i=0; i < 32; i++)
aa[i][6] = 1, aa[i][0] = (i%8)*70, aa[i][1] = 70*((i>=8)+5*(i>=16)+(i>=24));
m_startg(const_cast<char *>(""), &K, &L),
K = L = 0,
m_window(&K, &L),
K = 1, L = 3,
m_use_as_pixmap(&K, &L),
m_load_external_pixmap(&(K=1), b, a),
//m_load_tiles(&(K=1), const_cast<char **>(u), aa),
m_load_diaphanous_tiles(&(K=1), const_cast<char **>(u), aa, const_cast<char*>("auto"), 0),
//m_load_diaphanous_tiles(&(K=1), const_cast<char **>(u), aa, const_cast<char*>("auto"), gunza),
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'b',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=0)),
aa[20][1] = 350,
dove[0] = aa[20][0], dove[1] = aa[20][1],
m_move_tiles(&(K=1), quali, dove),
K = -1, L = 'a',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=ROSSO)),
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}


Questo programma, diversamente da quello proposto per m_load_tiles o m_move_tiles, invece di effettuare l'apertura e2-e4 fa la e2-e3. Si invita a riconoscere il diverso comportamento della presente funzione rispetto a m_load_tiles semplicemento rieseguendo il programma dopo aver sostituito il commento a quest'ultima con il commento alla funzione di cui si tratta. Non vi sarà chi non veda che questa funzione elimina la necessità di avere due pixmaps diverse per ciascun pezzo, secondo il colore della casa che occupi.
Si invita anche a sperimentare, per quanto sia offensivo per il giuoco degli scacchi, l'effetto dell'ultimo argomento non nullo, risuscitando la richiesta di esecuzione di questa funzione in cui si trasmette gunza.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_move_tiles(i, quali, dove)

Questa funzione sposta in una posizione diversa una (o più) pixmap caricata con m_load_tiles o m_load_diaphanous_tiles, rispetto alla posizione iniziale impostata da queste due funzioni. I primi due argomenti hanno tipo e semantica uguali a quelli forniti a m_hide_tiles; il terzo è un puntatore a int/INTEGER*4 che deve puntare 2n valori (se n è il numero di valori validi puntati dal secondo argomento) che saranno interpretati, a due a due, come coordinate orizzontale e verticale, rispettivamente, della nuova posizione che dovrà essere occupata dall'angolo superiore sinistro della pixmap da spostare. I valori puntati da dove devono quindi essere espressi nelle coordinate di pixel della finestra individuata dal primo argomento, col pixel in alto a sinistra che ha coordinate (0,0).
La libreria NON EFFETTUA ALCUN CONTROLLO sulla congruità dei valori puntati dal puntatore dove.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *b = const_cast<char *>("board.ppm");
const char *u[  ]=
{"TNb.ppm",
"CNn.ppm",
"ANb.ppm",
"DNn.ppm",
"RNb.ppm",
"ANn.ppm",
"CNb.ppm",
"TNn.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"TBn.ppm",
"CBb.ppm",
"ABn.ppm",
"DBb.ppm",
"RBn.ppm",
"ABb.ppm",
"CBn.ppm",
"TBb.ppm",
"\0"};
int i, K=560, L = 560, *aa[32], a[  ]={0,0,0,0,560,560,1}, dove[2],
quali[  ]{20,-1};
for(i=0; i < 32; i++)
aa[i] = new int[7], memset((void *)aa[i], 0, 7*sizeof(int));
for(i=0; i < 32; i++)
aa[i][6] = 1, aa[i][0] = (i%8)*70, aa[i][1] = 70*((i>=8)+5*(i>=16)+(i>=24));
m_startg(const_cast<char *>(""), &K, &L),
K = L = 0,
m_window(&K, &L),
K = 1, L = 3,
m_use_as_pixmap(&K, &L),
m_load_external_pixmap(&(K=1), b, a),
m_load_tiles(&(K=1), const_cast<char **>(u), aa),
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'b',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=0)),
aa[20][1] = 280,
dove[0] = aa[20][0], dove[1] = aa[20][1],
m_move_tiles(&(K=1), quali, dove),
K = -1, L = 'a',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=ROSSO)),
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}


Questo programma effettua la stessa apertura della partita di re e2-e4, come quello proposto come esempio di m_load_tiles, ma, grazie alla funzione qui descritta, non ha bisogno di effettuare una seconda esecuzione di quella funzione.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_hide_tiles(i, quali)

Questa funzione "nasconde" momentaneamente alla vista una (o più) pixmap caricata con m_load_tiles o m_load_diaphanous_tiles, ma SENZA rimuoverla definitivamente dalla memoria come invece fa m_unload_tiles. Le pixmaps così oscurate possono essere rivisualizzate tramite la funzione m_unhide_tiles.
I due argomenti hanno stesso tipo e semantica di quelli trasmessi a m_unload_tiles, la sola differenza essendo che questa funzione lascia inalterato il numero totale di pixmaps presenti in memoria per la finestra interessata; contestualmente gli indici stessi delle pixmaps restano assolutamente intonsi.
Se questa funzione vien fatta agire o su una finestra priva di pixmaps o su una (o più) pixmap già nascosta, si risolve in "nessuna operazione".

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *b = const_cast<char *>("board.ppm");
const char *u[  ]=
{"TNb.ppm",
"CNn.ppm",
"ANb.ppm",
"DNn.ppm",
"RNb.ppm",
"ANn.ppm",
"CNb.ppm",
"TNn.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"TBn.ppm",
"CBb.ppm",
"ABn.ppm",
"DBb.ppm",
"RBn.ppm",
"ABb.ppm",
"CBn.ppm",
"TBb.ppm",
"\0"};
int i, K=560, L = 560, *aa[32], a[  ]={0,0,0,0,560,560,1},
quali[  ]{20,-1};
for(i=0; i < 32; i++)
aa[i] = new int[7], memset((void *)aa[i], 0, 7*sizeof(int));
for(i=0; i < 32; i++)
aa[i][6] = 1, aa[i][0] = (i%8)*70, aa[i][1] = 70*((i>=8)+5*(i>=16)+(i>=24));
m_startg(const_cast<char *>(""), &K, &L),
K = L = 0,
m_window(&K, &L),
K = 1, L = 3,
m_use_as_pixmap(&K, &L),
m_load_external_pixmap(&(K=1), b, a),
m_load_tiles(&(K=1), const_cast<char **>(u), aa),
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'b',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=0)),
m_hide_tiles(&(K=1), quali),
K = -1, L = 'a',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=ROSSO)),
m_unhide_tiles(&(K=1), quali),
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=ROSSO)),
K = -1, L = 'w',
m_loop_for_events(&L, &K),
m_endg(  );}

Questo programma esemplifica l'uso di questa funzione e anche quello di m_unhide_tiles. È ripreso da quello proposto per m_unload_tiles e come quello visualizza, in presenza dei documenti *.ppm richiesti, lo schieramento iniziale dei pezzi su una scacchiera. In questo caso, però, il pedone bianco di re, che scompare alla vista dopo la digitazione di 'b', ricompare alla digitazione di 'a'.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_unhide_tiles(i, quali)

Questa funzione "risuscita" pixmaps che siano state in precedenza "nascoste" da m_hide_tiles (ma NON eliminate, per la qual bisogna si usa m_unload_tiles, perché non sarebbero in alcun modo rivisualizzabili). Descrizioni degli argomenti ed esempio d'uso si trovano in m_hide_tiles. Se questa funzione viene eseguita per una finestra priva di pixmaps o anche di pixmaps nascoste, si risolve in "nessuna operazione".

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_unload_tiles(i, quali)

Questa funzione elimina definitivamente dalla memoria del programma una (o più) pixmap precedentemente caricata con m_load_tiles o m_load_diaphanous_tiles; le pixmaps su cui questa funzione agisce divengono quindi non più utilizzabili.
Il primo argomento ha lo stesso tipo e significato dell'omologo argomento trasmesso a m_load_tiles (e a tutte le altre funzioni che hanno nel proprio nome la parole tiles);
il secondo è un VALIDO puntatore a int/INTEGER*4 che punta gli indici delle pixmap da rimuovere. Il puntatore si auto-termina al primo valore negativo puntato.
I valori (non negativi) puntati da quali non devono necessariamente essere ordinati, ma NON DEVONO, evidentemente, ECCEDERE il numero totale di pixmaps, meno 1, presenti nella finestra individuata dal primo parametro: a questo riguardo la libreria NON HA ALCUNA PROTEZIONE INTERNA. Dopo la rimozione il numero totale di pixmaps eventualmente residue viene automaticamente aggiornato dalla libreria, con completa rinumerazione degli indici, mantenendo l'ordine relativo delle pixmaps residue, un po' come accade agli iteratori di una classe contenitore STL dopo l'esecuzione del metodo erase.

Se questa funzione viene eseguita per una finestra in cui NON CI SIA alcuna pixmap si risolve, senza danno, in "nessuna operazione".

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *b = const_cast<char *>("board.ppm");
const char *u[  ]=
{"TNb.ppm",
"CNn.ppm",
"ANb.ppm",
"DNn.ppm",
"RNb.ppm",
"ANn.ppm",
"CNb.ppm",
"TNn.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"TBn.ppm",
"CBb.ppm",
"ABn.ppm",
"DBb.ppm",
"RBn.ppm",
"ABb.ppm",
"CBn.ppm",
"TBb.ppm",
"\0"};
int i, K=560, L = 560, *aa[32],
a[  ]={0,0,0,0,560,560,1},
quali[  ]{20,-1};
for(i=0; i < 32; i++)
aa[i] = new int[7], memset((void *)aa[i], 0, 7*sizeof(int));
for(i=0; i < 32; i++)
aa[i][6] = 1, aa[i][0] = (i%8)*70, aa[i][1] = 70*((i>=8)+5*(i>=16)+(i>=24));
m_startg(const_cast<char *>(""), &K, &L),
K = L = 0,
m_window(&K, &L),
K = 1, L = 3,
m_use_as_pixmap(&K, &L),
m_load_external_pixmap(&(K=1), b, a),
m_load_tiles(&(K=1), const_cast<char **>(u), aa),
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'b',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=0)),
m_unload_tiles(&(K=1), quali),
K = -1, L = 'a',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=ROSSO)),
K = -1, L = 'z',
m_loop_for_events(&L, &K),
m_endg(  );}

Questo programma, ripreso da quello proposto come esempio d'uso per m_load_tiles, realizza, in presenza dei documenti *.ppm citati, la disposizione iniziale dei pezzi di una scacchiera e, alla digitazione del tasto 'b', cui segue l'esecuzione della presente funzione, si noterà la scomparsa del pedone bianco di re.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_load_tiles(i, files, opzs)

Questa funzione è praticamente un "wrapper" per m_load_external_pixmap. Consente di "caricare" la finestra per cui viene eseguita, che deve OBBLIGATORIAMENTE essere stata destinata a una pixmap tramite esecuzione di m_use_as_pixmap, con un numero arbitrario (ragionevolmente) di pixmaps delle più svariate dimensioni e/o colori e/o immagini.
L'argomento i ha lo stesso tipo e significato rispetto all'omonimo argomento fornito a m_load_external_pixmap (cui si rinvia per la spiegazione).
L'argomento files è un array di stringhe il cui ultimo elemento DEVE ESSERE LA STRINGA DI LUNGHEZZA NULLA, utilizzata per "contare" il numero degli elementi nell'array. I fortranisti, MAL PER LORO, prestino attenzione a quanto altrove detto circa il passaggio di argomenti di tipo stringa alla libreria.
Ogni stringa di lunghezza positiva contenuta in files viene considerata come pathname di un documento contenente un'immagine in formato PPM, esattamente come m_load_external_pixmap tratta l'unica stringa che costituisce il proprio secondo argomento.
Ogni documento che non risultasse accessibile in lettura o che contenesse dati scorretti sarà semplicemente ignorato (al limite tutti, nel qual caso la funzione non farebbe nulla); a tal proposito si sottolinea che la funzione restituisce come proprio valore di ritorno il numero di pixmaps che sono state lette (e quindi caricate nella finestra) con successo.
L'ultimo argomento opzs è un array di puntatori (anche qui i fortranisti si arrangino, usando in modo acconcio un array a due indici) ciascuno equivalente ordinatamente al terzo argomento di m_load_external_pixmap.
Ne consegue che il numero di puntatori contenuto in opzs deve almeno pareggiare il numero di stringhe di lunghezza positiva contenute in files, ferma restando la libertà per ciascuno di essi di essere un puntatore nullo (e ancora una volta peggio per i fortranisti).

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{char *b = const_cast<char *>("board.ppm");
const char *u[  ]=
{"TNb.ppm",
"CNn.ppm",
"ANb.ppm",
"DNn.ppm",
"RNb.ppm",
"ANn.ppm",
"CNb.ppm",
"TNn.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PNn.ppm",
"PNb.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"PBb.ppm",
"PBn.ppm",
"TBn.ppm",
"CBb.ppm",
"ABn.ppm",
"DBb.ppm",
"RBn.ppm",
"ABb.ppm",
"CBn.ppm",
"TBb.ppm",
"\0"};
int i, K=560, L = 560, *aa[32], a[  ]={0,0,0,0,560,560,1};
for(i=0; i < 32; i++)
aa[i] = new int[7], memset((void *)aa[i], 0, 7*sizeof(int));
for(i=0; i < 32; i++)
aa[i][0] = (i%8)*70, aa[i][1] = 70*((i>=8)+5*(i>=16)+(i>=24));
m_startg(const_cast<char *>(""), &K, &L),
K = L = 0,
m_window(&K, &L),
K = 1, L = 3,
m_use_as_pixmap(&K, &L),
m_load_external_pixmap(&(K=1), b, a),
m_load_tiles(&(K=1), const_cast<char **>(u), aa),
m_flush(  ),
K = 0,
m_redraw(&K),
K = -1, L = 'b',
m_loop_for_events(&L, &K),
m_clear_pixmap(&(K=1), &(L=0)),
aa[20][1] = 280,
m_load_tiles(&(K=1), const_cast<char **>(u), aa),
K = -1, L = 'a',
m_loop_for_events(&L, &K),
m_endg(  );}


N.B.: Questo programma, proposto dallo studente Luca Orefice (soprannominato d'Artagnan) durante l'A.A. 2005-2006 carica una scacchiera (dal file "board.ppm") tramite m_load_external_pixmap, rendendola sfondo permanente per la finestra (cfr. il valore di a[6]); successivamente carica altre 32 pixmaps (dai files u[  ]) in modo volatile (si osservi che l'intero buffer aa è stato "azzerato" tramite l'esecuzione della funzione di sistema memset). L'attribuzione di valori agli elementi 0 e 1 dei puntatori aa[i], effettuata nel secondo ciclo for fa sì che si ottenga la distribuzione iniziale dei pezzi del gioco degli scacchi. Dopo l'uscita da m_loop_for_events l'esecuzione di m_clear_pixmap cancella tutte le pixmaps volatili lasciando la scacchiera ("board.ppm" era stata caricata in modo permanente). La successiva riesecuzione di m_load_tiles (dopo aver cambiato il valore di aa[20][1]) realizza la classica "partita di re" e2-e4.

N.B.:Per eseguire questo programma occorre ovviamente disporre dei files *.ppm citati nel codice (chi fosse interessato li può trovare qui, grazie alla cortesia di Luca Orefice.)



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































































mrapporto_assi(n, r)

Preseleziona la forma della figura che sarà contenuta nel file PostScript numero n (n = INTEGER*4/int). Il valore di n è compreso tra 0 e MAXPOST-1 (inclusi) e identifica ciascuno dei possibili files PostScript che saranno aperti.
Nell'attuale implementazione della libreria si ha MAXPOST = 60.
L'argomento r (REAL*8/double) rappresenta il rapporto della dimensione orizzontale alla dimensione verticale ed è compreso tra 0.05 e 20.0; eventuali valori fuori intervallo sono ignorati.
La forma di default è quadrata (r=1.0).
Questa funzione va chiamata, se si vuole, prima dell'apertura del file cui si riferisce (minizio_ps) e si intende che il valore di n si riferisce alla (n+1)-esima chiamata di minizio_ps in ordine cronologico. Eventuali chiamate a momenti non opportuni sono ignorate.

Esempio d'uso:

# include <passe_par_tout.h>

int main(  )
{int i;
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0};
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);}


N.B.: Questo programma non fa assolutamente nulla: si limita a preselezionare 6 forme diverse per eventuali future "figure PostScript" nei rapporti 1/2, 2/3, 1, 4/3 3/2 2.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































minizio_ps(file, scala, sf)

apre e inizializza un file PostScript di nome file (variabile stringa), pone a scala (REAL*8/double) la scala globale del disegno e a sf (REAL*8/double) il corpo del fonte di caratteri default. Inoltre riconnette la libreria con stderr.
scala è positivo. Il valore 1.0 dà un disegno di 14 cm di lato.
sf è positivo; il valore 1.0 dà un fonte di 8 mm quando anche scala vale 1.0.
Il valore di scala influenza anche la grandezza dei caratteri stampati per cui se si vogliono mantenere alla grandezza iniziale di 8 mm occorre che il prodotto

scala * sf

valga 1.0.
Per chi usa il FORTRAN valgono le cautele indicate a proposito delle stringhe di caratteri per la corretta interpretazione dell'argomento file (m_conv_string e m_conv_chars).
Il numero massimo di files PostScript che possono essere tenuti SIMULTANEAMENTE aperti è di 60 (sessanta); ogni file è completamente indipendente da tutti gli altri.
Per indirizzare l'output a uno dei files aperti cfr. mindirizza_ps.
Nessuna funzione il cui nome contenga la stringa "_ps" può essere chiamata prima di minizio_ps, RELATIVAMENTE A UN PARTICOLARE FILE.
Un file PostScript appena aperto da minizio_ps riceve tutto il susseguente output fino a una successiva chiamata a minizio_ps o a mindirizza_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i;
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf);}


N.B.: Questo programma lascia nella cartella da cui viene eseguito un file assolutamente inutile il cui nome è dato dal primo argomento inserito sulla linea comando (eseguendolo si faccia attenzione a non usare il nome di un file utile preesistente che verrebbe sovrascritto). Tale file, dato in pasto a un visualizzatore come ghostview non produce alcun errore; tuttavia, se inviato in stampa, non produrrà alcuna pagina.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































mfine_ps(  )

Funzione priva di argomenti in ingresso serve a chiudere tutti i files PostScript correntemente aperti da minizio_ps che sono quindi pronti per essere stampati (a condizione che la libreria non abbia segnalato alcun errore).
Dopo la chiamata a mfine_ps può solo essere chiamata minizio_ps tra tutte le funzioni che contengono la stringa "_ps" nel proprio nome.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i;
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfine_ps(  );}

N.B.: Questo programma lascia nella cartella da cui viene eseguito un file assolutamente inutile il cui nome è dato dal primo argomento inserito sulla linea comando (eseguendolo si faccia attenzione a non usare il nome di un file utile preesistente che verrebbe sovrascritto); tale file, se inviato in stampa, produrrà una pagina bianca.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






































































































mpaginaA4_ps(  )

Funzione senza argomenti; serve a trattare il file corrente (che deve essere aperto) come una pagina A4. Dopo l'esecuzione di questa funzione le coordinate usate per qualsiasi operazione di disegno sono valutate in centimetri a partire dall'angolo inferiore sinistro della pagina. Se stderr è collegato la libreria rammenta all'utente questa necessità ad ogni occorrenza. Questa funzione, pur essendo estremamente potente consentendo di accedere indistintamente all'intera pagina, va preferibilmente usata solo in caso di effettivo bisogno e da parte di chi conosca sufficientemente il linguaggio PostScript.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=0, qyl=5, qyr=0, alt[  ]={-2, 0, -2, 0};
double scala = 1.0, sf = 1.0, z[2],
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
char *titolo=const_cast<char *>("ecco un titolo"),
*assex=const_cast<char *>("etichetta asse x"),
*assey = const_cast<char *>("etichetta asse y");
if(narg < 2)
printf("devi fornire almeno un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax);
if(narg == 2)
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
i = 1,
mtitoli_ps(titolo, assex, assey, &i);
z[0] = xmin, z[1] = ymax,
mmuovi_ps(z),
z[0] = xmax, z[1] = ymin,
mlinea_ps(z),
mpaginaA4_ps(  ),
z[0] = 0, z[1] = 0,
mcolore_ps(&(i=1)),
mmuovi_ps(z),
z[0] = 21, z[1] = 29,
mlinea_ps(z),
xmin = 0.0, ymin = 0.0, xmax = 10.0, ymax = 10.0, sf = 0.5;
mrapporto_assi_(&(i=0), &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
z[0] = xmin, z[1] = ymax,
mmuovi_ps(z),
z[0] = xmax, z[1] = ymin,
mcolore_ps(&(i=2)),
mlinea_ps(z),
mpaginaA4_ps(  ),
z[0] = 0, z[1] = 10,
mmuovi_ps(z),
z[0] = 21, z[1] = 10,
mcolore_ps(&(i=3)),
mlinea_ps(z),
xmin = 0.0, ymin = 0.0, xmax = 10.0, ymax = 10.0, sf = 0.5;
mfinestra_ps(&xmin, &ymin, &xmax, &ymax);
if(narg > 2)
mcolore_ps(&(i=0)),
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
i = 1,
mtitoli_ps(titolo, assex, assey, &i);
z[0] = (xmin+xmax)*0.5, z[1] = ymax,
mmuovi_ps(z),
z[0] = (xmin+xmax)*0.5, z[1] = ymin,
mcolore_ps(&(i=6)),
mlinea_ps(z),
mfine_ps(  );}


N.B.: Questo programma mostra come sia possibile effettuare ripetute esecuzioni, identificabili coi diversi colori, sia di mpaginaA4_ps sia di mfinestra_ps (con diversi sistemi di riferimento) sullo stesso file.
Si notino il cambiamento di rapporto assi per la seconda esecuzione di mfinestra_ps e il fatto che le quotature e i titoli vengono eseguiti una sola volta in base al numero di argomenti forniti sulla linea comando.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"































































































































mfattore_scala_ps(x, y)

Funzione da chiamare prima di mfinestra_ps se si vuole che sia efficace. I due argomenti, entrambi di tipo int/INTEGER*4, sono interpretati come gli esponenti di 10 di un fattore di scala utilizzato per scrivere i valori delle quotature rispettivamente per gli assi orizzontale e verticale (qualora le scale siano lineari). I valori default sono 0 per entrambi. In parole brevi se su un asse lineare viene riportata una variabile compresa tra 0 e 10000 e si fornisce il corrispondente fattore di scala col valore 4 le quote di quell'asse varieranno tra 0 e 1 pur continuando le coordinate dei punti graficati a variare tra 0 e 10000. Non si ritiene necessario dare l'esempio d'uso.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



























































































mfinestra_ps(xmin,ymin,xmax,ymax)

Svolge per il file PostScript correntemente APERTO (cfr. minizio_ps) le stesse funzioni svolte da m_frame per lo schermo. Anche gli argomenti hanno lo stesso significato e lo stesso tipo REAL*8/double; tuttavia NON traccia né il sistema di riferimento né le quotature. Può essere eseguita più volte per lo stesso file, anche fornendo sistemi di riferimento diversi, tuttavia una volta tracciate le quotature (cfr. mquotature_ps) non si possono ritracciare.
Le (eventuali) esecuzioni multiple di questa routine possono anche essere inframmezzate da esecuzioni di mpaginaA4_ps. Ad ogni "nuova" esecuzione va persa l'efficacia di eventuali chiamate precedenti di mspessore_linea_ps e viene ripristinato lo spessore default iniziale.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i;
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mfine_ps(  );}


N.B.: Questo programma è identico a quello fornito come esempio d'uso di mfine_ps con in più la definizione di un sistema di riferimento per un'eventuale figura. Si osservi che la chiamata di mfinestra_ps non può precedere quella di minizio_ps.
Anche il file generato da questo programma produce la stampa di una pagina vuota.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"























































































mcomponi_accento(input, output)

Questa funzione può essere eseguita anche se nessun file PostScript è correntemente aperto (infatti il suo nome non termina coi caratteri _ps, cfr "generalità"). Serve a convertire l'argomento input di tipo char*/CHARACTER(  ) nell'argomento output (dello stesso tipo) in modo che siano fruibili i caratteri PostScript accentati. Per i programmatori C o C++ (ossia quelli seri) lo stesso valore è anche restituito dalla funzione stessa che è appunto di tipo char*. Lo spazio per l'argomento output DEVE ESSERE STATO ALLOCATO DAL PROGRAMMA CHIAMANTE IN MISURA SUFFICIENTE A CONTENERE L'ARRAY DI CARATTERI CONVERTITO.
La conversione avviene come segue: ogni occorrenza in input di una sottostringa di due caratteri consecutivi riconosciuta come sequenza di carattere accentato viene sostituita in output (e nel valore di ritorno della funzione) con una sottostringa di 4 caratteri che rappresenta il codice ottale di quel carattere accentato così come richiede l'interprete PostScript. Va da sé che ogni occorrenza in input di una delle citate sottostringhe fa aumentare di due unità lo spazio da allocare per output.
Sono riconosciute 40 sottostringhe di due caratteri consecutivi che vengono convertite secondo la seguente tabella

Seq.      Cod.        Car.
a`       \260      à     
a'       \265       á     
e`       \321       è     
e'       \322       é     
i`       \325       ì
i'       \326       í
o`       \331       ò
o'       \332       ó
u`       \336       ù
u'       \337       ú
a"       \300       ä
e"       \324       ë
i"       \330 ï
o" \334 ö
u" \342 ü
a^ \276 â
e^ \323 ê
i^ \327 î
o^ \333 ô
u^ \340 û
a~ \311 ã
n~ \344 ñ
o~ \335 õ
A` \345 À
A' \345 À
E` \346 È
E' \363 É
I` \347 Ì
I' \366 Í
O` \354 Ò
O' \354 Ò
U` \355 Ù
U' \355 Ù
O" \374 Ö
E^ \364 Ê
I^ \367 Î
A~ \362 Ã
N~ \357 Ñ
c, \314 ç
C, \356 Ç



CAVEATS:

Quantunque la funzione possa agire su stringhe di qualunque lunghezza e contenuto vanno osservati alcuni criteri.



Esempio d'uso:

#include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{char *inputstringa = "\
\"Pape` Sata`n, Pape` Sata`n Aleppe \"\n\
comincio` Pluto con la voce chioccia;\n\
e quel savio gentil che tutto seppe\n\n\
disse per confortarmi: \"Non ti noccia\n\
la tua paura, che', poter ch'egli abbia,\n\
non ci torra` lo scender questa roccia.\"\n\n\
Poi si rivolse a quell'enfiata labbia\n\
e disse: \"Taci, maladetto lupo!\n\
Consuma dentro te con la tua rabbia!\n\n\
Non e` sanza cagion l'andare al cupo:\n\
vuolsi ne l'alto la` dove Michele\n\
fe ' la vendetta del superbo strupo.\"\n\n\
Quali dal vento le gonfiate vele\n\
caggion avvolte poi che l'alber fiacca\n\
cotal si fe ' quella fiera crudele.\n\n\
Cosi` scendemmo ne la quarta lacca\n\
pigliando piu` della dolente ripa\n\
che 'l mal dell'universo tutto insacca \n\n",
*outputstringa = (char *)malloc(strlen(inputstringa)+21);
printf("%s", mcomponi_accento(inputstringa, outputstringa));}



N.B.: Questo programma produce su stdout la seguente stringa "convertita":


"Pap\321 Sat\260n, Pap\321 Sat\260n Aleppe "
cominci\331 Pluto con la voce chioccia;
e quel savio gentil che tutto seppe

disse per confortarmi: "Non ti noccia
la tua paura, ch\322, poter ch'egli abbia,
non ci torr\260 lo scender questa roccia."

Poi si rivolse a quell'enfiata labbia
e disse: "Taci, maladetto lupo!
Consuma dentro te con la tua rabbia!

Non \321 sanza cagion l'andare al cupo:
vuolsi ne l'alto l\260 dove Michele
fe ' la vendetta del superbo strupo."

Quali dal vento le gonfiate vele
caggion avvolte poi che l'alber fiacca
cotal si fe ' quella fiera crudele.

Cos\325 scendemmo ne la quarta lacca
pigliando pi\336 della dolente ripa
che 'l mal dell'universo tutto insacca.



Si notino gli spazi a destra di "Aleppe" e di "fe " per evitare che i successivi caratteri " e ' formino una sequenza riconosciuta. Si noti anche l'allocazione del puntatore outputstringa non necessaria per un programma in C o C++ ma richiesta per compatibilità con quella ciofeca del Fortran.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































mquotature_ps(qxl,qxh,qyl,qyr,alt)

Serve a scrivere le quote sugli assi sia in orizzontale sia in verticale, sia a sinistra sia a destra e nel numero che si desidera.
Se non viene mai chiamata si ottiene comunque una quotatura di default che riporta soltanto i valori di minimo e massimo di entrambe le coordinate.

qxl, qxh, qyl, qyr sono quattro interi (INTEGER*4/int);
alt è un array di lunghezza 4 di tipo INTEGER*4/int i cui elementi agiscono in corrispondenza dei 4 interi citati in precedenza: (qxl <--> alt{1} etc.).

Il significato degli argomenti è il seguente, usando la coppia qxl,alt{1} come campione:

il valore assoluto di qxl indica QUANTE QUOTATURE vanno poste (in forma di piccole tacche) all'interno dell'asse orizzontale inferiore.

Se alt{1} è positivo e non maggiore di 100 su ogni tacca è segnato il valore corrispondente della variabile posta su quell'asse; se è negativo e non minore di -100 i valori sono segnati su una tacca no e una sì, (a meno che abs(qxl) non sia un numero pari, nel qual caso si quotano comunque tutte le tacche); se è nullo o con valore assoluto > 100 vengono segnati soltanto minimo e massimo della scala.

Con alt{1}=0 si hanno quotature con due cifre significative/decimali, con abs(alt{1}) >= 100 si hanno quotature con abs(alt{1})-100 cifre significative/decimali. In ogni altro caso si hanno abs(alt{1}) cifre significative/decimali, con il numero di cifre comunque limitato superiormente a 15 (ciascuno ne tragga le opportune considerazioni)

La distinzione tra cifre significative e decimali si attua come segue: la routine scrive le quotature in notazione a virgola fissa se la parte intera del logaritmo in base 10 di (max-min)/(1+abs(qxl)) è compresa tra -2 e 3 (inclusi); si parla in questo caso di cifre decimali (ossia poste dopo il punto decimale). In caso contrario le quotature sono scritte con la notazione esponenziale e contestualmente si parla di cifre significative.

Se qxl è negativo la quotatura viene fatta sull'unico asse orizzontale (in tal caso qxh [cfr. appresso] è ininfluente) del sistema di riferimento cartesiano (cfr. mcontorno_ps). Non viene fatto alcun test sulla coerenza tra gli argomenti forniti alla funzione e quello assegnato successivamente a mcontorno_ps.

Gli altri argomenti agiscono in modo analogo per:
qxh + alt{2} --> asse orizzontale superiore (se presente)
qyl + alt{3} --> asse verticale sinistro
qyr + alt{4} --> asse verticale destro (se presente)

Se l'asse da quotare (in base a quanto fin qui detto) è logaritmico vengono disegnate tutte le 10 tacche corrispondenti ai numeri interi su ogni decade contenuta nell'asse stesso. Le quotature sono però scritte solo in corrispondenza di tutte e sole le tacche di "fine decade". In questo caso il significato dell'argomento alt relativo all'asse in questione non serve ad altro che a decidere il formato di scrittura delle quotature (ferma restando la possibilità di scriverci qualunque cosa attraverso l'uso di mquotature_con_stringhe_ps). Precisamente se il valore dell'elemento opportuno di alt è non nullo la quotatura viene scritta in formato "intero" (10, 100, 1000, ...), mentre se è nullo viene scritta in notazione esponenziale a lunghezza "fissa" (10^1, 10^2, 10^3,...)

Per default le quotature poste lungo gli assi verticali sono scritte orizzontalmente, secondo la normale orientazione di lettura; tuttavia è possibile farle disporre lungo l'asse (ossia ruotarle di 90° per l'asse sinistro e di -90° per l'eventuale asse destro) aumentando di 200 il valore assoluto di qyl (o qyr).

Una menzione particolare merita la quotatura dell'asse verticale sinistro in relazione all'eventuale concomitante e successiva scrittura di un titolo lungo lo stesso asse; in tal caso può accadere che ci sia spazio sufficiente tra una quotatura e l'altra per potervi piazzare frammezzo un titolo breve senza discostarsi dall'asse come la libreria fa, in default, per evitare sovrapposizioni tra titolo e quote. A tale scopo basta fornire, in questa funzione come in mquotature_con_stringhe_ps, il terzo elemento dell'array alt (quello appunto deputato a descrivere come quotare l'asse verticale sinistro) col suo valore appropriato ma con il bit numero 30 acceso. Per tale bisogna è disponibile la costante, dal nome parlante, ADERISCI_ASSE_SINISTRO. Nessun controllo viene a questo punto compiuto dalla libreria sull'eventuale sovrapposizione che si producesse tra titolo e quote.

VA TENUTO PRESENTE CHE SE QUESTA FUNZIONE VIENE ESEGUITA DOPO mcontorno_ps (PER UN DETERMINATO FILE) RISULTA DEL TUTTO INEFFICACE. IN UN SIMILE CASO LA LIBRERIA INVIA UN MESSAGGIO DI AVVERTIMENTO SU stderr (PURCHÉ COLLEGATO, cfr. minverti_messaggio_ps).
IN PARTICOLARE, SE SI INTENDESSE QUOTARE UN FILE POSTSCRIPT OMBRA, L'ESECUZIONE DI
mfora_contorno_ps E DI mricontorna_ps RESTA A CARICO DEL PROGRAMMATORE.


Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=0, qyl=5, qyr=0, alt[  ]={-2, 0, -2, 0};
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
mfine_ps(  );}


N.B.: Questo programma produce in stampa una pagina con qualcosa dentro: precisamente due sistemi di quotature alternate sull'asse x inferiore e sull'asse y di sinistra, una volta che saranno disegnati. Le quotature hanno due cifre significative. Si osservi che il rapporto orizzontale/verticale è 1/2 perché per il primo file aperto da minizio_ps va in vigore la prima chiamata di mrapporto_assi.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
































































































mquotature_con_stringhe_ps(qxl,qxh,qyl,qyr,alt,stringhe)

Se non fosse necessario mantenere in vita quella ciofeca del fortran questa funzione sarebbe potuta essere un semplice "overload" di mquotature_ps.
In effetti tutti gli argomenti, eccetto l'ultimo, sono identici a quelli della citata funzione e hanno lo stesso significato (cfr.).
L'ultimo argomento stringhe è, per i programmatori C o C++, un array di puntatori a stringhe con un elemento per asse (in tutto quattro elementi), mentre per i fortranisti è un array di caratteri a tre dimensioni con l'ultima dimensione = 4 (bah!).
Se tutte le stringhe contenute in stringhe fossero nulle la chiamata di questa funzione equivarrebbe "in toto" a quella di mquotature_ps.
Ogni stringa non nulla viene scritta (usando la sintassi di mscrivi_quasi_come_TeX_ps) al posto del numero reale corrispondente (quello che scriverebbe mquotature_ps).

Avvertenza:

Quando questa funzione viene usata per inserire quotature con stringhe comprendenti esponenti e/o pedici la BoundingBox della figura calcolata dalla libreria risulta sovrastimata. Ciò è stato preferito dall'autore piuttosto che perder tempo a valutare la struttura fine di ogni stringa per controllare il numero di esponenti e/o pedici, la loro lunghezza, la dimensione relativa del fonte con cui sono scritti al fine di una stima esatta dell'ingombro effettivo della stringa in questione.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=5, qyl=5, qyr=5, alt[  ]={-2, -2, -2, -2};
char **strin[4];
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
strin[0] = (char **)malloc((qxl+2)*sizeof(char *)),
strin[1] = (char **)malloc((qyl+2)*sizeof(char *)),
strin[3] = (char **)malloc((qyr+2)*sizeof(char *)),
strin[2] = (char **)malloc((qxh+2)*sizeof(char *));
for(i=0; i < 7; i++)
strin[1][i] = strin[2][i] = strin[3][i] = (char*)NULL;
for(i=1; i < 6; i++) strin[0][i] = (char *)NULL;
strin[0][0] = "-!p_n", strin[0][6] = "!p^n";
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mquotature_con_stringhe_ps(&qxl, &qxh, &qyl, &qyr, alt, strin),
mfine_ps(  );}


N.B.: Questo programma è identico a quello fornito come esempio d'uso di mquotature_ps salvo il fatto che sull'asse x inferiore la prima e l'ultima quotatura sono costituite da stringhe con sintassi "quasi TeX" e che sono quotati anche gli assi di destra e in alto.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































mtitoli_ps(titolo,assex,assey,n) 

Pone le stringhe titolo, assex e assey attorno alla figura in posizioni determinate dall'argomento n (INTEGER*4/int). Se necessario viene effettuata una chiamata implicita di mfora_contorno_ps.

La stringa titolo viene centrata sotto o sopra la figura secondo che n=0 oppure no. La sua lunghezza è limitata a un massimo di 80 caratteri.

Le stringhe assex e assey sono piazzate al centro dei due lati della box oppure accanto alle frecce cartesiane oppure non disegnate affatto secondo che (rispettivamente) sia n>0, n<0, o n=0. Le loro lunghezze sono limitate a 40 caratteri.

Se n>1 il contenuto dei suoi tre bytes meno significativi viene utilizzato come offsets delle titolazioni (da destra rispettivamente per il titolo, per l'asse x e per l'asse y); ognuno dei tre bytes è suddiviso in due metà di quattro bit ciascuna (in cui si possono inserire, in modo ovvio, valori compresi tra 0 e 15) che rappresentano rispettivamente gli offsets orizzontali e verticali di ciascun titolo.
I valori "quantizzati" tra 0 e 15 rappresentano percentuali delle estensioni spaziali dei rispettivi assi comprese tra -40% e +140% per il titolo generale e -25% e +125% per i titoli x e y.

Se chiamata da FORTRAN occorre tener conto di quanto detto a proposito delle variabili stringa (generalità, m_conv_string e m_conv_chars).

Il fonte usato è quello corrente (Helvetica se non è stata mai chiamata la funzione mfonte_ps).

Le stringhe possono essere fornite secondo le sintassi riconosciute da mscrivi_ps e da mscrivi_quasi_come_TeX_ps.
In quest'ultimo caso, e quando n > 0, le stringhe sono sempre scritte a partire dalla posizione mediana del riquadro della figura, a meno che non sia n>1 e il contenuto del terzo byte da destra non sia zero, altrimenti sono "centrate".

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=0, qyl=5, qyr=0, alt[  ]={-2, 0, -2, 0};
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
char *titolo=const_cast<char *>("questo est un titolo"),
*assex=const_cast<char *>("etichetta asse x"),
*assey = const_cast<char *>("etichetta asse y");
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
i = 1,
mtitoli_ps(titolo, assex, assey, &i),
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mquotature_ps. Si è solo aggiunta una chiamata esemplificativa di mtitoli_ps.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




































































































morigine_ps(x,y,a)

Pone l'origine del disegno nella posizione individuata all'interno della pagina A4 da x e y espressi in centimetri relativamento all'angolo inferiore sinistro della pagina stessa. Inoltre orienta il disegno secondo l'angolo a espresso in gradi.
Tutti i tre argomenti sono REAL*8/double. Nessun test viene fatto sul valore assegnato agli argomenti.

Perché sia efficace deve essere chiamata prima di mfinestra_ps e di mcontorno_ps e, ovviamente, dopo minizio_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=0, qyl=5, qyr=0, alt[  ]={-2, 0, -2, 0};
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
char *titolo=const_cast<char *>("questo est un titolo"),
*assex=const_cast<char *>("etichetta asse x"),
*assey = const_cast<char *>("etichetta asse y");
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
r[0] = 18.5, r[1] = 2.5, r[2] = 90.0,
morigine_ps(&r[0], &r[1], &r[2]),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
i = 1,
mtitoli_ps(titolo, assex, assey, &i),
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mtitoli_ps. Si è solo aggiunta una chiamata esemplificativa di morigine_ps posta immediatamente prima di mfinestra_ps.
L'effetto consiste nell'ottenere la stessa figura ruotata di 90 gradi.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"















































































mcontorno_ps(flag)

Traccia il sistema di riferimento e lo quota utilizzando il fonte corrente (questo se non è stata chiamata in precedenza mquotature_ps).

Inoltre serve a definire la regione al di fuori della quale NULLA PIÙ sarà disegnato e/o scritto.

L'argomento flag è un INTEGER*4/int che lavora come segue:

flag = 1:
viene tracciata una box quadrata attorno alla finestra logica, rendendo il disegno stampato del tutto simile a quello (eventualmente) visualizzato sullo schermo.

flag = 0:
vengono tracciati due assi cartesiani (in forma di frecce) intersecantisi nell'origine delle coordinate dell'utente (se questa cade all'interno della regione indicata in mfinestra_ps).

flag = -1:
non viene tracciato un bel nulla, ma si ha in ogni caso l'effetto di clipping sulla finestra logica definita da mfinestra_ps.


Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=0, qyl=5, qyr=0, alt[  ]={-2, 0, -2, 0};
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
char *titolo=const_cast<char *>("questo est un titolo"),
*assex=const_cast<char *>("etichetta asse x"),
*assey = const_cast<char *>("etichetta asse y");
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
i = 1,
mtitoli_ps(titolo, assex, assey, &i),
mcontorno_ps(&i),
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mtitoli_ps. Si è solo aggiunta una chiamata esemplificativa di mcontorno_ps.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"































































































mfora_contorno_ps(  )

Questa funzione senza argomenti serve a rimuovere dal file corrente l'effetto di clipping stabilito dalla chiamata di mcontorno_ps.
Utile per poter ritracciare checchessia al di fuori del contorno stabilito.

Esempio d'uso: cfr. mricontorna_ps.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




























































































mricontorna_ps(  )

Questa funzione senza argomenti annulla l'effetto di mfora_contorno_ps e ripristina pertanto il clipping sul file PostScript corrente.
Tuttavia non ridisegna nulla sulla pagina pertanto se si vuole di fatto ridisegnare l'eventuale contorno (perché ad esempio qualche curva ci è finita sopra colorandolo del proprio colore) va comunque rieseguita mcontorno_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=0, qyl=5, qyr=0, alt[  ]={-2, 0, -2, 0};
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0}, x[2],
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
char *titolo=const_cast<char *>("questo est un titolo"),
*assex=const_cast<char *>("etichetta asse x"),
*assey = const_cast<char *>("etichetta asse y");
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
i = 1,
mtitoli_ps(titolo, assex, assey, &i),
mcontorno_ps(&i),
mfora_contorno_ps(  ),
sf = 0.0,
x[0] = xmin, x[1] = ymax + 0.2 * (ymax-ymin),
mscrivi_ps(const_cast<char *>("questo viene scritto nonostante tutto"), x, &sf),
mricontorna_ps(  ),
mfine_ps(  );}


N.B.: Questo programma è identico a quello fornito come esempio d'uso di mcontorno_ps e viene presentato come esempio simultaneo d'uso di mricontorna_ps e mfora_contorno_ps. Per l'uso di mscrivi_ps cfr. il link indicato.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






















































































massegna_bounding_box_ps(BoundingBox)

Questa funzione serve a ottenere una bounding box per il file PostScript correntemente aperto secondo i valori int/INTEGER*4 esplicitamente e ordinatamente assegnati nel puntatore BoundingBox.
Può anche essere eseguita ripetutamente per lo stesso file, restando sottinteso che la bounding box effettivamente applicata sarà l'ultima assegnata dato che l'applicazione stessa avviene all'atto della chiusura del file, in concomitanza con l'esecuzione (implicita o esplicita) di mchiudi_ps.
Non si ritiene necessario fornire un esempio d'uso.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mmarca_ps(i)

Colloca un "mark" sul file correntemente indirizzato (cfr. mindirizza_ps) qualora il valore dell'argomento INTEGER*4/int i sia non nullo.

Se tale argomento è nullo si limita a fornire come valore di ritorno il più alto "mark" già collocato sul file senza aggiungerne alcuno.

Va da sé che, per usufruire di questa caratteristica, anche chi programma in FORTRAN dovrebbe usare mmarca_ps come function e NON come subroutine.

I "mark" si incrementano di una unità ad ogni successiva chiamata di mmarca_ps relativamente allo stesso file e il primo "mark" collocato vale sempre 1. Se non chiamata esplicitamente dall'utente mmarca_ps è comunque chiamata automaticamente dalla libreria al termine dell'esecuzione di mfinestra_ps.

Esempio d'uso: cfr. mcancella_ps

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

























































































































mmarca_stringa_ps(stringa, modo)

Inserisce la stringa stringa (character*(*)/char *) nella posizione attuale del file correntemente in uso. La libreria aggiunge comunque a stringa due caratteri di "andata a capo", uno prima e uno dopo stringa.
modo è un INTEGER*4/int che decide come va trattata stringa dal punto di vista del codice PostScript che viene prodotto.
Precisamente se modo è non nullo stringa viene inserita così come è stata fornita (salvo quanto detto sopra a proposito delle "andate a capo"); in tal modo chi sa quello che fa può inserire vero codice PostScript indipendente dalla libreria all'interno del file.
Se invece modo è nullo stringa viene inserita come commento, il che significa che viene prefissata da due caratteri % (segno di percentuale).
In questo caso stringa NON può, a sua volta, contenere dei caratteri di "andata a capo", pena errori cagionati all'interprete PostScript.

Esempio d'uso: cfr. mrimuovi_ps


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






















































































mrimuovi_ps(inizio, fine, modo)

Rimuove dal file PostScript corrente tutto quanto si trova tra la prima occorrenza della stringa inizio (character*(*)/char *) e la successiva prima occorrenza della stringa fine (character*(*)/char *) compresa.
I fortranisti ricordino come si passano argomenti stringa alla libreria (cfr. m_conv_string o m_conv_chars).

modo è un INTEGER*4/int che serve a decidere se anche la stringa inizio debba essere rimossa (modo = 0) o lasciata nel file (modo non nullo).
Se la stringa inizio non viene trovata il file PS resta intatto e la chiamata risulta irrilevante.
Se la stringa fine non viene trovata si ha la rimozione di tutto il file (fino alla fine del file) a partire da inizio e salvo quanto detto circa il valore di modo.

Esempio d'uso congiunto di mrimuovi_ps e mmarca_stringa_ps:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, s[  ]={0,1};
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 1.0, xmax = 1.0, ymax = 1000.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mscalelogaritmiche_ps(s),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, 3*x[0]),
mmuovi_ps(x);
for(i=1; i < 101; i++)
x[0] = (double)i / 100.0,
x[1] = pow(10.0, 3*x[0]),
mlinea_ps(x);
mmarca_stringa_ps("parto da qui", &(i=0)),
mcolore_ps(&(i=1));
x[0] = xmin, x[1] = pow(10.0, 2*x[0]),
mmuovi_ps(x);
for(i=1; i < 101; i++)
x[0] = (double)i / 100.0,
x[1] = pow(10.0, 2*x[0]),
mlinea_ps(x);
mmarca_stringa_ps("finisco qui", &(i=0)),
mcolore_ps(&(i=2));
x[0] = xmin, x[1] = pow(10.0, x[0]),
mmuovi_ps(x);
for(i=1; i < 101; i++)
x[0] = (double)i / 100.0,
x[1] = pow(10.0, x[0]),
mlinea_ps(x);
if(narg > 2)
sscanf(args[2], "%d", &i),
mrimuovi_ps("parto da qui", "finisco qui", &i);
mfine_ps(  );}


N.B.: Questo programma è tratto da quello fornito come esempio d´uso di mlinea_ps.
Vengono tracciate tre linee e immediatamente prima del tracciamento della seconda e della terza linea si esegue mmarca_stringa_ps.
Quindi, secondo il numero di argomenti forniti sulla linea comando, viene eseguita o no mrimuovi_ps. Nel primo caso la seconda linea tracciata non appare nel file prodotto dal programma.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"








































































































mcancella_ps(inizio, fine, conserva)

Elimina fisicamente dal file correntemente indirizzato (cfr. mindirizza_ps) quanto sta tra il "mark" inizio (INTEGER*4/int) e il "mark" fine (come sopra).

Per il significato dei "marks" confronta mmarca_ps.

L'argomento conserva ha tipo (INTEGER*4/int) e se è non nullo lascia nel file il "mark" fine che altrimenti viene rimosso come accade comunque sempre al "mark" inizio.

La funzione segnala chiamate anomale come ad esempio inizio>=fine o file indirizzato non ancora aperto o quant'altro. In ognuno di tali casi la chiamata ritorna senza produrre alcun effetto.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, qxl=5, qxh=0, qyl=5, qyr=0, alt[  ]={-2, 0, -2, 0};
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
char *titolo=const_cast<char *>("questo est un titolo"),
*solo = const_cast<char *>("solo questo appare");
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mquotature_ps(&qxl, &qxh, &qyl, &qyr, alt),
i = 1,
mscrivi_ps(titolo, r, r+2),
mcontorno_ps(&i),
qxh = 2,
mmarca_ps(&qxh),
mcancella_ps(&i, &qxh, &qyr),
mtitoli_ps(solo, solo, solo, &i),
mfine_ps(  );}

N.B.: Questo programma è fornito come esempio d'uso di mcancella_ps e mmarca_ps.
In sostanza identico a quello dato come esempio di mcontorno_ps, se ne distingue per l'inserimento di una chiamata a mmarca_ps immediatamente dopo quella a mcontorno_ps e di una chiamata a mcancella_ps subito dopo.
L'effetto consiste nell'annullare tutto quanto era stato fatto per cui l'unica cosa che resterà saranno i titoli eseguiti dall'ultima chiamata a mtitoli_ps.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

































































































mscalelogaritmiche_ps(s)

Permette di introdurre scale logaritmiche; s è un array (INTEGER*4/int) di due elementi, il primo per l'asse orizzontale e il secondo per l'asse verticale; il valore 0 (default) di ciascuna componente indica che il corrispondente asse è lineare, mentre qualsiasi valore non nullo lo fa diventare logaritmico.

La funzione è efficace SOLO SE chiamata prima di mfinestra_ps relativamente allo stesso file (naturalmente già aperto).

I valori degli argomenti successivamente trasferiti a mfinestra_ps devono continuare a essere quelli naturali (e NON I LORO LOGARITMI se sono state chieste scale logaritmiche).

È RESPONSABILITÀ DEL PROGRAMMA CHIAMANTE CHE LE COORDINATE PLOTTATE SU UN ASSE LOGARITMICO SIANO SEMPRE POSITIVE. NESSUN TEST VIENE FATTO A TAL PROPOSITO.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, s[  ]={0,1};
double r[  ]={0.5, 0.66666, 1.0, 1.3333333, 1.5, 2.0},
scala = 1.0, sf = 1.0,
xmin = 0.0, ymin = 1.0, xmax = 1.0, ymax = 1000.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
for(i=0; i < 6; i++) mrapporto_assi(&i, &r[i]);
minizio_ps(args[1], &scala, &sf),
mscalelogaritmiche_ps(s),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mfinestra_ps e come tale non fa assolutamente nulla se non una pagina vuota. Serve solo a mostrare come si definisce l'intenzione di avere un grafico in scala semilogaritmica sull'asse y.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































mmuovi_ps(x)

Sposta il punto corrente del file PostScript nella posizione x (vettore con 2 elementi REAL*8/double), espressa in coordinate utente, senza produrre output grafico.

Serve a iniziare qualsiasi operazione di effettivo output grafico che non sia la semplice scrittura di caratteri e/o il tracciamento di sistemi di riferimento con o senza quotature (cfr. mlinea_ps e mpunto_ps).

Le coordinate fornite in x possono anche cadere al di fuori della regione di clipping (mcontorno_ps).

Esempio d'uso: cfr. mlinea_ps


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































mlinea_ps(x)

Traccia una linea retta nel tratteggio attuale (cfr. mtratteggio_ps) partendo dal punto corrente fino alla posizione x (vettore di due elementi REAl*8/double) data in coordinate utente.
Il punto x diventa altresì il nuovo punto corrente.

La parte di linea che eventualmente cada fuori dell'area di clipping (mcontorno_ps) NON VIENE TRACCIATA.

Può essere chiamata SOLO dopo un'altra chiamata di mlinea_ps oppure dopo una chiamata a mmuovi_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, s[  ]={0,1};
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 1.0, xmax = 1.0, ymax = 1000.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mscalelogaritmiche_ps(s),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = pow(10.0, 3*x[0]),
mmuovi_ps(x);
for(i=1; i < 101; i++)
x[0] = (double)i / 100.0,
x[1] = pow(10.0, 3*x[0]),
mlinea_ps(x);
mfine_ps(  );}

N.B.: Questo programma è fornito come esempio simultaneo d'uso di mlinea_ps e mmuovi_ps.
Traccia un grafico in scala semilogaritmica della funzione 10^(3x) senza né contorno né titoli né quotature.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mspessore_linea_ps(f)

Moltiplica per f (REAL*8/double) lo spessore con cui vengono tracciate TUTTE le linee, compresi i vettori; l'effetto è cumulativo, nel senso che due chiamate successive con argomenti f1 e f2 hanno lo stesso risultato di un'unica chiamata con argomento f1*f2.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, s[  ]={0,1};
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 1.0, xmax = 1.0, ymax = 1000.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mscalelogaritmiche_ps(s),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
x[0] = xmin, x[1] = pow(10.0, 3*x[0]),
mmuovi_ps(x),
sf = 3.0, mspessore_linea_ps(&sf);
for(i=1; i < 101; i++)
x[0] = (double)i / 100.0,
x[1] = pow(10.0, 3*x[0]),
mlinea_ps(x);
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mlinea_ps ma con l'aggiunta del contorno. Traccia lo stesso grafico con una linea 3 volte più spessa.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mgiunzione_linee_ps(modo)

Questa funzione esegue, per il file PostScript correntemente aperto, le stesse operazioni svolte da m_how_join_lines per la finestra grafica. Si rimanda a tale sezione per le spiegazioni.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mpunto_ps(x)

Marca con il simbolo attuale (cfr. msimbolo_ps) il punto le cui coordinate utente sono contenute nel vettore x (di due elementi REAL*8/double).
Il punto x diventa altresì il nuovo punto corrente.

Se x cade fuori dell'area di clipping (mcontorno_ps) il punto NON VIENE MARCATO.

Prima della prima chiamata di mpunto_ps occorre una chiamata a mmuovi_ps (o a mlinea_ps).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, s[  ]={0,1};
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 1.0, xmax = 1.0, ymax = 1000.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mscalelogaritmiche_ps(s),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
x[0] = xmin, x[1] = pow(10.0, 3*x[0]),
mmuovi_ps(x);
for(i=1; i < 101; i++)
x[0] = (double)i / 100.0,
x[1] = pow(10.0, 3*x[0]),
mpunto_ps(x);
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mlinea_ps ma con l'aggiunta del contorno. Traccia lo stesso grafico marcato per punti.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































msimbolo_ps(n)

Seleziona l'n-esimo (n = INTEGER*4/int) simbolo, tra un certo numero di simboli predefiniti, per il marcamento di punti isolati tramite mpunto_ps.

I valori accettabili di n sono compresi tra 0 e 41 (inclusi). Il valore 0 è il default e corrisponde al singolo dot.

Se si attribuisce, per la prima volta, un valore fuori intervallo si intende che si vuole creare un simbolo personalizzato; in questo caso l'argomento n deve puntare a un intero array di interi; il primo elemento determina quanti sono, al massimo, gli elementi che seguono: se è negativo devono seguire abs(n) ulteriori elementi; se è maggiore di 41 devono seguire n-41 elementi.
Ad ogni modo la libreria smette di leggere il puntatore al primo elemento incontrato il cui valore assoluto superi la capienza numerica di un unsigned char.
Il numero di elementi successivi al primo dovrebbe essere pari; se non lo è l'ultimo elemento valido viene considerato due volte consecutive.
Gli elementi del puntatore, presi a coppie, indicano gli spostamenti relativi del path del simbolo che si sta creando a partire dal punto che si vuole marcare.
Se il primo elemento di n era negativo il simbolo creato viene utilizzato immediatamente come simbolo pieno, altrimenti come simbolo vuoto.
Una volta che il simbolo è stato creato vi si può fare ulteriore riferimento eseguendo msimbolo_ps con argomenti 42 o 43 (rispettivamente simbolo vuoto o simbolo pieno).
Per azzerare il simbolo creato (condizione necessaria per crearne uno nuovo) occorre chiamare "a salve" msimbolo_ps con argomento negativo.
Ogni altro valore fuori intervallo (e.g. n = 64) attribuito a msimbolo_ps quando il simbolo personalizzato è già stato creato per il file in corso comporta come effetto l'uso del simbolo default (dot).
Il simbolo selezionato resta ovviamente in vigore finché non si fa una nuova chiamata di msimbolo_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, s[  ]={0,1};
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 1.0, xmax = 1.0, ymax = 1000.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mscalelogaritmiche_ps(s),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
x[0] = xmin, x[1] = pow(10.0, 3*x[0]),
mmuovi_ps(x);
for(i=1; i <= 42; i++)
x[0] = (double)i / 52.0,
x[1] = pow(10.0, 3*x[0]),
s[0] = i - 1,
msimbolo_ps(&s[0]),
mpunto_ps(x);
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mpunto_ps ma con i punti marcati con tutti i 42 simboli disponibili (nell'ordine dal basso a sinistra).




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mripristina_grandezza_simbolo_ps(  )

Funzione senza argomenti e di cui non si ritiene necessario fornire un esempio d'uso. Serve a riportare al valore iniziale la grandezza dei simboli tracciati per il file PostScript correntemente attivo, annullando l'effetto di ogni precedente esecuzione della funzione mgrandezza_simbolo_ps per lo stesso file.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


















































































mgrandezza_simbolo_ps(f)

Moltiplica per f (numero puro REAL*8/double) la grandezza corrente con cui sono disegnati i simboli definiti e scelti tramite la funzione msimbolo_ps.
L'effetto è cumulativo, il che significa che due successive chiamate con argomenti f1 e f2 hanno lo stesso effetto di una sola chiamata con argomento f1*f2.
Nessun test viene fatto sul valore di f: in particolare nessuna protezione contro valori non positivi è garantita.

La grandezza di default dei simboli è ragionevole, secondo il parere dell'autore della libreria, quando il parametro scala fornito a minizio_ps vale 1.0.

I simboli num. 0, 1 e quelli "numerici" sono insensibili a questa funzione (come accade anche per m_symbol).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, s[  ]={0,1};
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 1.0, xmax = 1.0, ymax = 1000.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mscalelogaritmiche_ps(s),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
x[0] = xmin, x[1] = pow(10.0, 3*x[0]),
sf = 3.0, mgrandezza_simbolo_ps(&sf),
mmuovi_ps(x);
for(i=1; i <= 26; i++)
x[0] = (double)i / 52.0,
x[1] = pow(10.0, 3*x[0]),
s[0] = i - 1,
msimbolo_ps(&s[0]),
mpunto_ps(x);
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di msimbolo_ps ma con i simboli più grandi del normale per un fattore 3.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mtratteggio_ps(n)

seleziona l'n-esimo (n = INTEGER*4/int) tipo di tratteggio, tra un certo numero di tratteggi predefiniti, per il tracciamento di linee tramite mlinea_ps.

I valori accettabili di n sono compresi tra 0 e 15 (inclusi).
Il valore 0 è il default e corrisponde alla linea continua; valori crescenti di n corrispondono a tratteggi via via più lunghi partendo da una linea punteggiata (n=1).

Se si attribuisce un valore fuori intervallo significa che si intende fornire un tratteggio personalizzato.

In tal caso, come accade per m_dash, n deve puntare a un intero array di interi strettamente positivi.

La lettura degli elementi del puntatore successivi al primo termina quando si sono letti 8 elementi o al primo zero incontrato. I valori così forniti non hanno limite superiore e sono interpretati come nel caso di m_dash.

Il tratteggio selezionato resta in vigore per tutte le linee finché non si fa una nuova chiamata di mtratteggio_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i;
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i);
for(i=0; i <= 8; i++)
x[1] = ((double)i + 1.0)/ 12.0,
x[0] = xmin,
mtratteggio_ps(&i),
mmuovi_ps(x),
x[0] = xmax,
mlinea_ps(x);
mfine_ps(  );}

N.B.: Questo programma mostra 9 tratteggi standard (dal basso in alto).




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































mcolore_ps(n)

Cambia il colore di tracciamento di checchessia (escluse eventuali bitmaps) ponendolo uguale a quello numero n all'interno di una tavolozza predefinita. n è un intero (INTEGER*4/int) qualsiasi.

Il colore selezionato resta in vigore fino a una successiva chiamata alla stessa mcolore_ps oppure a mcolore_rgb_ps o a mcolore_hcv_ps.

I valori dell'argomento n sono interpretati come segue:

n = 0 (default) --> nero
n = 3 --> giallo
n = 1 --> rosso
n = 6 --> cyan
n = 2 --> verde
n = 5 --> magenta
n = 4 --> blu
n = 7 (cancellazione) --> bianco

n > 7 --> nero (default)

Se n < 0 il suo valore viene usato come codifica RGB di un colore attribuendo il contenuto dei 30 bits meno significativi come intensità dei tre colori fondamentali R (bits 29-20), G (bits 19-10) e B (bits 9-0).

Su stampanti in bianco nero la scelta di un colore comporta una tonalità di grigio.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i;
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i);
for(i=0; i <= 7; i++)
x[1] = ((double)i + 1.0)/ 12.0,
x[0] = xmin,
mcolore_ps(&i),
mmuovi_ps(x),
x[0] = xmax,
mlinea_ps(x);
mfine_ps(  );}

N.B.: Questo programma mostra gli 8 colori standard (dal basso in alto), compreso il bianco che, ovviamente, non si vede se non per i due piccoli "buchi" che produce sul contorno.





torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































mcolore_rgb_ps(rosso, verde, blu, colore)

Serve a definire un colore attraverso le sue componenti RGB per produrre stampe a colori.

Gli argomenti rosso, verde e blu sono dei REAL*8/double il cui valore compreso tra 0 (intensità nulla) e 1 (intensità massima) indica l'intensità della corrispondente componente di colore.

Nessun test viene fatto sul valore attribuito a questi tre argomenti.

Dopo la chiamata di questa funzione OGNI COSA (eccetto eventuali bitmaps) viene disegnata nel colore indicato fino a una successiva chiamata alla stessa mcolore_rgb_ps oppure a mcolore_hcv_ps o a mcolore_ps. Su stampanti in bianco e nero ciò comporta delle tonalità di grigio.

L'argomento colore è un INTEGER*4/int che contiene in uscita la codifica intera del colore richiesto e può essere riutilizzato come argomento di chiamata della funzione mcolore_ps per ottenere lo stesso risultato.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, c;
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
scala = 0.8, sf = 0.8, x[0] = 0.4,
mcolore_rgb_ps(&scala, &sf, &x[0], &c);
for(i=0; i <= 100; i++)
x[1] = ((double)i + 1.0)/ 100.0,
x[0] = xmin,
mmuovi_ps(x),
x[0] = xmax,
mlinea_ps(x);
mfine_ps(  );}

N.B.: Questo programma mostra un gran numero di linee orizzontali disegnate con un colore non standard (una sorta di verde oliva).



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mcolore_hcv_ps(hue, chroma, val, col)

Serve a definire un colore attraverso le sue componenti HCV per produrre stampe a colori.

Gli argomenti hue, chroma e val sono dei REAL*8/double il cui valore compreso tra 0 (intensità nulla) e 1 (intensità massima) indica l'intensità della corrispondente componente di colore.

Valori fuori intervallo di chroma e val sono ricondotti all'estremo più vicino dell'intervallo stesso.
Valori fuori intervallo di hue sono riportati all'interno modulo 1.

Dopo la chiamata di questa funzione OGNI COSA (eccetto eventuali bitmaps) viene disegnata nel colore indicato fino a una successiva chiamata alla stessa mcolore_hcv_ps oppure a mcolore_rgb_ps o a mcolore_ps. Su stampanti in bianco e nero ciò comporta delle tonalità di grigio.

L'argomento col è un INTEGER*4/int che contiene in uscita la codifica intera del colore richiesto e può essere riutilizzato come argomento di chiamata della funzione mcolore_ps per ottenere lo stesso risultato.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, c;
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
scala = 0.8, sf = 0.8, x[0] = 0.4,
mcolore_hcv_ps(&scala, &sf, &x[0], &c);
for(i=0; i <= 100; i++)
x[1] = ((double)i + 1.0)/ 100.0,
x[0] = xmin,
mmuovi_ps(x),
x[0] = xmax,
mlinea_ps(x);
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mcolore_rgb_ps. Si noti come lo stesso dato produca un colore completamente diverso (una sorta di color prugna).


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



































































































msfondo_ps(rosso, verde, blu)

Colora lo sfondo della regione di "clipping" (cfr. mcontorno_ps) con il colore dato dalle componenti RGB rosso, verde, blu.
I tre argomenti sono dei REAL*8/double compresi tra 0.0 e 1.0 (cfr. anche mcolore_rgb_ps). Può essere chiamata solo dopo che la regione di "clipping" sia stata definita e quindi solo dopo mfinestra_ps e una sola volta per ogni file PostScript aperto.
Se viene chiamata dopo che qualcosa è già stato disegnato quel qualcosa risulta non più visibile, pur restando il codice che lo riproduce inserito nel file PostScript.
In questo senso la funzione non va interpretata come un modo per cancellare dei disegni, per la qual bisogna esistono già le funzioni mmarca_ps e mcancella_ps.
Non esiste una funzione per colorare lo sfondo attribuendo il colore con le componenti HCV.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i;
double scala = 1.0, sf = 1.0, x[2],
xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
scala = sf = x[0] = 0.6,
msfondo_ps(&scala, &sf, &x[0]),
i = 1, mcontorno_ps(&i),
mfine_ps(  );}

N.B.: Questo programma si limita a colorare di grigio chiaro la regione di "clipping". Si noti che la chiamata a mcontorno_ps, allorché traccia qualcosa, come nel corrente esempio, deve seguire e non precedere msfondo_ps se si vuole evitare che quanto disegnato da mcontorno_ps risulti invisibile.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































mfreccia_ps(x, vect, a, n)

Disegna un vettore applicato in x (vettore di due elementi REAL*8/double) e di componenti vect (vettore di due elementi REAL*8/double).

Entrambi gli argomenti sono in coordinate utente: si sottolinea in particolare che vect NON È il versore del vettore in questione come invece avviene per la funzione m_vector usata per grafica a schermo.

I due ulteriori argomenti a (REAL*8/double) e n (INTEGER*4/int) servono a definire la forma della punta della freccia: precisamente a ne definisce la lunghezza (in millimetri) e n l'apertura angolare (in gradi).

Nessun test viene fatto sul valore degli argomenti.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n = 30;
double scala = 1.0, sf = 1.0, x[2], v[2], a = 4,
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i);
for(i=0; i < 10; i++)
x[0] = 0.5*cos(0.2*M_PI*i), x[1] = 0.5*sin(0.2*M_PI*i),
v[0] = -0.5*x[1], v[1] = 0.5*x[0],
mfreccia_ps(x, v, &a, &n);
mfine_ps(  );}

N.B.: Questo programma traccia un campo vettoriale di modulo 1/4 tangente al cerchio di raggio 1/2.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mellisse_ps(x, ax, modo, rot)

Serve a tracciare un'ellisse di centro x (vettore di due double/REAL*8) e semiassi ax (vettore di due double/REAL*8).
Entrambi i vettori sono da dare in coordinate utente e le due componenti di ax DEVONO essere positive.

I due ultimi argomenti sono degli interi (int/INTEGER*4).

Se modo = 0 viene solo tracciato il perimetro dell'ellisse (col tratteggio e il colore corrente); altrimenti viene disegnata un'ellisse piena (nel colore corrente).

L'argomento rot indica infine l'angolo di rotazione (in gradi) della prima componente del vettore ax rispetto all'orizzontale orientata verso destra.

NON SI PUÒ USARE SU GRAFICI LOGARITMICI.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n = 30, a = 0;
double scala = 1.0, sf = 1.0, x[2], v[2],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
x[0] = x[1] = 0.0,
v[0] = 0.25, v[1] = 0.33,
mellisse_ps(x, v, &a, &n),
x[0] = -0.75, a = 1, n = 0, v[1] = v[0],
mcolore_ps(&i),
mellisse_ps(x, v, &a, &n),
mfine_ps(  );}

N.B.: Questo programma traccia un'ellisse vuota e inclinata di 30° (col centro nell'origine) e un cerchio pieno di colore rosso centrato in (-3/4, 0).



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"









































































































mbersaglio_ps(configurazione, settori, colori, stringhe)

Questa funzione si sarebbe potuta scrivere da parte di ogni utente evoluto della libreria, dato che, tutto sommato, è un semplice involucro per altre funzioni: infatti disegna quel che gli angloamericani chiamano pie chart e che qui si preferisce chiamare diagramma circolare, quando non "bersaglio delle freccette" (da cui il nome attribuito alla funzione).

L'argomento configurazione è un array/puntatore a double/REAL*8 che contiene un numero variabile di elementi, almeno 5 affinché si possa ottenere qualcosa di sensato: la funzione CESSA di utilizzarlo appena vi trova un valore negativo dal quinto posto in avanti, che quindi DEVE esservi presente in quanto funge da terminatore.

Osservazione:
non viene effettuato alcun controllo da parte della funzione sul contenuto di configurazione: si usa quel che vi si trova. Qui appresso si dànno alcuni esempi di possibili contenuti, con le conseguenze che ne derivano.

Contenuto 1:
-1.0 2.0 1.0 1.0 -0.5 -----------> perfettamente sensato

Contenuto 2:
-1.0 2.0 -1.0 1.0 -0.5 -----------> insensato: rischio di interruzione del programma

Contenuto 3:
-1.0 2.0 1.0 -1.0 -0.5 -----------> insensato: equivale a NESSUNA OPERAZIONE

Contenuto 4:
1.0 2.0 -----------> insensato: "Segmentation Fault" dietro l'angolo

Fine osservazione.

Il contenuto di configurazione viene interpretato come segue: i primi due elementi, OBBLIGATORIAMENTE PRESENTI, sono usati come coordinate orizzontale e verticale rispettivamente, e specificate nel sistema dell'utente, del centro del diagramma circolare, come avviene quando si voglia tracciare un cerchio con altre primitive della libreria: come tali possono entrambi avere qualsiasi segno; il terzo elemento, OBBLIGATORIAMENTE PRESENTE e OBBLIGATORIAMENTE e STRETTAMENTE POSITIVO e RAGIONEVOLE, indica il rapporto d'aspetto del diagramma: un valore pari a 1 lo disegna esattamente circolare, minore di 1 lo disegna schiacciato in verticale e viceversa se maggiore di 1. Chi fornirà per questo argomento valori del tipo 0.00000000000000001 o 1.e+21, affermando che sono entrambi strettamente positivi, sarà appeso al muro per i tendini d'Achille, a causa della mancanza di ragionevolezza.
Gli elementi dal quarto in poi, fino a incontrare il terminatore negativo, sono interpretati come raggi, nelle unità dell'utente, di ellissi concentriche nel punto indicato dai primi due elementi; ed ecco perché occorre che configurazione contenga almeno cinque elementi. In questo modo è possibile realizzare anche diagrammi sovrapposti nella stessa figura e non solo diagrammi eventualmente giustapposti uno accanto all'altro.
Sarebbe opportuno che i raggi, qualora in numero superiore a uno solo, siano inseriti nel contenitore in ordine decrescente di grandezza, altrimenti i cerchi non saranno TUTTI visibili a causa dell'opacità del linguaggio PostScript; lo stesso discorso vale per la grafica a schermo, salvo il fatto che venga utilizzata la funzione m_opacity. Si ribadisce che la funzione non esegue alcun controllo sull'ordinamento dei raggi, e del resto, in una condizione di lavoro minimale, è frequente che si finisca per fornire un raggio solo.

L'argomento settori è un puntatore a puntatori/array di array dello stesso tipo di configurazione e, come dice il suo nome, serve a fornire alla funzione informazioni sull'ampiezza degli spicchi da inserire nel diagramma: per chi ha qualche dimestichezza con la sfera di Riemann si potrebbe dire che, mentre configurazione ne dà una descrizione dei paralleli, settori dà un'informazione simile relativamente ai meridiani.

L'informazione fornita da settori è alquanto strutturata, e consente una gestione molto fine del disegno del diagramma: tanto per cominciare l'estensione della memoria occupata da questo argomento, al primo livello di puntamento (il più esterno) deve essere almeno pari al numero di raggi effettivi inseriti nel puntatore configurazione; in parole povere se N >= 1 è il numero di raggi inseriti in configurazione, settori deve puntare ALMENO N puntatori, che saranno rispettivamente utilizzati per ciascuno dei cerchi, quindi in maniera totalmente indipendente uno dall'altro.

Ognuno dei puntatori indirizzati da settori che fosse inizializzato come puntatore nullo comporta che il corrispondente cerchio sia totalmente ignorato nel disegno del diagramma: grazie a questa caratteristica è possibile utilizzare questi puntatori come variabili booleane che decidono se disegnare o no un cerchio in base all'esito di qualsivoglia procedura svolta all'interno del programma; va da sé che se TUTTI i puntatori contenuti in settori fossero nulli si ricadrebbe in una sindrome di NESSUNA OPERAZIONE.

Ciascuno dei puntatori NON nulli puntati da settori punta a sua volta un numero variabile di elementi di tipo double/REAL*8: la funzione considera come terminatore dell'area di memoria puntata un valore negativo minore di -2.1.

I valori non negativi presenti nell'area di memoria puntata vi dovrebbero essere inseriti in ordine crescente, senza che la funzione lo controlli in alcun modo: rappresentano i valori angolari, espressi in gradi sessagesimali e frazioni, dell'inizio di ogni spicchio da disegnare nel cerchio ordinalmente corrispondente al puntatore. Quando si dice gradi sessagesimali e frazioni s'intende, ad esempio, che il valore 30.51 indica un angolo di 30 gradi, 30 primi e 36 secondi di grado; l'origine degli angoli è posta, secondo consuetudine, lungo la semiretta orizzontale destra.

I valori non negativi possono, opzionalmente, essere inframmezzati da NON PIÙ DI UN SOLO valore negativo e tale da non essere confuso col terminatore già citato, ancora una volta SENZA alcun controllo da parte della funzione; tali valori servono a interrompere, eventualmente, la consecutività degli spicchi e precisamente un valore che sia nell'intorno di -1 fa saltare uno spicchio, lasciando visibile, eventualmente, il cerchio sottostante, mentre un valore posto nell'intorno di -2 rende evidente la mancanza di un dato da riportare nello spicchio corrispondente, lasciando apparire addirittura il colore dello sfondo. Invece un valore posto nell'intorno di 0, e che non sia in prima posizione, viene interpretato come completamento del diagramma, nel senso che lo spicchio che terminerebbe con tale valore viene ricongiunto con il primo spicchio specificato, indipendentemente da dove questo sia stato fatto iniziare.

Osservazione per i fortranisti (ahiloro)
Chi si ostinasse a utilizzare il linguaggio fortran si ricordi che, a meno di evoluzioni previste nelle ultime nefande versioni di un linguaggio da dimenticare, non si possono far puntare aree di memoria di diversa lunghezza a puntatori di secondo livello; pertanto occorrerà riservare quella più ampia che risultasse necessaria. Inoltre, quando si parla di "livello di puntamento più esterno", si ricorda che nel fortran la convenzione adottata è opposta (e SBAGLIATA) rispetto a quella (GIUSTA) del C/C++, per cui quello che in C/C++ è, correttamente, x[2][5] diventa, in fortran, astrusamente, x(5,2).
Fine osservazione.

Esempi di contenuto di uno dei puntatori NON NULLI di settori:

Esempio 1:
0 0 -3
(disegna un cerchio di un solo spicchio, da 0 a 360 gradi [equivalente a 0 360 -3, o anche a QUALSIASI valore positivo in prima posizione e 0 in seconda]; non bastava usare la funzione che disegna direttamente i cerchi?)

Esempio 2:
15 120 270 0 -3
(disegna TRE spicchi: il primo da 15 a 120 gradi, il secondo da 120 a 270 e il terzo da 270 a 15; naturalmente per vederli occorrerà che non siano coperti da altri cerchi di raggio maggiore e, OVVIAMENTE, che NON siano tutti dello stesso colore...)

Esempio 3:
0 120 270 300 -3
(anche questo disegna TRE spicchi: il primo da 0 a 120 gradi, il secondo da 120 a 270 e il terzo da 270 a 300; gli ultimi 60 gradi restano vuoti e NON disegnati)

Esempio 4:
0 10 15 22 70 75 -1 90 111 125 150 225 270 0 -3
(disegna 11 spicchi: 1: da 0 a 10 gradi; 2: da 10 a 15; 3: da 15 a 22; 4: da 22 a 70; 5: da 70 a 75; 6: da 90 a 111; 7: da 111 a 125; 8: da 125 a 150; 9: da 150 a 225; 10: da 225 a 270; 11: da 270 a 360.
Lo spicchio tra 75 e 90 gradi viene saltato, lasciando trasparire l'eventuale cerchio sottostante)

Esempio 5:
0 10 -2 15 22 70 75 -1 90 111 125 150 225 270 0 -3
(Fermo restando quanto detto sull'esempio precedente, in questo viene saltato anche lo spicchio tra 10 e 15 gradi e al suo posto si lascia trasparire direttamente il colore dello sfondo, per quanti eventualmente siano i cerchi sottostanti. Appare ovvio che qualora si disegni UN SOLO cerchio la distinzione tra il valore -1 e il valore -2 perde ogni significato).

L'argomento colori ha la stessa natura di puntatore a puntatori/array di array dell'argomento precedentemente discusso, ma il tipo è int/INTEGER*4 e la topologia del puntamento è leggermente diversa.

Innanzitutto il numero di puntatori puntati al livello più esterno deve essere superiore di almeno un'unità rispetto a quello di settori: mantenendo il significato dei simboli, se settori punta N puntatori colori ne deve puntare N+1. I primi N di questi N+1 puntatori lavorano in sinergia rispettiva con quelli puntati da settori e, anche in questo caso, un eventuale puntatore nullo porta a ignorare il disegno del relativo cerchio, sicché esistono due vie per evitare che un certo diagramma sia disegnato.

Ogni puntatore NON nullo tra i primi N deve puntare almeno un numero di valori interi pari al numero di valori double puntati dal corrispondente puntatore di settori, se NON nullo a sua volta, diminuito dello spazio che, nei puntatori di settori, compete al terminatore (che qui non occorre) e di quello occupato dal numero di valori negativi eventualmente inseriti in quei puntatori, come spiegato quando se ne è sopra discusso.

Ogni valore inserito viene interpretato come l'indice del colore con cui disegnare lo spicchio corrispondente, quando effettivamente disegnato, secondo le sintassi proprie delle funzioni m_color e mcolore_ps di questa stessa libreria.

Il puntatore N+1-esimo, che mai può essere nullo, DEVE puntare almeno UN valore intero: se quel valore è -2 (e NULL'altro) per questa funzione, ovvero qualsiasi valore negativo per m_target, equivale a nessuna ulteriore operazione. In caso contrario vengono tracciati i bordi di tutti gli spicchi disegnati, nel colore il cui indice corrisponde al valore puntato da quest'ultimo puntatore.

L'ultimo argomento stringhe, come dice il suo stesso nome, è un puntatore a puntatori a puntatori a char. I fortranisti è meglio che lo inizializzino al puntatore NULLO, che comporta nessuna operazione. Per chi scrive in C/C++ ogni puntatore non nullo al terzo livello di puntamento comporta la scrittura dei caratteri puntati (meglio se MOOOOOLTO pochi) in una posizione pressoché centrale rispetto allo spicchio cui quel puntatore compete. Si sottintende che la struttura topologica di stringhe coincida con quella di colori per i primi due livelli di puntamento. I caratteri eventualmente scritti appaiono nel fonte di caratteri corrente e nel colore dello sfondo del diagramma. Questo argomento non va abusato, dato che qualunque beota capisce che per diagrammi con spicchi molto sottili si rischia di avere disegni con scritte incomprensibili.

Esempi d'uso:
1)

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{int K, L, M, **colori;
double raggi[5], **settori, x[  ]={-1.0, -1.0, 1.0, 1.0};
char ***s;
m_startg(const_cast<char *>(""), &(K=600), &(L=600)),
m_window(&(K=((255 << 16) + (112 << 8) + 112) | OMBREGGIA_FINESTRA), &(L=0)),
m_frame(x, x+1, x+2, x+3);
raggi[4] = -3.0, raggi[0] = raggi[1] = 0.0, raggi[2] = 1.0, raggi[3] = 0.9;
settori = new double*, colori = new int*[2];
settori[0] = new double[5], colori[0] = new int[3];
colori[1] = new int{0};
settori[0][0] = 15,
settori[0][1] = 110,
settori[0][2] = 240,
settori[0][3] = 0,
settori[0][4] = -3.0,
colori[0][0] = 1, colori[0][1] = 4, colori[0][2] = 5,
s = new char**,
s[0] = new char * [3]
{const_cast<char*>("A"), const_cast<char*>("B"), const_cast<char*>("C")},
m_target(raggi, settori, colori, s),
m_redraw(&(K=0)),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}


Il programma precedente realizza un semplice diagramma circolare con tre spicchi etichettati con le lettere A, B e C evidenziate nel colore di sfondo. Nel file PostScript ombra sono distintamente visibili i bordi neri degli spicchi, meno visibili sullo schermo a causa della sottigliezza delle linee.

2)


# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{int K, L, M, **colori;
double
raggi[20], **settori,
x[  ]={-1.0, -1.0, 1.0, 1.0},
h, c = 1.0, v = 1.0;
m_startg(const_cast<char *>(""), &(K=600), &(L=600)),
m_window(&(K=OMBREGGIA_FINESTRA), &(L=0)),
m_frame(x, x+1, x+2, x+3);
for(M=BIANCO; M >= NERO; --M) m_remove_color(&M);
for(M=0; M < 256; ++M) h = M/255.0, m_new_color_hcv(&h, &c, &v, &(L=1), x);
raggi[19] = -3.0, raggi[0] = raggi[1] = 0.0, raggi[2] = 1.0;
for(M=3; M < 19; ++M) raggi[M] = (21.0-M) / 20.0;
settori = new double*[16], colori = new int*[17];
for(M=0; M < 16; ++M) settori[M] = new double[18], colori[M] = new int[16];
colori[16] = new int{-2};
for(M=0; M < 16; ++M)
{for(L=0; L < 16; ++L) settori[M][L] = L * 22.5, colori[M][L] = 16*M+L;
settori[M][L] = 0; settori[M][L+1] = -3.0;}
m_target(raggi, settori, colori, 0),
m_redraw(&(K=0)),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}


Il programma precedente disegna un bersaglio arcobaleno, e come tale non ha etichette né bordi; si lascia ai lettori la facoltà di trovare un algoritmo di assegnazione dei colori che eviti l'apparente discontinuità sui cerchi. Anche in questo caso è stato allestito un file PostScript ombra.

3)

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int K, L, i, **col = new int*[4] {
new int[13]{0, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 1},
// nullptr, // cerchio esterno
new int[15]{4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6},
//nullptr, // cerchio medio
new int[15]{1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 0},
//nullptr, // cerchio interno
new int{-1} // "terminatore"
};
char *** str = new char**[3] {
nullptr,
nullptr,
new char*[15]
{nullptr, nullptr, nullptr, nullptr, const_cast<char*>("S"),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, const_cast<char*>("A"), nullptr, nullptr, nullptr}
};
double scala = 1.0, sf = 1.0, x[7],
**settori=new double*[3] {
new double[15]{0, 10, 15, 22, 70, 75, -1, 90, 111, 125, 150, 225, 270, 0, -3},
//nullptr, // cerchio esterno
new double[14]{0, 10, 15, 22, 70, 75, 90, 111, 125, 150, 225, 270, 0, -3},
//nullptr, // cerchio medio
new double[17]{0, 10, -1, 15, 22, 70, 75, 90, 111, 125, -2, 150, 225, 270, 280, 0, -3}
//nullptr // cerchio interno
},
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 2) printf("devi fornire un nome di file\n"), exit(0);
m_startg(const_cast<char*>(""), &(K=600), &(L=600)),
m_window(&(K=OMBREGGIA_FINESTRA), &(L=0)),
m_frame(&xmin, &ymin, &xmax, &ymax),
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
x[1] = x[0] = 0.15, x[2] = 1.0,
x[3] = 0.75,
x[4] = 0.65,
x[5] = 0.55,
x[6] = -1.0,
m_target(x, settori, col, str),
mindirizza_ps(args[1]),
mbersaglio_ps(x, settori, col, str),
mchiudi_ps(args[1]),
mindirizza_ps(const_cast<char*>("implicito_PS_1")),
m_wait_for_events(&(K=EVENTO_ENTER)),
m_endg(  );}


Il programma precedente, oltre al solito file PostScript ombra, ne crea uno esplicitamente, di uguale contenuto: si apprezzino gli effetti dei valori negativi inseriti nel secondo argomento e la possibilità di etichettare selettivamente i diversi spicchi. Inoltre, secondo la memoria dell'autore, questo è l'unico codice esempio in cui si mostra la gestione simultanea di files PostScript ombra assieme a files PostScript, per così dire, autonomi. Nel codice sono presenti dei puntatori nulli commentati, nei punti in cui possono sostituire lecitamente quelli non nulli: si invitano i lettori a sperimentare il diverso comportamento della funzione descritto in queste stesse note.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


























































































































m_target(configurazione, settori, colori, stringhe)

Questa funzione è la controparte di mbersaglio_ps per quanto concerne la grafica a schermo: funziona esattamente alla stessa maniera e con lo stesso significato degli argomenti; pertanto, essendo sufficiente solo il cambio del nome della funzione, si rimanda colà per le spiegazioni.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































































marco_ps(x, ax, modo, s, rot)

Questa funzione è complementare a mellisse_ps e serve a disegnare un settore ellittico invece di un'ellisse intera.
Gli argomenti x, ax, modo e rot hanno significato e tipo identici a quelli degli omonimi argomenti di mellisse_ps (cui si rinvia per la spiegazione).

L'argomento aggiuntivo s, inserito in penultima posizione, ha lo stesso scopo dell'omonimo argomento fornito all'omologa funzione a schermo m_arc, ma se ne differenzia per quanto segue:

  1. ha due sole componenti, invece di tre.

  2. il secondo elemento dell'array non rappresenta l'ampiezza angolare del settore bensì il valore dell'angolo finale (in altre parole non ha senso inserire in s due valori uguali, cosa perfettamente significativa per m_arc)

  3. Essendo ammissibili ellissi con assi obliqui va tenuto presente che l'origine rispetto a cui vengono calcolati i valori dei due elementi dell'array è quella del sistema di riferimento solidale con l'ellisse (l'esempio illustra meglio di qualsiasi discorso).



Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n = 30, a = 0;
double
scala = 1.0, sf = 1.0, x[2], v[2], s[2],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 2) printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
v[0] = 0.25, v[1] = 0.33,
x[0] = x[1] = 0.0,
s[0] = 90, s[1] = 180,
marco_ps(x, v, &a, s, &n),
x[0] = -0.75, a = 1, n = 0, v[1] = v[0],
mcolore_ps(&i),
s[0] = 45, s[1] = 360,
marco_ps(x, v, &a, s, &n),
mfine_ps(  );}

N.B.: Questo programma traccia due settori ellitici, uno vuoto e uno pieno; il primo appartiene a un'ellisse inclinata di 30°, col centro nell'origine ed eccentricità 0.25:0.33, e ha un'ampiezza di 90 gradi a partire dal semiasse verticale positivo dell'ellisse ruotata; il secondo appartiene a un cerchio di colore rosso centrato in (-3/4, 0) e ha un'ampiezza di 315 gradi a partire dalla diagonale del primo quadrante.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




































































































mpoligono_ps(x, n)

È la controparte PostScript della funzione a schermo m_polygon. Gli argomenti hanno significato identico e identica è la funzionalità.

Il limite per n è dato solo dalla capacità di memoria dell'interprete PostScript usato. Anche qui NESSUN CONTROLLO viene compiuto salvo l'invio su stdout di un breve messaggio nel caso in cui n < 3.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n = 3;
double scala = 1.0, sf = 1.0, x[6],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i),
x[0] = x[1] = 0.0, x[2] = -0.8, x[3] = 0.0,
x[4] = x[5] = -0.8,
i = 2, mcolore_ps(&i),
mpoligono_ps(x, &n),
mfine_ps(  );}

N.B.: Questo programma traccia un triangolo di colore verde coi vertici indicati.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mindirizza_ps(file)

Dopo questa chiamata il file file (CHARACTER*(*)/char *), che deve essere correntemente aperto, riceve ogni susseguente output fino alla successiva chiamata a mindirizza_ps o a una chiamata a minizio_ps per un nuovo file.

Se file non è correntemente aperto la chiamata viene ignorata e non produce quindi alcun effetto.

Chi programma in FORTRAN deve tenere conto di quanto detto a proposito delle variabili di tipo stringa (generalità, m_conv_string e m_conv_chars).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n = 3, a;
double scala = 1.0, sf = 1.0, x[6], v[2],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 3)
printf("devi fornire due nomi di files\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
minizio_ps(args[2], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i);
x[0] = x[1] = 0.0, x[2] = -0.8, x[3] = 0.0,
x[4] = x[5] = -0.8,
i = 2, mcolore_ps(&i),
mpoligono_ps(x, &n),
mindirizza_ps(args[1]),
i = 1, mcontorno_ps(&i),
x[0] = -0.75, a = 1, n = 0, v[1] = v[0] = 0.25,
mcolore_ps(&i),
mellisse_ps(x, v, &a, &n),
mfine_ps(  );}

N.B.: Questo programma usa due files distinti, il cui nome viene fornito sulla linea comando, per disegnare su ciascuno una figura diversa: un cerchio rosso sul primo file e un triangolo verde sul secondo. Si noti la chiamata a mindirizza_ps.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






































































































mchiudi_ps(file)

Serve a chiudere il file PostScript di nome file (CHARACTER*(*)/char *).

Con questa funzione tutti gli altri files aperti correntemente restano aperti mentre quello che è stato chiuso è pronto per la stampa.

Il numero di files correntemente aperti diminuisce di una unità e può quindi essere aperto un nuovo file con una chiamata a minizio_ps. Se file non è correntemente aperto la chiamata viene ignorata e non produce errore.

Chi programma in FORTRAN deve tenere conto di quanto detto a proposito delle variabili di tipo stringa (cfr. generalità, m_conv_string e m_conv_chars).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n = 3, a;
double scala = 1.0, sf = 1.0, x[6], v[2],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 3)
printf("devi fornire 2 nomi di files\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
minizio_ps(args[2], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i);
x[0] = x[1] = 0.0, x[2] = -0.8, x[3] = 0.0,
x[4] = x[5] = -0.8,
i = 2, mcolore_ps(&i),
mpoligono_ps(x, &n),
mindirizza_ps(args[1]),
i = 1, mcontorno_ps(&i),
x[0] = -0.75, a = 1, n = 0, v[1] = v[0] = 0.25,
mcolore_ps(&i),
mellisse_ps(x, v, &a, &n),
mchiudi_ps(args[1]);}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mindirizza_ps, ma poiché la chiamata di mfine_ps è stata sostituita con mchiudi_ps(args[1]) solo il file chiamato args[1] può essere usato correttamente: l'altro potrà provocare errore se inviato a una stampante.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mqualefile_ps(i, l, file)

Restituisce nel puntatore i (INTEGER*4/int) l'indice (0<=i) del file PostScript che sta attualmente ricevendo output. Tale valore, aumentato di 1, è anche restituito dalla funzione come valore di ritorno in modo che valga 0 se la funzione è chiamata senza che nessun file PostScript sia correntemente attivo.

Il vettore di caratteri file (CHARACTER (  )/ char *) riceve, in caso positivo, il nome del file stesso (come dichiarato da minizio_ps) e il puntatore l (INTEGER*4/int) la lunghezza della stringa file (escluso il carattere di terminazione). Il programma chiamante è tenuto ad allocare sufficiente spazio per l'array file.

Per chi programma in FORTRAN si sottolinea che, in questo caso, poiché la variabile file non è una stringa, ma un vettore di caratteri, non si incorre nei problemi discussi in generalità.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int i, n = 3, a;
char *f;
double scala = 1.0, sf = 1.0, x[6], v[2],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 3)
printf("devi fornire 2 nomi di files\n"), exit(0);
f = (char *)malloc(64),
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
minizio_ps(args[2], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
i = 1, mcontorno_ps(&i);
x[0] = x[1] = 0.0, x[2] = -0.8, x[3] = 0.0,
x[4] = x[5] = -0.8,
i = 2, mcolore_ps(&i),
mpoligono_ps(x, &n),
printf("sto inviando output al file numero %d\n",
mqualefile_ps(&i, &n, f)),
printf("il cui nome est %s, di lunghezza %d\n", f, n),
mindirizza_ps(args[1]),
printf("ora invece lo invio al file numero %d\n",
mqualefile_ps(&i, &n, f)),
printf("il cui nome est %s, di lunghezza %d\n", f, n),
i = 1, mcontorno_ps(&i),
x[0] = -0.75, a = 1, n = 0, v[1] = v[0] = 0.25,
mcolore_ps(&i),
mellisse_ps(x, v, &a, &n),
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mchiudi_ps, con il ripristino della chiamata di mfine_ps; sono state solo aggiunte alcune istruzioni di output che esemplificano l'uso di mqualefile_ps.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

























































































mscrivi_ps(stringa, x, a)

Scrive la stringa di caratteri stringa a partire dalla posizione x (vettore di lunghezza 2 REAL*8/double) data in coordinate utente e con l'orientazione a (REAL*8/double) che rappresenta l'angolo in gradi misurato dalla normale direzione di scrittura dell'alfabeto latino (a=0).

Se chiamata da FORTRAN occorre tenere conto di quanto detto a proposito delle variabili di tipo stringa (cfr. generalità, m_conv_string e m_conv_chars).

Se è stata già chiamata mcontorno_ps i caratteri che eventualmente cadano fuori del contorno NON sono scritti.

Il fonte di caratteri usato è quello corrente (Helvetica se non è mai stata chiamata mfonte_ps).

È possibile scrivere stringhe miste contenenti anche caratteri greci presi dal fonte /Symbol: per far questo occorre usare il punto esclamativo come carattere di Escape.

Esempi di stringhe e loro significato:


cucu
{scrive cucu}

ab!c!def
{scrive i due caratteri latini ab, seguiti dai due greci 'chi' e 'delta', poi ancora dai latini ef}.


Per avere in stampa un punto esclamativo occorre metterne due consecutivi nella stringa, per cui n!! apparirà come il fattoriale di n mentre n!!!! sarà il semifattoriale e !n!! sarà il fattoriale di 'nu' greco.
Infine, in n!, il singolo punto esclamativo seguito da niente sarà ignorato.

L'argomento a viene usato anche per scegliere la giustificazione della stringa rispetto alle coordinate x; precisamente:


se 0 <= a < 360 la stringa è giustificata a sinistra
se 360 <= a < 720 la stringa è centrata in x
se 720 <= a la stringa è giustificata a destra.


Per ultimo, per avere in stampa il carattere usato come delimitatore della stringa stessa, ciascuno si rifaccia alle regole standard del linguaggio di compilazione adottato.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{double scala = 1.0, sf = 1.0, x[2], a = 0.0,
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
x[0] = 0.2,
x[1] = 1.6,
mscrivi_ps(const_cast<char *>("ab!c!def"), x, &a),
a = 360.0,
x[1] = 1.2,
mscrivi_ps(const_cast<char *>("ab!c!def"), x, &a),
a = 720,
x[1] = 0.8,
mscrivi_ps(const_cast<char *>("ab!c!def"), x, &a),
x[0] = xmin, x[1] = ymin, a = 90,
mscrivi_ps(const_cast<char *>("abcdef"), x, &a),
mfine_ps(  );}

N.B.: Questo programma mostra 4 esempi d'uso della funzione: i primi 3 riguardano le diverse possibili giustificazioni di una stringa mista (la coordinata x[0] è fissa (!)), l'ultimo la scrittura di una stringa in direzione verticale.
Si noti l'assenza della chiamata di mcontorno_ps, evitata per non avere problemi di clipping.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































mscrivi_quasi_come_TeX_ps(stringa, x, a)

Ha gli stessi argomenti (con lo stesso significato) di mscrivi_ps, ma in questo caso stringa può essere fornita con una sintassi simile a quella usata da TeX per realizzare esponenti e pedici in modo matematico ottenendo più o meno lo stesso effetto. Utile per realizzare captions di figure in cui compaiano espressioni matematiche.


La sintassi di TeX è rispettata parzialmente nel senso che:

Le precedenti combinazioni di due caratteri servono, come d'abitudine, a considerare il secondo carattere della combinazione come tale, senza tener conto del suo particolare significato per la funzione (cfr. sotto).

D'altra parte le analogie con TeX sono:



Una chiamata di questa funzione con l'argomento stringa che non contiene alcun carattere ^ né alcun carattere _ (underscore) equivale in tutto e per tutto a una chiamata a mscrivi_ps.

Ogni carattere ^ incontrato in stringa a partire dall'inizio provoca l'invio a esponente di TUTTI i caratteri che seguono, fino al successivo _ oppure al successivo carattere blank oppure alla successiva graffa.

Ogni carattere _ incontrato in stringa a partire dall'inizio provoca l'invio a pedice di TUTTI i caratteri che seguono, fino al successivo ^ oppure al successivo carattere blank oppure alla successiva graffa.

Ogni carattere blank incontrato in stringa a partire dall'inizio ripristina la baseline iniziale del gruppo cui appartiene, intendendosi per gruppo una sottostringa di stringa delimitata da parentesi graffe.

La funzione non segnala al presente eventuali errori sintattici, come sbilanciamento di parentesi e/o costrutti ambigui come a_b_c. Il loro esito in stampa è imprevedibile e potrebbe anche dar luogo a errori per l'interprete PostScript.


Esempi di stringhe e loro significato:

p^p_s
In questo esempio si ottiene "p" con pedice "s" ed esponente "p".

p_s^p
Identico al precedente.


pe^p_ps
In questo esempio si scrive una stringa "pe" con un esponente "p" e con un pedice costituito dalla stringa "ps".


!pe^!p_!p!s
Questo esempio è identico al precedente, salvo il fatto che la stringa "pe" ha il carattere iniziale in greco, è elevata a pi greco e ha un pedice costituito dalle lettere greche pi e sigma.


x^2 +y^2
In questo esempio si ottiene la scrittura della somma dei quadrati di x e y. Si noti il carattere blank dopo il primo 2 in stringa. In assenza di tale carattere, come in
x^2+y^2
si sarebbe avuto un costrutto ambiguo (doppio esponente, il primo "2+y" e il secondo "2").


p^{x^2 +y^2}
In questo esempio si ottiene "p" elevato alla somma dei quadrati di "x" e "y"; si noti ancora il blank dopo l'esponente di "x".


p^{\{n_i\}}
In questo esempio si ottiene "p" elevato a un esponente racchiuso tra parentesi graffe. L'esponente è la stringa "n" con pedice "i".


p^\\
In questo esempio si ottiene "p" elevato a una backslash.


scrivo\ x^2 +y^2 \ e\ leggo
Questo è un esempio misto testo/formula. Si notino i caratteri blank preceduti da backslash, per farli effettivamente comparire in stampa, e quelli non preceduti da backslash (dopo i "2") per il ripristino della baseline iniziale. Senza il secondo blank la stringa '\ e\ leggo' sarebbe finita a esponente di "y" a destra del "2".


p^{n_i^l} _{k_m^u}
Si indovini che cosa esce da questo esempio.


p^{n^i_{k_m^u}}
Si indovini che cosa esce da questo esempio.


p^{{n_i}^2}
Si indovini che cosa esce da questo esempio.



Osservazione finale: al presente il livello massimo di nidificazione delle parentesi graffe è di due parentesi simultaneamente aperte, come nell'ultimo esempio riportato. Eventuali livelli di nidificazione più profondi non sono segnalati come errori, ma producono risultati non prevedibili, compresi eventuali ERRORI PostScript.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{double scala = 1.0, sf = 1.0, x[2], a = 0.0,
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
x[0] = -0.2,
x[1] = 2.0,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^p_s"), x, &a),
x[1] = 1.8,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p_p^s"), x, &a),
x[1] = 1.6,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("pe^p_ps"), x, &a),
x[1] = 1.4,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("!pe^!p_!p!s"), x, &a),
x[1] = 1.2,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("x^2 +y^2"), x, &a),
x[1] = 1.0,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^{x^2 +y^2}"), x, &a),
x[1] = 0.8,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^{\\{n_i\\}}"), x, &a),
x[1] = 0.6,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^\\\\"), x, &a),
x[1] = 0.4,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("scrivo\\ x^2 +y^2 \\ e\\ leggo"), x, &a),
x[1] = 0.2,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^{n_i^l} _{k_m^u}"), x, &a),
x[1] = 0.0,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^{n^i_{k_m^u}}"), x, &a),
x[1] = -0.2,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^{{n_i}^2}"), x, &a),
x[1] = -0.4,
mscrivi_quasi_come_TeX_ps(const_cast<char *>("p^\""), x, &a),
mfine_ps(  );}

N.B.: Questo programma esegue tutti gli esempi citati nella precedente discussione, con angolazione orizzontale.
Si osservi il raddoppio dei "backslash" ogni volta che un singolo "backslash" deve pervenire alla funzione (cfr. chiamate 7, 8, 9 in contrapposizione all'ultima chiamata): il raddoppio è necessario a chi programma in C perché, come è noto, tale carattere funge da "escape" per il compilatore stesso.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mfonte_ps(n, k, s)

Seleziona il fonte numero k (1<=k<=4) (k = INTEGER*4 /int) della famiglia di fonti numero n (1<=n<=9) (n = INTEGER*4/int) per un totale di 36 fonti selezionabili, di cui l'ultimo coincide col primo, dato che il linguaggio PostScript ne contempla solo 35.

Il fonte ha una grandezza di s (REAL*8/double) centimetri.
Se non viene mai chiamata tutto ciò che viene scritto appare nel fonte Helvetica opportunamente scalato rispetto alle dimensioni della figura.

cfr. anche mcercafonte_per_nome_ps.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{double scala = 1.0, sf = 1.0, x[2],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
int i = 0, j, k;
char *s=const_cast<char *>("tanto va la gatta al lardo che ci lascia lo zampino");
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
x[0] = -1.0, sf = 0.3, scala = 0.0,
x[1] = 2.2;
for(j=0; j < 35; j++)
i = 1 + j/9,
k = 1 + (j % 9),
mfonte_ps(&k, &i, &sf),
mscrivi_ps(s, x, &scala),
x[1] -= 0.1;
mfine_ps(  );}

N.B.: Questo programma scrive la stringa citata usando tutti i fonti default con una grandezza di 3 millimetri.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mcercafonte_per_nome_ps(famiglia, tipo, scala)

Consente di selezionare un fonte non attraverso un numero (mfonte_ps), ma tramite una stringa di caratteri indicativa del nome.

Gli argomenti famiglia e tipo sono delle stringhe (chi usa il FORTRAN rammenti quanto detto in proposito: cfr. generalità e funzioni m_conv_string e m_conv_chars) mentre l'argomento scala ha significato identico all'argomento s passato a mfonte_ps.
Vale la seguente corrispondenza tra i valori degli argomenti di mfonte_ps (colonna di sinistra) e le stringhe da passare a mcercafonte_per_nome_ps (colonna di destra):

n = 1 "Courier"
n = 2 "Times"
n = 3 "Helvetica"
n = 4 "Helvetica-Narrow"
n = 5 "Palatino"
n = 6 "Bookman"
n = 7 "AvantGarde"
n = 8 "NewCentury"
n = 9 "ZapfDingbats"
k = 1 "Normal"
k = 2 "Bold"
k = 3 "ObliqueItalic"
k = 4 "BoldObliqueBoldItalic"





Le stringhe possono essere fornite così come indicate o anche scritte COMPLETAMENTE in minuscolo o COMPLETAMENTE in maiuscolo: nessun'altra combinazione di caratteri misti (e.g. "cOurieR") è riconosciuta.

Inoltre, perché sia realizzata la corrispondenza indicata con gli argomenti di mfonte_ps, è sufficiente fornire una sottostringa univocamente identificabile. Ad esempio la stringa "ime" fornita come argomento famiglia è sufficiente a identificare la stringa "Times" così come "quei" passato come argomento tipo identifica univocamente "ObliqueItalic".

Ogni chiamata a mcercafonte_per_nome_ps che non consenta l'identificazione univoca di un fonte rimane senza alcun effetto nel senso che il fonte corrente resta quello che era (eventualmente quello default ossia Helvetica).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{double scala = 1.0, sf = 1.0, x[2],
xmin = -1.0, ymin = -1.0, xmax = 1.0, ymax = 1.0;
int i = 0, j, k;
char *s=const_cast<char *>("tanto va la gatta al lardo che ci lascia lo zampino");
cons char *tipo[  ]={"Normal", "Bold", "ObliqueItalic", "BoldObliqueBoldItalic"},
*famiglia[  ]={
"Courier",
"Times",
"Helvetica",
"Helvetica-Narrow",
"Palatino",
"Bookman",
"AvantGarde",
"NewCentury",
"ZapfDingbats"};
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
minizio_ps(args[1], &scala, &sf),
mfinestra_ps(&xmin, &ymin, &xmax, &ymax),
x[0] = -1.0, sf = 0.3, scala = 0.0,
x[1] = 2.2;
for(j=0; j < 35; j++)
i = j/9,
k = j % 9,
mcercafonte_per_nome_ps(const_cast<char *>(famiglia[k]), const_cast<char *>(tipo[i]), &sf),
mscrivi_ps(s, x, &scala),
x[1] -= 0.1;
mfine_ps(  );}

N.B.: Questo programma è identico a quello fornito come esempio d'uso di mfonte_ps, salvo l'introduzione di arrays di stringhe identificative dei nomi dei vari fonti.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"























































































minizia_bitmap(m, k)

Crea una bitmap vuota di lati k entro l'array m, secondo la classe di bitmap eventualmente specificata tramite la funzione mclasse_bitmap. Inoltre ricollega la libreria a stderr.

La classe default è la monocromatica con un solo bit per pixel.

k e m sono due array interi (INTEGER*4/int), il primo di lunghezza 2 e il secondo di lunghezza sufficiente a contenere la bitmap ossia:
{lunghezza di m} >= k{2}* k{1}*bits/32.
I due valori degli elementi di k sono le dimensioni della bitmap in pixels.

Se ad esempio si vuole una bitmap standard di 512x512 pixels occorre dare k{1}=k{2}=512 e dimensionare l'array m almeno a lunghezza 8192 (per le bitmaps standard, come già detto, bits vale 1).

NON USARE minizia_bitmap per cancellare una bitmap in corso di utilizzazione! Usare invece mcancella_bitmap.

Questa funzione può essere chiamata anche se nessun file PostScript è correntemente aperto (minizio_ps).

Nessuna funzione il cui nome contiene la stringa "bitmap" può essere chiamata prima di minizia_bitmap PER LA STESSA BITMAP, tranne mclasse_bitmap, che, d'altra parte, non usa l'array m come argomento.

È possibile attribuire dimensioni arbitrarie alle bitmaps purché siano rispettate le seguenti condizioni:

(la regola generale traspare in modo evidente). Se questa condizione non viene rispettata il contenuto delle ultime righe della bitmap non è prevedibile.



La libreria si autoconfigura all'utilizzazione della più grande bitmap (della stessa classe) che abbia larghezza in pixels corrispondente ai precedenti requisiti e che sia inseribile nell'array fornito dall'utente.
Questo discorso può assumere rilevanza per applicativi che necessitano di bitmaps con risoluzione non inferiore a una certa soglia di tollerabilità. Ogni utente faccia le sue considerazioni in proposito.

Se la libreria si trova a dover ridefinire i valori delle componenti dell'array k restituisce i nuovi valori nell'array stesso e segnala la cosa su stderr.

Se, ciò fatto, le dimensioni risulterebbero comunque illegali la libreria NON INIZIALIZZA la bitmap che, a quel punto, non può essere usata.

In questo caso la funzione minizia_bitmap restituisce un valore nullo (verificabile da chi programma in C o da chi, pur programmando in Fortran, la usa correttamente come funzione e non come subroutine).

N.B.: se una delle componenti dell'array k ha un valore negativo ne viene usato il valore assoluto; in tal caso però l'array m deve avere un elemento in più che viene utilizzato dalla libreria per inserirvi un codice identificativo dell'array stesso. Ciò protegge l'utente che adoperi più bitmaps simultaneamente dal rischio di confondere tra di loro gli arrays relativi a ciascuna.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, m, i[4][2]={{512,512}, {479,512}, {512,-512}, {0,0}},
ibitmap[8192], jbitmap[8192], kbitmap[8193], lbitmap[1],
*p[4];
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0];
for(n=0; n < 4; n++)
m = minizia_bitmap(p[n], i[n]),
printf("%d %d %d\n", m, i[n][0], i[n][1]);}

N.B.: Questo programma inizializza quattro bitmaps standard da 1 bit per pixel.
La prima ha dimensioni 512x512 e l'array riservato ad essa ha esattamente la giusta lunghezza;
la seconda viene richiesta di dimensioni 479x512 e la libreria la ridimensionerà internamente a 476x512 per cui il relativo array risulta ridondante;
la terza ha dimensioni uguali alla prima ma poiché uno degli indici di dimensione è negativo l'array a essa riservato deve avere un elemento in più.
La quarta bitmap ha dimensioni illegali.

Si osservino i valori i[  ] ottenuti in uscita e il valore restituito dalla funzione stessa (0 nell'ultima chiamata).
Si osservi altresì che non viene chiamata alcun'altra funzione della libreria e che quindi questo programma è assolutamente inutile.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mclasse_bitmap(n_bitmap, classe)

La libreria è in grado di gestire internamente fino a 30 bitmaps diverse e tutte le classi di bitmaps previste dal linguaggio PostScript sono contemplate.
Con la chiamata di mclasse_bitmap (CHE VA EFFETTUATA, SE LA SI VUOLE, PRIMA DELLA CORRISPONDENTE CHIAMATA A minizia_bitmap) è possibile definire delle bitmaps non standard. I due argomenti sono degli INTEGER*4/int.

Il primo è il numero ordinale della bitmap cui si fa riferimento e deve essere compreso tra 0 e 29 (inclusi);

Il secondo è la classe cui appartiene la bitmap numero n_bitmap.

I valori possibili sono i seguenti:

classe tipo di bitmap memoria per minizia_bitmap
0, 1 monocromatica standard 1 bit per pixel
2 monocromatica 4 grigi 2 bit per pixel
4 monocromatica 16 grigi 4 bit per pixel
8 monocromatica 256 grigi 8 bit (1 byte) per pixel
-1 a 8 colori 3 bit per pixel
-2 a 64 colori 6 bit per pixel
-4 a 4096 colori 12 bit per pixel
-8 a 2**24 colori 24 bit per pixel



Tutti i precedenti valori di classe, moltiplicati per 3, producono una bitmap della stessa classe rispettiva, ma con un diverso comportamento dal punto di vista del cosiddetto "blending".
Precisamente se si forniscono i valori multipli di 3 il "blending" viene disattivato (è invece attivo se si forniscono i valori non multipli di 3).

Si rammenta che con il "blending" disattivato ogni pixel della bitmap apparirà in stampa con il colore che vi è stato posto per ultimo, mentre con "blending" attivo ogni pixel appare colorato con una "miscela" dei colori che (eventualmente) vi siano stati posti a più riprese.

Valori illegali degli argomenti causano semplicemente il ritorno della funzione come se non fosse stata chiamata.

Se si intende lavorare solo con bitmaps standard non è mai necessario chiamare mclasse_bitmap.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, i[  ]={512,512},
ibitmap[8192], jbitmap[16384], kbitmap[32768], lbitmap[65536],
*p[4];
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;}

N.B.: Eccettuate le istruzioni di scrittura e fissate tutte le dimensioni delle bitmaps a 512x512 pixels, questo programma riprende quello mostrato come esempio d'uso di minizia_bitmap.
In questo caso le 4 bitmaps appartengono a 4 classi diverse: la prima è ancora una bitmap standard da 1 bit per pixel e le successive sono da 2, 4, e 8 bits per pixel rispettivamente.
Coerentemente si osservino le lunghezze minimali dei rispettivi arrays. Anche questo programma non produce assolutamente nulla.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































mseleziona_bitmap(n_bitmap)

Funzione da chiamare SOLTANTO se si stanno usando diverse bitmaps appartenenti a classi diverse.

L'argomento n_bitmap è lo stesso citato in mclasse_bitmap.

Una chiamata a mseleziona_bitmap rende ATTIVA la classe di bitmaps associata al valore di n_bitmap così come a suo tempo era stato fornito a mclasse_bitmap. Ne segue che dopo questa chiamata ogni operazione di modifica di bitmaps (cfr. mcambia_bitmap, mcodifica_colore_bitmap, mstampa_bitmap_ps) sarà eseguita in accordo con la classe selezionata.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, i[  ]={512,512},
ibitmap[8192], jbitmap[16384], kbitmap[32768], lbitmap[65536],
*p[4];
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);}

N.B.: Questo programma è identico a quello presentato come esempio d'uso di mclasse_bitmap. Al termine viene aggiunta una chiamata a mseleziona_bitmap che dispone il programma a lavorare nella classe di bitmap della bitmap numero 2 (la penultima inizializzata). Tuttavia anche questo programma, così com'è, non serve a nulla.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mdistruggi_bitmap(i)

Serve a "distruggere" la bitmap di indice i (INTEGER*4/int) che deve essere già stata inizializzata con una chiamata a minizia_bitmap.
Serve soltanto se si utilizza più di una sola bitmap nello stesso programma e quindi se si è nella necessità di ricorrere alla funzione mseleziona_bitmap. L'argomento i ha in effetti l'identico significato dato per quella funzione.

N.B.: la chiamata di questa funzione non altera il contenuto dell'array associato alla bitmap in questione; se lo stesso array viene successivamente utilizzato come argomento di minizia_bitmap può accadere che la nuova bitmap "erediti" il contenuto di quella appena distrutta. Usare in tal caso mcancella_bitmap subito dopo minizia_bitmap.

Questa funzione è utile quando ci si trovi nella bisogna di eccedere il numero massimo di bitmaps simultaneamente gestibili: in una simile (rara) circostanza si può procedere al completamento del disegno di una bitmap, produrre il corrispondente output con mstampa_bitmap_ps e poi "liberare" la bitmap con questa funzione.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, i[  ]={512,512},
ibitmap[8192], jbitmap[16384], kbitmap[32768], lbitmap[65536],
*p[4];
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);
for(n=0; n < 4; n++)
{if(n == 2) continue;
mdistruggi_bitmap(&n);}}

N.B.: Questo programma è identico a quello presentato come esempio d'uso di mseleziona_bitmap.
Al termine tutte le bitmaps non appartenenti alla classe selezionata vengono addirittura distrutte e non sono quindi più utilizzabili per lo scopo per cui erano state create. (In altre parole i tre arrays corrispondenti tornano a completa disposizione del programma).
Anche questo programma, così com'è, non serve a nulla.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




















































































mcancella_bitmap(m)

Serve a porre il contenuto della bitmap contenuta nel vettore INTEGER*4/int m ai suoi valori iniziali, come se fosse stata appena inizializzata.
Il vettore m deve essere lo stesso fornito alla corrispondente chiamata di minizia_bitmap. In pratica tutto quanto è stato disegnato entro la bitmap fino al momento dell'esecuzione di questa funzione va perduto.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, i[  ]={512,512},
ibitmap[8192], jbitmap[16384], kbitmap[32768], lbitmap[65536],
*p[4];
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);
for(n=0; n < 4; n++)
{if(n == 2) continue;
mdistruggi_bitmap(&n);}
mcancella_bitmap(p[n]);}

N.B.: Questo programma è identico a quello presentato come esempio d'uso di mdistruggi_bitmap.
Al termine si chiama mcancella_bitmap (del tutto vanamente, poiché l'array kbitmap, relativo alla classe selezionata e unica superstite, è stato appena inizializzato).



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






























































































mcancella_colore_bitmap(m, colore)

Funziona come mcancella_bitmap (cfr.), ma permette di "cancellare" ponendo tutti i pixels allo stesso colore (utile per realizzare "sfondi" di bitmaps).
L'argomento m è lo stesso di mcancella_bitmap e ha il medesimo significato. L'argomento colore è un int/INTEGER*4 che contiene il colore cui devono essere ricondotti tutti i pixels della bitmap. Il suo valore deve essere compatibile con la classe di bitmap correntemente selezionata (cfr. mclasse_bitmap e mseleziona_bitmap) per cui è consigliabile ricavarlo tramite un'opportuna chiamata di mcodifica_colore_bitmap o mcodifica_colore_hcv_bitmap.

N.B.: Il colore colore viene inserito nei pixels della bitmap in modo OPACO indipendentemente dalla classe della bitmap in relazione alla proprietà di "blending" (cfr. mclasse_bitmap); tuttavia il colore inserito entra a far parte a pieno titolo del colore "risultante" di ogni pixel nel caso di "blending" attivo.

Per bitmaps monocromatiche standard il valore di colore viene controllato solo in relazione al fatto di essere o no nullo.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, i[  ]={128,128}, ibitmap[6144], u;
double rosso = 1.0, verde = 0.0, blu = 0.0, xx[  ]={-2,-2,2,2};
if(narg < 2)
printf("devi fornire un nome di file\n"), exit(0);
c = -12;
n=0;
mclasse_bitmap(&n, &c),
minizia_bitmap(ibitmap, i),
mcodifica_colore_bitmap(&rosso, &verde, &blu, &u),
mcancella_colore_bitmap(ibitmap, &u),
rosso = verde = 1.0,
minizio_ps(args[1], &rosso, &verde),
mfinestra_ps(xx, xx+1, xx+2, xx+3),
mstampa_bitmap_ps(ibitmap, i),
c = 1,
mcontorno_ps(&c),
mfine_ps(  );}

N.B.: Questo programma è simile a quello presentato come esempio d'uso di mcancella_bitmap ma in questo caso si immette il colore rosso su tutti i pixels di una bitmap di classe -12 (cfr. mclasse_bitmap) e la si stampa su file tramite mstampa_bitmap_ps.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"















































































mtrasforma_bitmap(k, s, x, l)

Restituisce nell'array intero (INTEGER*4/int) l, di lunghezza 2, la posizione (in pixels) occupata dal punto di coordinate utente x (vettore REAL*8/double con 2 elementi) in una bitmap i cui lati (in pixels) sono nel vettore k (INTEGER*4/int di lunghezza 2), (minizia_bitmap) quando essa rappresenta una finestra rettangolare di piano i cui vertici, in coordinate utente, sono contenuti nell'array s (REAL*8/double di lunghezza 4), secondo lo schema usuale s{1}=xmin, s{2}=ymin, s{3}=xmax, s{4}=ymax.

Questa funzione può essere chiamata anche se nessun file PostScript è correntemente aperto (minizio_ps).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, l[2], i[  ]={512,512},
ibitmap[8192], jbitmap[16384], kbitmap[32768], lbitmap[65536],
*p[4];
double s[  ]={-1.0, -1.0, 1.0, 1.0}, x[  ]={0.0, 0.0};
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);
for(n=0; n < 4; n++)
{if(n == 2) continue;
mdistruggi_bitmap(&n);}
mcancella_bitmap(p[n=2]),
mtrasforma_bitmap(i, s, x, l),
printf("il punto di coordinate (%g,%g) si trova nel pixel (%d,%d)\n",
x[0], x[1], l[0], l[1]);}

N.B.: Questo programma è identico a quello presentato come esempio d'uso di mcancella_bitmap.
Al termine si chiama mtrasforma_bitmap per mostrare a quali coordinate in pixels corrisponde l'origine del piano se la bitmap rappresenta il quadrato [-1, 1].




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





















































































mcodifica_colore_bitmap(rosso, verde, blu, colore_codificato)

Restituisce in colore_codificato (INTEGER*4/int) il valore che rappresenta le tre componenti RGB fornite in rosso, verde e blu (REAL*8/double), secondo la classe di bitmaps correntemente selezionata (mseleziona_bitmap). Nessun test viene compiuto sui valori dei primi tre argomenti poiché un colore_codificato può in ogni caso essere restituito.

Se tuttavia si vuole che colore_codificato corrisponda a qualcosa di sensato e prevedibile i tre primi argomenti dovrebbero avere valori compresi tra 0.0 e 1.0 (inclusi), come in mcolore_rgb_ps.

colore_codificato, se inserito come ultimo argomento di mcambia_bitmap, provoca l'inserimento dell'opportuno colore nella dovuta posizione della bitmap stessa.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, i[  ]={32,32},
ibitmap[32], jbitmap[64], kbitmap[128], lbitmap[256],
*p[4];
double rosso = 0.8, verde = 0.8, blu = 0.4;
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);
for(n=0; n < 4; n++)
{if(n == 2) continue;
mdistruggi_bitmap(&n);}
mcancella_bitmap(p[n=2]),
mcodifica_colore_bitmap(&rosso, &verde, &blu, &c),
printf("il colore di componenti (%g,%g,%g) si codifica come %d\n",
rosso, verde, blu, c);}

N.B.: Questo programma è identico a quello presentato come esempio d'uso di mtrasforma_bitmap che viene sostituita da mcodifica_colore_bitmap e dall'opportuna istruzione di output.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































mcodifica_colore_hcv_bitmap(hue, chroma, val, colore_codificato)

Restituisce in colore_codificato (INTEGER*4/int) il valore che rappresenta le tre componenti HCV fornite in hue, chroma e val (REAL*8/double), secondo la classe di bitmaps correntemente selezionata (mseleziona_bitmap). I valori dei primi tre argomenti sono ricondotti entro il proprio intervallo di validità come descritto in mcolore_hcv_ps.

colore_codificato, se inserito come ultimo argomento di mcambia_bitmap, provoca l'inserimento dell'opportuno colore nella dovuta posizione della bitmap stessa.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, i[  ]={32,32},
ibitmap[32], jbitmap[64], kbitmap[128], lbitmap[256],
*p[4];
double rosso = 0.8, verde = 0.8, blu = 0.4;
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);
for(n=0; n < 4; n++)
{if(n == 2) continue;
mdistruggi_bitmap(&n);}
mcancella_bitmap(p[n=2]),
mcodifica_colore_hcv_bitmap(&rosso, &verde, &blu, &c),
printf("il colore di componenti (%g,%g,%g) si codifica come %d\n",
rosso, verde, blu, c);}

N.B.: Questo programma è identico a quello presentato come esempio d'uso di mcodifica_colore_bitmap che viene sostituita da mcodifica_colore_hcv_bitmap per mostrare la diversa codifica degli stessi dati.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































mcambia_bitmap(m, l, k, onoff)

Pone il valore codificato dell'argomento onoff (INTEGER*4/int) nel pixel di coordinate l (INTEGER*4/int con 2 elementi restituito da mtrasforma_bitmap) della bitmap m di lati k creata con minizia_bitmap.

Se la bitmap è standard (un solo bit per pixel) onoff = 0 implica far diventare nero il pixel, mentre onoff = 1 (o diverso da zero) lo fa diventare bianco.

Se la bitmap non è standard cfr. le funzioni mcodifica_colore_bitmap e mcodifica_colore_hcv_bitmap.

Questa funzione può essere chiamata anche se nessun file PostScript è correntemente aperto (minizio_ps).

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, l[2], i[  ]={32,32},
ibitmap[32], jbitmap[64], kbitmap[128], lbitmap[256],
*p[4];
double rosso = 0.8, verde = 0.8, blu = 0.4;
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);
for(n=0; n < 4; n++)
{if(n == 2) continue;
mdistruggi_bitmap(&n);}
mcancella_bitmap(p[n=2]),
mcodifica_colore_hcv_bitmap(&rosso, &verde, &blu, &c),
l[0] = l[1] = 32,
mcambia_bitmap(p[n], l, i, &c);}

N.B.: Questo programma è identico a quello presentato come esempio d'uso di mcodifica_colore_hcv_bitmap; si aggiunge solo una chiamata a mcambia_bitmap per inserire la codifica del colore in una determinata posizione.
Si osservi che se si usano coordinate assolute di bitmap non è necessario eseguire mtrasforma_bitmap.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
























































































mstampa_bitmap_ps(m, k)

Inserisce nel file PostScript che riceve correntemente output grafico (minizio_ps e mindirizza_ps), le istruzioni necessarie per la stampa della bitmap m di lati k (minizia_bitmap)
NELLO STATO IN CUI SI TROVA
al momento della chiamata, compresa la classe di bitmap eventualmente selezionata tramite la più recente chiamata di mseleziona_bitmap.

Quest'ultima proprietà è estremamente rilevante nel caso che si siano adoperate bitmaps appartenenti a classi diverse (nel qual caso si potrebbero ottenere risultati erronei in stampa se ci si dimentica di selezionare la classe adeguata).

Se uno dei due valori contenuti nell'array k è negativo se ne usa il valore assoluto; in questo caso però la stampa avviene appunto in NEGATIVO nel senso fotografico del termine.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, m[2], l[2], *i, *j, *ibitmap, indice,
bits_per_pixel[  ]={1,2,4,8,3,6,12,24},
colonne[  ]={32,16,8,4,32,16,8,4};
double r, v, b, scala;
char *immagine = (char *)malloc(512), *buff = (char *)malloc(512);
FILE *f;
if(narg < 4)
printf("devi fornire due nomi di file e una classe di bitmap\n\
opzionalmente un fattore di scala\n"), exit(0);
if(narg == 5) sscanf(args[4], "%lf", &scala); else scala = 0.75;
sscanf(args[1], "%s", immagine);
if(!(f = fopen(immagine, "r")))
printf("file %s inaccessibile\n", immagine), exit(255);
if(!fgets(buff, 5, f))
printf("file %s malformattato\n", immagine), exit(254);
if(strcmp(buff, "P6\n"))
printf("file %s non è un'immagine ppm\n", immagine), exit(253);
i = new int[2], j = new int[2], n = 0;
while(n < 2)
{if(!fgets(buff, 81, f) || buff[strlen(buff)-1] != 10)
printf("file %s malformattato\n", immagine), exit(254);
switch(n)
{case 0: if(sscanf(buff, "%i %i", j, j+1) == 2) n++; break;
case 1: if(sscanf(buff, "%i", &c) == 1) n++;}}
buff = (char *)realloc(buff, j[0]*j[1]*3),
fread((void *)buff, sizeof(char), j[0]*j[1]*3, f),
fclose(f), free(immagine),
sscanf(args[3], "%i", &c),
indice = (n = abs(c)/2) < 3 ? n : 3;
if(c < 0) indice += 4;
i[0] = (j[0]/colonne[indice])*colonne[indice],
i[1] = j[1], n = 0, v = (double)j[0]/j[1],
mrapporto_assi(&n, &v),
mclasse_bitmap(&n, &c),
ibitmap = (int *)malloc(i[0]*i[1]*bits_per_pixel[indice]*sizeof(int)/32),
minizia_bitmap(ibitmap, i);
for(l[0]=1; l[0] <= i[0]; l[0]++)
for(l[1]=1; l[1] <= i[1]; l[1]++)
m[0] = l[0], m[1] = i[1]+1-l[1],
r = buff[3*(j[0]*(l[1]-1)+l[0]-1)]/255.0,
v = buff[3*(j[0]*(l[1]-1)+l[0]-1)+1]/255.0,
b = buff[3*(j[0]*(l[1]-1)+l[0]-1)+2]/255.0,
mcodifica_colore_bitmap(&r, &v, &b, &c),
mcambia_bitmap(ibitmap, m, i, &c);
v = 1.0,
minizio_ps(args[2], &scala, &v),
mpaginaA4_ps(  ),
r = v = 3.0, b = 0.0, morigine_ps(&r, &v, &b),
mstampa_bitmap_ps(ibitmap, i), mfine_ps(  );}

N.B.: Questo programma mostra come sia facile convertire un'immagine fotografica in PostScript (per poterla stampare) utilizzando soltanto la libreria, che si mostra quindi in grado di aggiungersi ai numerosi programmi di "conversione" in circolazione.
L'immagine fotografica deve essere contenuta in un file in formato portable pixmap (ppm) (facilmente ottenibile a partire da qualsiasi altro formato standard) il cui nome viene fornito sulla linea di comando come primo argomento; il secondo argomento da fornire è la classe di bitmap PostScript che si intende utilizzare per la conversione.
È "istruttivo" constatare il modo in cui "degrada" la qualità dell'immagine convertita man mano che si usano classi di bitmap inferiori alla classe -8.
Si noti che è possibile stampare una bitmap anche senza aver eseguito mfinestra_ps e/o mcontorno_ps mentre sono state eseguite sia mrapporto_assi (per conservare le proporzioni dell'immagine) sia mpaginaA4_ps in associazione con morigine_ps per poter piazzare l'immagine nella pagina tramite coordinate metriche. Si notino infine l'utilizzo di minizio_ps con un fattore di scala minore di 1, quello di mcodifica_colore_bitmap per trasferire nella bitmap gli appropriati colori dell'immagine, e l'inversione alto <--> basso per tener conto della diversa convenzione di orientamento tra il formato ppm e la presente libreria.
Ovviamente questo programma non produce né sistema di riferimento né quotature.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



















































































mimpagina(k, file, x, y, sx, sy, out, tipo)

Riunisce in una sola pagina un numero arbitrario di files PostScript prodotti dalla presente libreria o da GIOTTO.

È efficacemente e semplicemente interfacciata con gli utenti attraverso il programma impagina sviluppato da Simone Campagna.

La variabile k è un intero (INTEGER*4/int) non nullo con valori
-infinito <= k <= 6
che indica quanti sono i files da impaginare;

La funzione segnala un avvertimento se abs(k) > 100 o se k > 6, ma prosegue ugualmente. Invece ritorna senza far nulla se k = 0.

file è un vettore di stringhe i cui elementi sono i nomi dei files da impaginare (deve contenere almeno abs(k) stringhe di lunghezza arbitrariamente ragionevole (ovvero ragionevolmente arbitraria));

le variabili x, y, sx, sy sono usate soltanto quando k è < 0 (cfr. appresso);

out è una stringa che contiene il nome del file PostScript impaginato (ovvero in cui sarà scritto il codice per riprodurre gli abs(k) files sulla stessa pagina e può essere di qualsiasi ragionevole lunghezza); Il file di OUTPUT è sempre prodotto come INCAPSULATO, a meno che il suo nome out non inizi con una lettera MAIUSCOLA.

La variabile tipo è un array intero (INTEGER*4/int) di lunghezza almeno abs(k) e serve a distinguere la provenienza dei singoli files da impaginare:

ogni elemento = 0 indica che il file proviene dalla libreria;
ogni elemento = 1 indica che il file proviene da GIOTTO e contiene un grafico;
ogni elemento = 2 indica che il file proviene da GIOTTO e contiene una bitmap.
ogni elemento = 3 indica che il file proviene da GIOTTO e contiene una figura 3D.


Quando k è > 0 (e <= 6) il programma impagina i files secondo uno schema fisso, indipendente dal codice che li visualizzava individualmente; precisamente la pagina A4 viene trattata come un display con centro di gravità nel punto mediano del lato inferiore:
pertanto se k=1 l'unico file viene riprodotto centrato nella pagina e accostato al suo lato inferiore;
se k=2 i due files sono riprodotti affiancati e accostati al lato inferiore e così via fino a k=6 nel qual caso i 6 files occupano praticamente tutta la pagina e sono disposti come i semi del 6 di coppe nel gioco delle carte.

Quando invece k è < 0 il programma utilizza i vettori REAL*8/double x, y, sx, sy che devono essere tutti, se effettivamente usati, di lunghezza almeno abs(k) e devono contenere posizione (x,y) e fattori di scala (sx,sy) da applicare ordinatamente a ciascuno dei files.

In tal modo è possibile collocare ogni disegno in una posizione arbitaria entro la pagina e con una grandezza arbitraria.

x e y sono misurati in centimetri a partire dall'angolo inferiore sinistro della pagina A4;

sx e sy sono numeri puri e si applicano moltiplicativamente alla taglia del disegno originale, così com'era riprodotto individualmente nel suo file.

Se sx è negativo se ne usa il valore assoluto, ma viene annullata ogni eventuale rotazione del disegno. Questa possibilità è utile quando si voglia impaginare come "portrait" dei disegni generati individualmente come "landscape".

Non c'è garanzia di corretta impaginazione di files con orientazione mista.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args)
{int n, c, l[2], i[  ]={32,32},
ibitmap[32], jbitmap[64], kbitmap[128], lbitmap[256],
*p[4];
double rosso = 0.8, verde = 0.8, blu = 0.4;
char **files;
if(narg < 3)
printf("devi fornire 2 nomi di files\n"), exit(0);
files = (char **)malloc(2*sizeof(char *)),
files[0] = args[1], files[1] = args[2],
p[0] = &ibitmap[0], p[1] = &jbitmap[0],
p[2] = &kbitmap[0], p[3] = &lbitmap[0],
c = 1;
for(n=0; n < 4; n++)
mclasse_bitmap(&n, &c),
minizia_bitmap(p[n], i),
c <<= 1;
n = 2, mseleziona_bitmap(&n);
for(n=1; n < 4; n += 2) mdistruggi_bitmap(&n);
mcodifica_colore_hcv_bitmap(&rosso, &verde, &blu, &c),
l[0] = l[1] = 32,
mcambia_bitmap(p[n=2], l, i, &c),
l[0] = l[1] = 1,
mcambia_bitmap(p[n], l, i, &c),
n = 0, mseleziona_bitmap(&n),
l[0] = 1, l[1] = 32,
mcambia_bitmap(p[n], l, i, &n),
l[0] = 32, l[1] = 1,
mcambia_bitmap(p[n], l, i, &n),
rosso = verde = 1.0,
minizio_ps(args[2], &rosso, &verde),
mstampa_bitmap_ps(p[n], i),
minizio_ps(args[1], &rosso, &verde),
n = 2, mseleziona_bitmap(&n),
mstampa_bitmap_ps(p[n], i),
mfine_ps(  ),
l[0] = l[1] = 0, n = 2,
mimpagina(&n, files,
(double *)NULL, (double *)NULL,(double *)NULL,(double *)NULL, "out.ps", l);}

N.B.: Questo programma, dopo aver prodotto due distinti files ciascuno contenente una diversa bitmap, sulla falsariga del programma proposto come esempio d'uso di mstampa_bitmap_ps, li impagina insieme in un unico file incapsulato, col nome indicato.
Si notino i puntatori nulli forniti (dato che il primo argomento è positivo), fruibili da chi programma in C.




torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_use_as_Lego(i, intarray, realarray)

Serve a "dedicare" una finestra ad essere usata come contenitore di un istogramma tridimensionale in stile Lego. La finestra così dedicata si comporta per molti aspetti come se fosse "dedicata" a una pixmap (cfr. m_use_as_pixmap), ma nel caso presente non può ricevere alcun'altra chiamata che non sia una tra m_draw_Lego o m_clear_Lego. L'argomento i è un INTEGER*4/int e svolge l'identico ruolo del primo argomento fornito a m_use_as_pixmap. La finestra corrispondente deve già essere stata aperta (cfr. m_window).
Il secondo argomento intarray è un vettore di tipo INTEGER*4/int e di lunghezza almeno 6+u ove "u" vale zero se viene fornito un valore POSITIVO al dodicesimo elemento del successivo argomento realarray; se invece viene fornito come dodicesimo elemento di realarray un valore NEGATIVO O NULLO "u" deve valere quanto il valore del quarto elemento di intarray medesimo.

Il terzo argomento realarray è un vettore di tipo REAL*8/double e di lunghezza almeno 12. Per tutti gli elementi di tutti e due gli argomenti sono previsti valori di default che entrano in vigore quando

  1. si fornisce per intarray e/o realarray il puntatore nullo (ciò agevola i programmatori C o C++)

  2. si fornisce un singolo elemento con valore negativo, fatta eccezione per i primi 6 elementi di realarray.

Il significato degli elementi dei due vettori è il seguente (si ricorda che gli indici racchiusi tra parentesi graffe hanno solo un significato ordinale):

intarray{1} --> indice del colore di sfondo della finestra (default bianco).

intarray{2} --> indice del colore di sfondo del "pavimento" dell'istogramma (default nero).

intarray{3} --> numero di suddivisioni verticali della scala dell'istogramma (default 10).

intarray{4} --> numero di settori delle colonne; deve essere ragionevolmente piccolo dato che occorrono tre colori per ogni settore (default 1).

intarray{5} --> valore booleano: se "vero" il "pavimento" dell'istogramma viene colorato con intarray{2} (default 0 [falso])

intarray{6} --> valore booleano: se "vero" il contorno delle colonne viene marcato col colore nero (default 1 [vero])



Dalla locazione settima alla locazione 6+u (u >= 1) possono trovarsi gli indici di colore dei corrispondenti settori; gli indici devono già essere stati inizializzati nella tavolozza (cfr. m_new_color). La libreria introdurrà a sua volta nella tavolozza 2*u nuovi colori corrispondenti a "sfumature" di quelli richiesti, onde ottenere l'effetto visuale di tridimensionalità.

realarray{1,4} --> valore minimo e massimo della coordinata X (default: -1.0, 1.0);

realarray{2,5} --> valore minimo e massimo della coordinata Y (default: -1.0, 1.0);

realarray{3,6} --> valore minimo e massimo della coordinata Z (default: 0, 1.0);

realarray{7,8} --> angoli (espressi in gradi per la proiezione dell'istogramma (default 30, 60));

realarray{9,10} -->collocazione dell'angolo inferiore dell'istogramma all'interno della finestra (default 0.75 0.10 [volte le due dimensioni della finestra medesima]);

realarray{11} --->"spessore" delle colonne (default 1.0 che implica che colonne adiacenti si "tocchino"). Valori maggiori di 1.0 sono accettati anche se sconsigliati dato che provocherebbero sovrapposizioni delle colonne disegnate per ultime sopra le prime, anche se situate alla stessa "distanza" dal punto di osservazione.

realarray{12} --->Se contiene un valore POSITIVO qualsiasi il vettore DEVE contenere ulteriori 3*intarray{4} locazioni: ogni terna rappresenta le componenti rgb (normalizzate a 1.0) del colore da attribuire al corrispondente settore delle colonne; in questo caso NON È NECESSARIO che il programma chiamante esegua alcuna chiamata di m_new_color.


I colori delle colonne dell'istogramma sono gestiti secondo i seguenti criteri:

  1. se l'utente richiede un numero di settori > 1 (fornendo un coerente valore a intarray{4}) e se sono fornite le componenti rgb entro il vettore realarray (ciò implica, come già detto, che l'utente non ha dovuto eseguire m_new_color) viene inoltrata al server X11 la richiesta di allocazione dei nuovi colori e se il server non è in grado di restituirli tutti vengono utilizzati solo quelli restituiti effettivamente modulo il loro numero.

  2. se l'utente richiede un numero di settori > 1 (fornendo un coerente valore a intarray{4}) e ha eseguito m_new_color per il numero di volte necessario dovrebbe già conoscerne l'esito e aver autonomamente provveduto a riempire opportunamente il vettore intarray dalla locazione settima in avanti.

  3. se l'utente richiede un solo settore e fornisce un proprio colore in uno dei due modi sopra previsti, l'unico settore assume il colore fornito.

  4. se l'utente fornisce solo puntatori nulli viene usato il colore rosso per l'unico settore richiesto.

CAVEAT



NON ESISTE, AL PRESENTE, ALCUNA PROTEZIONE DA PARTE DELLA LIBRERIA CONTRO LA SITUAZIONE ANOMALA IN CUI L'UTENTE FORNISCA ENTRAMBI I PUNTATORI, PONGA UN VALORE POSITIVO IN realarray{12} MA NON DIA LE SUCCESSIVE LOCAZIONI DELLO STESSO PUNTATORE. IN UN CASO SIMILE È QUASI CERTO CHE IL PROGRAMMA ABORTISCA E ANCHE SE NON LO FACESSE I COLORI DEL DISEGNO SAREBBERO DEL TUTTO ALEATORI (VEROSIMILMENTE IMPERCETTIBILI VARIANTI DEL NERO).
Esempio d'uso: cfr. m_draw_lego





torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"










































































































m_draw_Lego(i, numcol, x, numsect, z)

Questa funzione realizza un istogramma "3D" in una finestra a questo deputata (m_use_as_Lego).
L'argomento i ha lo stesso significato del primo argomento fornito a quella funzione (indice della finestra aumentato di 1); il secondo (INTEGER*4/int) indica il numero totale di colonne da tracciare; il terzo è un vettore REAL*8/double contenente 2*numcol valori e indica la posizione di ciascuna colonna nel piano.
Le due coordinate di una colonna devono essere adiacenti all'interno del vettore, il che vuol dire che, se si usa un array a due indici, i programmatori in C o C++ avranno a che fare con un ovvio x[numcol][2], mentre i fortranisti avranno un assurdo x(2,numcol).

Non ha alcuna importanza l'ordine con cui viene riempito il vettore rispetto alla finestra di piano che vi viene trasferita, né che la finestra di piano sia uniformemente trasformata nel vettore.

In ogni caso le colonne situate al di fuori della finestra [X,Y] fornita a m_use_as_Lego non saranno disegnate.
Il quarto argomento (INTEGER*4/int) indica il numero di settori di ogni colonna; se risulta maggiore dell'omologo argomento specificato in m_use_as_Lego i settori eccedenti sono colorati utilizzando daccapo i colori disponibili. Infine l'argomento z è un vettore REAL*8/double e contiene numsect*numcol valori (quelli relativi alla stessa colonna di nuovo devono essere adiacenti).
Ovviamente l'ordine dei valori in z deve essere coerente con quello dato in x.

Esempio d'uso:

#include <passe_par_tout.h>

#define N_segmenti 7
#define NUM_COLONNE 6400
#define COLONNE_PER_LATO 80


int main(int argc, char **argv, char **env)
{double
x1[2], xx[12], x[NUM_COLONNE][2], z[N_segmenti*NUM_COLONNE],
dz=1.0/N_segmenti, zmax, u, r, g, b;
int i, K, L, numcol, j, sector, sectormax, iarray[6+N_segmenti];
iarray[0] = iarray[1] = iarray[2] = iarray[4] = -1,
iarray[5] = 0, iarray[3] = N_segmenti,
xx[11] = xx[10] = xx[9] = xx[8] = xx[7] = xx[6] = xx[0] = xx[1] = -1.0,
xx[2] = 0.0, xx[3] = xx[4] = xx[5] = 1.0,
j = 0;
for(L=0; L < COLONNE_PER_LATO; L++) for(K=0; K < COLONNE_PER_LATO; K++)
{x1[0] = x[j][0] = -1 + (double)L * 2.0 / (COLONNE_PER_LATO-1.0),
x1[1] = x[j][1] = -1 + (double)K * 2.0 / (COLONNE_PER_LATO-1.0),
zmax = exp(-(x1[0]*x1[0] + x1[1]*x1[1])/0.2),
sectormax = (int)(zmax/dz);
for(sector=0; sector < sectormax; sector++) z[N_segmenti*j+sector] = dz;
z[N_segmenti*j+sectormax] = zmax-dz*(sectormax);
for(sector=sectormax+1; sector < N_segmenti; sector++) z[N_segmenti*j+sector] = 0;
j++;}
m_startg(const_cast<char *>("pippo"), &(K=600), &(L=600)),
m_window(&(K=80), &(L=80));
for (i=0; i<N_segmenti; i++)
u = (double)i/N_segmenti,
r = pow(fabs(sin((u-0.3)*M_PI)),1.2),
g = pow(sin(u*M_PI),1.8),
b = pow(cos(0.5*u*M_PI),1.1),
iarray[6+i] = m_new_color(&r, &g, &b);
m_use_as_Lego(&(K=1), iarray, xx),
m_draw_Lego(&(K=1),&(numcol=NUM_COLONNE) , x, &(L=N_segmenti), z),
m_wait_for_events(&(K=EVENTO_MOUSE)),
m_endg(  );}

N.B.: Questo programma realizza un istogramma con 6400 colonne sul quadrato -1,1; Sulle colonne sono riportati i valori di 7 frazioni di una gaussiana nella variabile x^2+y^2. Il programma termina al click del mouse. La scala cromatica è stata fornita dall'utente Carlo Benedetti.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































m_clear_Lego(i)

Questa funzione cancella un istogramma "3D" dalla finestra a questo deputata, lasciando visibile solo il contenitore dell'istogramma stesso.
Detto che l'argomento i ha lo stesso significato dell'omonimo argomento di m_draw_Lego non si ritiene di dover aggiungere altro.





torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






















































































mdisegnaLego_ps(intarray, realarray, numcol, x, numsect, z)

Questa funzione riunisce in una sola chiamata indirizzata a un file PostScript correntemente aperto (e per il quale non sia già stata eseguita la funzione mfinestra_ps) le funzionalità di m_use_as_Lego e m_draw_Lego cui si rimanda per la descrizione degli argomenti che hanno significato identico a quelli omonimi delle due citate funzioni.
Per questa funzione non ci sono limiti al numero di colori diversi utilizzabili per le colonne.

Esempio d'uso:

#include <passe_par_tout.h>

#define N_segmenti 7
#define NUM_COLONNE 6400
#define COLONNE_PER_LATO 80


int main(int narg, char **args, char **env)
{double
x1[2], x[NUM_COLONNE][2], z[N_segmenti*NUM_COLONNE], r, g, b, xx,
dz=1.0/N_segmenti, zmax, scala = 1.0, sf = 1.0,
*ff = new double[12+3*N_segmenti];
int K, L, n, numcol, j, sector, sectormax,
ints[  ]={-1, -1, -1, N_segmenti, -1, 0};
if(narg < 2)
printf("devi fornire il nome di un file\n"), exit(255);
ff[0] = ff[1] = -1.0,
ff[2] = 0., ff[3] = ff[4] = ff[5] = 1.0,
ff[6] = ff[7] = ff[8] = ff[9] = ff[10] = -1.0, ff[11] = 1.0,
j = 0;
for(L=0; L < COLONNE_PER_LATO; L++)
for(K=0; K < COLONNE_PER_LATO; K++)
{x1[0] = x[j][0] = -1 + (double)L * 2.0 / (COLONNE_PER_LATO-1.0),
x1[1] = x[j][1] = -1 + (double)K * 2.0 / (COLONNE_PER_LATO-1.0),
zmax = exp(-(x1[0]*x1[0] + x1[1]*x1[1])/0.2),
sectormax = (int)(zmax/dz);
for(sector=0; sector < sectormax; sector++)
z[N_segmenti*j+sector] = dz;
z[N_segmenti*j+sectormax] = zmax-dz*(sectormax);
for(sector=sectormax+1; sector < N_segmenti; sector++)
z[N_segmenti*j+sector] = 0;
j++;}
for(j=0; j < N_segmenti; j++)
xx = (double)j/N_segmenti,
r = pow(fabs(sin((xx-0.3)*M_PI)),1.2),
g = pow(sin(xx*M_PI),1.8),
b = pow(cos(0.5*xx*M_PI),1.1),
ff[12+3*j] = r, ff[13+3*j] = g, ff[14+3*j] = b;
minizio_ps(args[1], &scala, &sf),
mdisegnaLego_ps(ints, ff, &(numcol=NUM_COLONNE), x, &(n=N_segmenti), z),
mfine_ps(  );}

N.B.: Questo programma realizza su file PostScript lo stesso istogramma descritto nell'esempio relativo a m_draw_Lego. Cambia solo il modo in cui sono forniti alla libreria i colori (cfr. il valore di ff[11]).


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




























































































m_legend(n, stringhe, x, flag, colori)

Premessa:

chi ha solo critiche distruttive e/o pretestuose da muovere a questa funzione, si riscriva da sé il codice equivalente: la libreria contiene tutti gli ingredienti necessari alla bisogna.

Questa funzione inserisce una legenda nella finestra numero n (argomento iniziale di tipo int/INTEGER*4). Come sempre n>=0.
I successivi argomenti hanno identico significato e funzionalità degli omonimi argomenti di mlegenda_ps cui si rinvia per maggior dettaglio. Va solo osservato che, nel caso presente, i valori leciti dell'argomento colori sono gli indici della tavolozza e non le codifiche RGB.

A differenza di quanto avviene per quella funzione, tuttavia, nel caso presente la legenda viene immediatamente (modulo una eventuale esecuzione di m_redraw) realizzata sulla finestra, di modo che si possa usufruire con profitto delle funzioni di "editing" (cfr. m_move_legend, m_recolor_legend, m_hide_legend, m_unhide_legend, m_destroy_legend).

La finestra di indice n, per poter contenere la legenda, deve essere stata preparata fin dall'inizio a questa bisogna. A tal proposito occorre e basta accendere il bit numero 23 nel secondo argomento trasferito a m_window.

Se la finestra è ombreggiata da un file PS, anch'esso riceve, ovviamente, la legenda, ma resta vero che il codice corrispondente viene inserito nel file solo all'atto della chiusura, il che implica che le eventuali esecuzioni di una delle funzioni di "editing" si riflettono anche sul file PS ombra. In particolare, se si invoca la funzione m_destroy_legend, il file PS ombra non riceverà alcun codice atto a produrre la legenda, mentre se l'ultima operazione effettuata sulla finestra fosse una m_hide_legend, il file PS ombra riceverà ugualmente il codice per la legenda, ma lo riceverà "commentato".

Se le stringhe della legenda contengono caratteri riconosciuti dalla semantica di mscrivi_quasi_come_tex_ps va ricordato che questi saranno visualizzati sul monitor come caratteri ordinari, ma l'eventuale file PS ombra li elaborerà correttamente.

Esempio d'uso:

#include <passe_par_tout.h>

int main(  )
{char *u=const_cast<char *>("");
const char *s[  ]=
{"AAA", "BBB", "CCC", "DDDDDD",
"EEE", "FFF", "GGG", "\0"};
double xmin = 0.0, ymin = 0.0, xmax = 5.0, ymax = 5.0, x[2], xx[2];
int K=400, L = 400, i, col[  ]={0,1,2,3,4,5,6,-1};
m_startg(u, &K, &L),
m_sound_message(u),
K = L = 95,
L |= RICHIEDO_LEGENDA,
K |= OMBREGGIA_FINESTRA,
m_window(&K, &L),
K = 0,
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = x[1] = 2.6, L = DA_QUI_A_DESTRA_ALTO,
xx[0] = x[0], xx[1] = x[1],
col[0] |= RIQUADRO_OPACO,
m_legend(&K, const_cast<char **>(s), x, &L, col);
for(i=0; i < 7; i++)
x[0] = xmin, x[1] = 0.35 + i*0.4,
m_move(x),
K = i,
m_color(&K),
x[0] = xmax,
m_line(x);
K = 0,
m_redraw(&K),
L = EVENTO_ENTER,
m_wait_for_events(&L);
while(true)
{printf("dove vuoi piazzare la legenda e quale colore negativo [meno di 8!]? "),
scanf("%lf %lf %i", &x[0], &x[1], &L);
if(x[0] >= xmax) break;
for(i=0; i < L; i++) col[i] = i; for(i=L; i < 7; i++) col[i] = -1;
if(col[0] >= 0) col[0] |= RIQUADRO_OPACO;
if(x[0] < xmax)
xx[0] = x[0], xx[1] = x[1], m_move_legend(&K, x, (int*)NULL),
m_recolor_legend(&K, col),
m_redraw(&K), m_flush(  );}
m_mouse(x);
printf("ora nascondo la legenda fino a un click del mouse\n"), fflush(stdout),
m_hide_legend(&K),
m_mouse(x),
m_move_legend(&K, xx, (int*)NULL),
m_unhide_legend(&K),

m_flush(  ),
m_redraw(&K);
if(m_mouse(x) > 1)
printf("ora DISTRUGGO la legenda, perché non hai cliccato col sinistro ! \n"),
fflush(stdout),
m_destroy_legend(&K);
m_redraw(&K),
printf("provo a eseguire m_move_legend col valore cliccato da mouse\n"),
fflush(stdout);
if(!m_move_legend(&K, x, (int*)NULL))
printf("come si vede non ha potuto.\n"), fflush(stdout);
L = EVENTO_ENTER,
m_wait_for_events(&L),
m_endg(  );}


N.B.: Questo programma illustra l'uso di m_legend e delle altre funzioni di editing della legenda. Si osservi che la finestra è anche ombreggiata da un file PS, ma che in esso non si troverà traccia della legenda allorché l'ultima operazione compiuta (con successo) sarà stata la distruzione della legenda medesima. Si osservi anche che l'esecuzione di m_legend è stata effettuata senza far uso di alcun argomento default.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































m_move_legend(n, x, flag)

Funzione che sposta la legenda della finestra n (int/INTEGER*4) obbligatoriamente già creata, ma non necessariamente visualizzata, nella posizione x (con lo stesso significato dell'omonimo argomento di m_legend, ma obbligatoriamente non NULL), e con l'orientazione data da flag (con lo stesso significato dell'omonimo argomento di m_legend, ed eventualmente NULL per conservarlo invariato).
L'esempio d'uso si trova in m_legend.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































m_recolor_legend(n, colori)

Funzione che modifica i colori di una legenda già creata. Gli argomenti hanno semantica identica a quelli omonimi di m_legend, cui si rinvia per spiegazioni ed esempio d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"




























































































m_hide_legend(n)

Funzione che toglie dal monitor la legenda (già creata) della finestra n. Se la legenda non è stata creata o è già nascosta equivale a "nessuna operazione". Esempio d'uso in m_legend.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



























































































m_unhide_legend(n)

Funzione che rivisualizza la legenda (già creata) della finestra n. Se la legenda non è stata creata o è già visualizzata equivale a "nessuna operazione". La legenda viene visualizzata nella posizione e con l'orientamento e i colori stabiliti tramite le ultime eventuali esecuzioni di m_move_legend e/o m_recolor_legend che funzionano anche "a legenda nascosta".
Esempio d'uso in m_legend.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"


































































































m_destroy_legend(n)

Funzione che distrugge definitivamente la legenda della finestra di indice n, liberando anche la memoria di programma riservata all'uopo. Dopo che è stata eseguita questa funzione, per avere una legenda occorre rieseguire m_legend. Questa è anche l'unica via per modificare l'array di stringhe della legenda.
Esempio d'uso in m_legend.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































































































































mlegenda_ps(stringhe, x, flag, colori)

Premessa:
chi ha solo critiche distruttive e/o pretestuose da muovere a questa funzione, si riscriva da sé il codice equivalente: la libreria contiene tutti gli ingredienti necessari alla bisogna.

Questa funzione inserisce nel file PostScript correntemente aperto le informazioni necessarie a farvi comparire una "legenda" descrittiva del disegno effettuato. La legenda viene racchiusa in un riquadro all'interno della regione di "clipping" e il riquadro si autodimensiona in base alla lunghezza delle stringhe che costituiscono la legenda.

Il file PS cui si vuole attribuire una legenda deve essere stato adeguatamente preparato fin dalla sua apertura tramite la funzione minizio_ps. A tal fine è necessario e sufficiente fornire alla funzione minizio_ps un valore negativo (o nullo) per il suo terzo argomento. Il valore assoluto (eventualmente ricondotto a 1.0) sarà utilizzato per gli scopi di cui alla descrizione della citata funzione.

Il codice PostScript necessario alla realizzazione effettiva della legenda viene scritto nel file PostScript relativo solo all'atto della chiusura del file medesimo (tramite mchiudi_ps o mfine_ps) di modo che, fino a quel momento, sia sempre possibile modificare e/o eliminare la legenda (cfr. funzioni msposta_legenda, mricolora_legenda, mdistruggi_legenda, mnascondi_legenda, mrivela_legenda). I nomi delle funzioni citate tra parentesi sono volutamente privi della stringa finale "_ps" perché, nelle intenzioni dell'autore e in ossequio alle regole generali della libreria, in un prossimo futuro potranno essere eseguite anche su file PostScript generati precedentemente da versioni più antiche della libreria.

Dei quattro argomenti della funzione solo il primo deve necessariamente ricevere dei valori, mentre per gli altri tre è previsto un "comportamento standard" corrispondente alla fornitura del puntatore nullo (preceduto dall'opportuno operatore di "casting", per chi programma in C o C++).

Il primo argomento deve essere un array di stringhe il cui ultimo elemento deve essere la stringa di lunghezza nulla ("\0" per chi programma in C o C++, mentre i fortranisti, ahiloro, devono tener conto di quanto detto a proposito della fornitura di argomenti di tipo stringa alla libreria).

Le stringhe costituiscono il contenuto della legenda e saranno scritte, una per riga, all'interno di un riquadro autodimensionato contornato da un perimetro di colore nero, indipendentemente dal colore correntemente in uso per il relativo file. La sintassi delle stringhe rispetta quella discussa a proposito della funzione mscrivi_quasi_come_tex_ps di modo che si possano inserire nella legenda anche espressioni matematiche.

Il numero di stringhe che si possono fornire non è limitato superiormente, ma è ovvio che occorra qualche ragionevolezza per evitare legende che coprano l'intera figura e/o cadano al di fuori della regione di clipping. Se il numero di stringhe fornito è "elevato" si consideri l'opportunità di invocare la funzione mfonte_ps subito prima della chiusura del file per modificare la grandezza dei caratteri, oppure, se si è certi che il proprio disegno non "deborda" dalla regione di clipping, la funzione mfora_contorno_ps per abolire il clipping stesso, qualora sia la legenda a "debordare". La libreria riduce autonomamente la grandezza del fonte del 25% se il file PS è un file ombra. Lo stesso effetto si può ottenere su file PS normali accendendo il quarto bit (0x10000000) del primo elemento dell'ultimo argomento (colori).

Dato che gli spazi all'interno delle stringhe sono significativi ai fini del dimensionamento del riquadro della legenda, se ne può trarre profitto per ottenere effetti di "centratura" delle stringhe entro il riquadro (si rammenti che la sintassi di mscrivi_quasi_come_tex_ps implica sempre giustificazione a sinistra) o di maggiore spaziatura tra una stringa e l'altra (inframmezzando tra le stringhe alcune costituite di soli caratteri "blank").

Il secondo argomento, se non è NULL, viene interpretato come un vettore di double/REAL*8 contenente le due coordinate (nel sistema di riferimento dell'utente) in cui va piazzato uno dei vertici del riquadro della legenda: il valore default di x è la coppia (xmin, ymax) (facendo riferimento ai nomi usati nella descrizione della funzione mfinestra_ps). Quale sia il vertice da piazzare in x è determinato dal valore dell'argomento flag (di tipo int/INTEGER*4) il cui valore default (se flag è NULL) è la costante predefinita

DA_SINISTRA_ALTO

In tal caso il vertice piazzato in x è quello superiore sinistro e il riquadro si estende da lì verso destra e verso il basso. Valori alternativi per flag sono elencati al capitolo "costanti predefinite" e il loro significato dovrebbe essere intuitivo. Va osservato che la libreria accetta qualsiasi combinazione di valori per x e flag, anche se ciò implicasse che il riquadro della legenda cada completamente al di fuori della regione di clipping (e quindi non appaia affatto una volta che si visualizzi il file). Una tale combinazione sarebbe, ad esempio, x = (double *)NULL e flag = DA_QUI_A_DESTRA_ALTO.

Le stringhe sono inserite nel riquadro nell'ordine in cui appaiono entro l'array, con la prima stringa in alto; se però si fornisce flag preceduto dal segno meno (e.g. flag = -DA_SINISTRA_ALTO) l'ordine di apparizione delle stringhe viene invertito.

L'ultimo argomento colori (di tipo int/INTEGER*4), se non è NULL, viene usato per attribuire colori diversi alle stringhe. In difetto di colori tutte le stringhe sono scritte in nero, indipendentemente dal colore attuale in uso per il file PS cui la legenda appartiene.

colori deve puntare un array di interi non negativi: il primo valore negativo incontrato ne termina la scansione. (attenzione: se il primo valore puntato è negativo NON è come se colori fosse stato NULL; infatti in un caso simile la libreria emette un messaggio di errore, dopo di che si comporta come con colori=NULL). Se il numero di valori non negativi incontrato in colori è non minore del numero di stringhe ogni elemento di colori viene ordinatamente collegato al corrispondente elemento di stringhe fino a esaurimento dell'array e ogni stringa viene disegnata nel colore che le è stato attribuito.
Se invece il numero di elementi non negativi incontrato in colori è minore del numero di stringhe, alle stringhe eccedenti vengono riattribuiti gli elementi di colori a ripartire dal primo, e così via fino a esaurimento di stringhe.

I valori leciti per gli elementi di colori sono le codifiche dei colori PostScript così come vengono definite dalla funzione mcolore_rgb_ps di questa stessa libreria, quando le vengano forniti i primi tre argomenti negativi.

Un discorso a parte riguarda il primo elemento di colori:
se tale elemento ha accesi il secondo o il terzo bit o entrambi (come avviene facendone l'or bit a bit rispettivamente con 0x40000000, 0x20000000, 0x60000000), allora viene espunto da colori in modo tale che per la colorazione delle stringhe sono usati, secondo gli stessi ragionamenti fatti in precedenza, gli elementi di colori dal secondo in poi.
Nel contesto presente il primo elemento di colori viene invece utilizzato per attribuire un colore al riquadro della legenda, che diventa in questo caso OPACO e va a coprire la regione del disegno che occupa (altrimenti il riquadro sarebbe trasparente).

Precisamente, se ad essere acceso è il secondo bit (or con 0x40000000 o con 0x60000000), allora al riquadro viene attribuito lo stesso colore dello sfondo del disegno e si ha solo l'effetto di opacità.
Se invece è acceso solo il terzo bit (or con 0x20000000) il riquadro assume il colore la cui codifica si trova nei tre bytes di destra dello stesso elemento di colori (coerentemente con la codifica di mcolore_rgb_ps).
Se ad esempio il primo elemento di colori valesse esattamente 0x20000000 il riquadro apparirebbe nero.

Esempio d'uso:

#include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{int i = 1, col[  ]={0x20ff00ff, 0xffff, -1};
double s = 1.0, sf = 0.0, x[  ]={-1.0, -1.0, 1.0, 1.0};
char *st[  ]={"!a = b^2 + !c^2", "B",
"CC", "\0"};
if(narg == 1) printf("devi fornire un nome\n"), exit(1);
minizio_ps(args[1], &s, &sf),
mfinestra_ps(x, x+1, x+2, x+3),
mlegenda_ps(st, (double *)NULL, (int *)NULL, col),
mcontorno_ps(&i),
mfine_ps(  );}

N.B.: questo programma mostra come inserire una legenda di tre stringhe (di cui una in forma matematica) in un riquadro color magenta situato nella posizione di default.
Tutte le stringhe sono colorate in ciano.
Si notino l'attribuzione di un valore nullo all'argomento sf di minizio_ps, la stringa di terminazione dell'array st e la struttura dell'array col.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































msposta_legenda(i, x, flags, modo)

Funzione atta a spostare una legenda inserita in un file PostScript. Attualmente viene eseguita automaticamente dalla libreria in connessione con la gestione di files PostScript ombra e non ha senso che venga eseguita da parte di un utente.

Gli argomenti i e modo hanno lo stesso significato e tipo degli omonimi argomenti citati in mrivela_legenda.

L'argomento x è un array di tipo double/REAL*8 che contiene i valori (in coordinate utente) della posizione in cui si vuol collocare l'angolo inferiore sinistro del riquadro contenente la legenda.

L'argomento flags è un vettore di tipo int/INTEGER*4 il cui significato resta, al presente, "in autoris pectore".

La forma e le dimensioni del riquadro della legenda non sono alterati da questa funzione.

Data la riservatezza di questa funzione allo stato dell'arte non si ritiene opportuno darne un esempio d'uso.


torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"





























































































mricolora_legenda(i, colori, modo)

Funzione atta a modificare i colori di una legenda inserita in un file PostScript. Attualmente viene eseguita automaticamente dalla libreria in connessione con la gestione di files PostScript ombra e non ha senso che venga eseguita da parte di un utente.

Per gli argomenti i e modo vale quanto detto circa mrivela_legenda. L'argomento colori è un array di int/INTEGER*4 che contiene, come presumibile, i valori da attribuire ai colori con cui la legenda viene scritta.

Data la riservatezza di questa funzione allo stato dell'arte non si ritiene opportuno darne un esempio d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
































































































mnascondi_legenda(i, modo)

funzione "contraria" di mrivela_legenda. Valgono le stesse considerazioni colà espresse.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"































































































mrivela_legenda(i, modo)

serve a far sì che una legenda "nascosta" e inserita in un file PS torni visibile; attualmente viene eseguita automaticamente dalla libreria stessa in connessione con l'uso dei files PostScript ombra e non ha senso eseguirla da parte di un utente.

L'argomento i è di tipo int/INTEGER*4 e rappresenta l'indice progressivo (nella cronologia dei files PostScript) del file cui ci si riferisce. Nessun test (attualmente) viene effettuato sulla validità del valore attribuito a tale argomento.

L'argomento modo è di tipo stringa ed è riservato a usi futuri "in autoris pectore"; attualmente viene riconosciuto solo il valore NULL per tale argomento: ogni altro valore implica "nessuna operazione".

Data la riservatezza di questa funzione allo stato dell'arte non si ritiene opportuno darne un esempio d'uso.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"






























































































mdistruggi_legenda(i)

Funzione che "distrugge" definitivamente la legenda inserita nel file PostScript che occupa l'indice i (int/INTEGER*4) nella cronologia dei files PostScript.

Attualmente viene eseguita automaticamente dalla libreria in connessione con la gestione dei files PostScript ombra e non ha senso che venga eseguita da parte di un utente (basta non eseguire mlegenda_ps).

Data la riservatezza di questa funzione allo stato dell'arte non si ritiene opportuno darne un esempio d'uso.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"
















































































m_open_display(display)

Normalmente la libreria lavora su un unico DISPLAY gestito da un solo server X11 e di solito si tratta del DISPLAY locale. Questa funzione invece permette a un'applicazione che la usi di connettersi con fino a otto (8) diversi DISPLAY contemporaneamente rendendo quindi possibile a numerose diverse "postazioni" di interagire in tempo reale tra loro attraverso la stessa applicazione, che sarà comunque in esecuzione su uno solo degli host collegati.

È chiaro che gli hosts coinvolti debbano essere reciprocamente accessibili via rete e debbano consentirsi vicendevolmente lo scambio di informazioni attraverso i protocolli standard di X.

In difetto di ciò questa funzione non può avere successo, relativamente a un eventuale host che non rispetti quanto sopra enunciato; anzi se l'host "ribelle" stesse eseguendo il proprio server X11 con qualche proprietà non standard dal punto di vista della "sicurezza" l'applicazione che eseguisse questa funzione tentando di connettersi a un simile server potrebbe andare incontro a un loop infinito dal quale non sarebbe più possibile alcun tipo di scappatoia se non l'interruzione brutale del programma. Se ne conclude che prima di eseguire questa funzione è sempre opportuno assicurarsi della piena accessibilità di tutti i server cui si intende collegarsi.

L'unico argomento della funzione è una stringa (ne tengano conto i fortranisti, che sono comunque sconsigliati di avventurarsi in questa funzione) che deve contenere una denominazione plausibile di un DISPLAY accessibile, secondo la semantica propria del protocollo TCP/IP.
Il server che corrisponde alla stringa contenuta in display (se esiste) viene connesso all'applicazione e diventa istantaneamente il "server corrente" (allo stesso modo in cui una finestra appena aperta con m_window diventa la finestra corrente); ciò significa che da quell'istante e fino a nuovo ordine (cfr. ad esempio m_select_display) ogni nuova finestra sarà aperta su quel server (fino al massimo di 32 finestre previsto dalla libreria).
Pertanto un'applicazione che usi la libreria può arrivare a gestire fino a 32x8 = 256 finestre simultaneamente.

D'altra parte, poiché il protocollo TCP/IP prevede diversi "alias" per lo stesso DISPLAY, un utente avveduto può servirsi di questa funzione anche per "sforare" il limite delle 32 finestre sullo stesso server, semplicemente eseguendola più volte con diversi alias che realizzino "connessioni fittizie" al server locale (già connesso); questo significa che si possono aprire (teoricamente) sullo stesso DISPLAY fino a 32xN finestre, N essendo il numero totale di alias disponibili per lo stesso server e purché, beninteso, N sia minore di 9.

Se questa funzione fallisce per qualsiasi motivo, ma riesce almeno a restituire il controllo al chiamante (esclusi quindi i casi patologici di loop infinito di cui si è discusso in precedenza) la connessione richiesta semplicemente non avviene e tutto resta com'era prima (salva l'eventuale comparsa su stdout di due righe di diagnostico esterne alla libreria e provenienti dal server remoto che nega l'accesso o dal server locale che non capisce che cosa si pretenda). Un esempio d'uso è fornito assieme alla descrizione della funzione m_select_display.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































m_select_display(display, finestra)

Rende correntemente attivo il display di nome display (argomento di tipo stringa del tutto omologo a quello di m_open_display). Se l'argomento finestra (di tipo int/INTEGER*4) non è il puntatore nullo viene resa attiva la finestra che sul display display ha l'indice numero finestra, altrimenti è resa attiva la finestra di display che ha l'indice più alto. Dopo che è stata eseguita questa funzione l'applicativo "dialoga" col display display esattamente come se fosse l'unico display esistente.

Esempio d'uso:

# include <passe_par_tout.h>

int main(int narg, char ** args, char ** env)
{int k, l, n, o, M, maxp, punteggio[  ]={0, 0}, j[2];
double x[  ]={0., 0., 1., 1., 0., 0., 0., 0.}, m[2], t[  ]={0.1, 0.75};
char *displa[2];
const char *esito[  ]={"hai vinto", "hai perso",
"pari e patta"};
ostrstream ostra;
if(narg < 2)
cout << "ci vuole un DISPLAY sulla linea comando\n", exit(255);
M = narg > 2 ? atoi(args[2]) : 3,
maxp = narg > 3 ? atoi(args[3]) : 1000000,
m_startg(const_cast<char *>("multidisplay"), &(k=600), &(l=600)),
displa[0] = (char *)m_which_display(&k),
displa[1] = args[1],
m_window(&(k=0), &(l=FINESTRA_DOPPIA)),
m_frame(x, x+1, x+2, x+3);
if(!m_open_display(displa[1]))
{cout << "impossibile connessione col secondo display\n"; return 254;}
m_window(&(k=0), &(l=FINESTRA_DOPPIA)),
m_frame(x, x+1, x+2, x+3),
x[1] = x[3] = 0.33333333, x[5] = x[7] = 0.66666667;
for(l=0; l < 2; l++)
{m_select_display(displa[l], (int *)NULL);
for(k=1; k < 4; k++)
m_color(&k),
x[0] = x[6] = 0.125 + 0.25 * (k-1),
x[2] = x[4] = x[0] + 0.25,
m_polygon(x, &(n=4));}
m_loop_for_events(&(k=97), &(o=-1)),
x[0] = x[6] = 0.0, x[2] = x[4] = 1.0,
x[1] = x[3] = 0.7, x[5] = x[7] = 1.0;
{for(l=0; l < M*4 && abs(punteggio[0] - punteggio[1]) < maxp; l++)
{o = (l % 2) * ((((l%4)/2) % 4) == 0) + ((l+1)%2) * ((((l%4)/2) % 4) != 0),
m_select_display(displa[o], &(k=0)),
m_color(&(k=BIANCO)),
m_polygon(x, &n),
m_color(&(k=NERO));
if(l%2) m_text(const_cast<char *>("rispondi su un rettangolo"), t);
else m_text(const_cast<char *>("clicca su un rettangolo"), t);
m_redraw(&(k=0)),
m[1] = m[0] = 0.0;
while(m[1] < 0.33333333 || m[1] > 0.66666667 || m[0] < 0.125
|| m[0] >= 0.875) m_mouse(m);
m_color(&(k=BIANCO)),
m_polygon(x, &n),
m_color(&(k=NERO));
m_redraw(&(k=0)),
j[l%2] = (int)((m[0]-0.125)/0.25);
if(l%2) punteggio[((l-1)%4) == 0] += j[1] == j[0];
if(!((l+1) % 2))
{for(o=0; o < 2; o++)
m_select_display(displa[o], (int *)NULL),
m_color(&(k=BIANCO)),
m_polygon(x, &n),
m_color(&(k=NERO)),
ostra.seekp(0, ios :: beg),
ostra << punteggio[o] << ':' << punteggio[1-o] << '\0',
m_text(ostra.str(  ), t),
m_redraw(&(k=0));
m_select_display(displa[punteggio[0] >= punteggio[1]], (int *)NULL),
m_loop_for_events(&(k=97), &(o=-1));}}}
for(l=0; l < 2; l++)
m_select_display(displa[l], (int *)NULL),
m_color(&(k=BIANCO)),
m_polygon(x, &n),
m_color(&(k=NERO)),
m_text(const_cast<char *>(esito[(punteggio[l] <= punteggio[1-l])*
(1+(punteggio[l] == punteggio[1-l]))]), t),

m_redraw(&(k=0));
m_select_display(displa[punteggio[0] > punteggio[1]], (int *)NULL),
m_loop_for_events(&(k=97), &(l=-1)),
m_close_display((char *)m_which_display(&l)),
m_select_display(displa[1-l], (int *)NULL),
m_loop_for_events(&(k=97), &(l=-1));
m_endg(  );}

Questo programma presenta esempi d'uso di tutte le funzioni deputate alla gestione di DISPLAY multipli; per la verità la linea m_close_display(m_which_display(&l)), è solo dimostrativa e se ne sarebbe potuto fare tranquillamente a meno (in questo codice).
Il programma realizza uno stupidissimo gioco di "lettura del pensiero" in cui due giocatori scelgono alternativamente uno tra tre colori lasciando all'antagonista la facoltà di provare a indovinare quale colore sia stato scelto.
Il programma tiene conto dei punteggi e dichiara il vincitore; il gioco termina quando si verifica per primo uno di questi due eventi: o sono stati espletati M turni completi o uno dei due contendenti si è portato in vantaggio di almeno maxp punti. Nel primo caso è correttamente contemplata la possibilità di impattare.



torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"

















































































m_close_display(display)

È la "negazione" (o il "distruttore") di quanto realizzato da m_open_display; disconnette dall'applicazione il server che corrisponde alla stringa contenuta nell'unico argomento (del tutto omologo dell'argomento di m_open_display).
Se il server citato non esiste o non è connesso equivale a "nessuna operazione". Se viene completata con successo implica ovviamente la chiusura definitiva di tutte le finestre che erano state aperte sul server disconnesso. Per un esempio d'uso si rimanda a m_select_display.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



























































































m_which_display(quale)

Permette all'applicazione di conoscere in ogni momento quale server è correntemente attivo, sia restituendo nell'unico argomento di tipo int/INTEGER*4 l'indice ordinale (tra 0 e 7) del server corrente rispetto all'ordine cronologico di connessione, sia attraverso il valore di ritorno della funzione che è la stringa utilizzata all'atto della connessione come argomento di m_open_display.
La prima di queste due informazioni è la sola fruibile facilmente dai fortranisti (mal per loro). Per un esempio d'uso si rimanda a m_select_display.

torna a elenco funzioni

torna a funzioni grafiche a schermo

torna a funzioni grafiche PostScript

torna a funzioni grafiche "3D"



































































































Produzione di documentazione permanente

A parte la produzione di files PostScript incapsulati e l'impaginazione di più files PostScript sulla stessa pagina A4 (cfr tutte le routines col nome che termina in _ps e la routine mimpagina), la libreria è in grado anche di produrre files PostScript che siano copie conformi di quanto appare disegnato sulle finestre grafiche X11 (cfr. discussione sui files PostScript ombra e funzioni particolari associate alle routines m_mouse e m_loop_for_events) e perfino files di tipo gif (cfr. opzioni particolari della routine m_save_pixmap). Questi ultimi consentono di realizzare agevolmente animazioni di grande effetto.

torna daccapo










































































Problemi noti e possibili soluzioni

La quasi totalità delle operazioni della libreria è sicura. A parte limiti intrinseci, come l'inefficacia di tutte le funzioni che fanno appello a X11 quando non si lavora in tale ambiente, sono noti, al presente, i soli seguenti problemi concernenti:

  1. Le quotature dell'asse verticale sulla finestra grafica a video possono talvolta non comparire se sono più "lunghe" dello spazio che intercorre tra il bordo della finestra e la parte interna in cui viene effettuato il disegno: rimediabile facilmente o allargando il bordo o restringendo/eliminando le quotature.

  2. Per quanto concerne la grafica PostScript si segnala che la routine mimpagina_ps (praticamente in disuso, vista l'evoluzione dei moderni strumenti di gestione dei files PostScript) non calcola con precisione la BoundingBox.

  3. e che la funzione mscrivi_quasi_come_TeX_ps non giustifica correttamente a destra (se richiesto) quando la stringa fornita contiene degli spazi.

  4. Qualora si effettui con m_save_window il salvataggio di una finestra che ombreggiava un file PostScript, un'eventuale successiva esecuzione di m_load_window ripristina l'ombreggiatura su un file chiamato implicito_loadN ove N è il numero della finestra ombreggiata. Tuttavia potrebbe non esserci una corrispondenza assoluta tra i tokens con cui la finestra era stata salvata e quelli con cui il file PostScript viene rigenerato.
    Altresì può non esserci perfetta identità tra alcune caratteristiche "accessorie" della finestra sul monitor e le omologhe riportate all'interno del file PostScript ombra: si tratta segnatamente di spessore di linee, forma dei tratteggi e forma dei simboli. L'autore non ritiene di dovere sprecare tempo per aggiustare col calibro simili inezie.

  5. In generale, secondo il flusso esecutivo percorso dal programma, il codice PostScript generato dalla libreria può presentare qualche ridondanza non nociva, come ad esempio vane ripetizioni della selezione di un colore o inutili ricorrenze di coppie di comandi "gsave grestore". Anche in questo caso non si ritiene di dover intervenire, dato che il costo di un eventuale "post processo" del documento PostScript per espungerne cotali fanfaluche è di gran lunga eccessivo rispetto al beneficio che ne sarebbe tratto, e soprattutto in rapporto al danno NULLO che ne deriva.

  6. La presenza di legende in una figura NON VIENE, AL PRESENTE, CONSERVATA da m_save_window né nella finestra ricuperata con m_load_window né, a fortiori, in un eventuale file PostScript ombreggiato.



Infine, quantunque l'intervallo di validità delle variabili di tipo double in C o C++ raggiunga e superi l'ordine di grandezza 307, dato che la libreria usa per scopi interni variabili così "innaturalmente" grandi si suggerisce caldamente di evitare di trasferirle variabili "significative" per il proprio programma che abbiano valori superiori all'ordine di grandezza 304. Se qualcuno le avesse si studi qualche procedura di rinormalizzazione.

torna daccapo








































































Variabili d'ambiente

La libreria riconosce e utilizza alcune variabili d'ambiente proprie (oltre a quelle ovvie, come ad esempio DISPLAY). Tali variabili sono indicate nel presente documento assieme al loro significato e al loro valore default.

NOME DELLA VARIABILE VALORE DEFAULT FUNZIONE SVOLTA
PASSE_PAR_TOUT_TOGIF dipendente dal sistema fornire un programma di conversione da ppm a GIF ( m_save_pixmap)
PASSE_PAR_TOUT_COMANDO_MOVIE " fornire un metodo di generazione di animazioni ( m_mount_film)
PASSE_PAR_TOUT_ANIMAZIONI_VIETATE assente dall'ambiente inibisce, con la sua sola presenza, la generazione delle animazioni ( m_mount_film)
PASSE_PAR_TOUT_CINECITTA "/tmp/" cartella in cui sono scritti i files-fotogramma delle animazioni (m_write_photogram, m_mount_film)
torna daccapo









































































































Il più semplice programma (FUNZIONANTE)

Questo programma traccia una linea orizzontale a metà altezza in una finestra quadrata di 700 pixel di lato che rappresenta il quadrato di lato 1.0 del piano, e termina quando si digita il tasto "enter" mentre il puntatore del mouse sta all'interno della finestra.

# include <passe_par_tout.h>

int main(  )
{double xmin = 0.0, ymin = 0.0, xmax = 1.0, ymax = 1.0, x[2];
int K=700, L = 700;
m_startg(const_cast<char *>("esempio semplice"), &K, &L),
K = L = 95,
m_window(&K, &L),
m_frame(&xmin, &ymin, &xmax, &ymax),
x[0] = xmin, x[1] = 0.5,
m_move(x),
x[0] = xmax,
m_line(x),
L = EVENTO_ENTER,
m_wait_for_events(&L),
m_endg(  );}

torna daccapo

























































































Costanti predefinite

Per chi programma (lodevolmente) in C o C++ e quindi include il file passe_par_tout.h sono a disposizione un certo numero di costanti (dichiarate tramite direttive #define ) che possono essere usate con profitto in diversi contesti al posto dei valori numerici corrispondenti. Qui di seguito se ne riporta un elenco con indicati il contesto e il valore numerico (che resta l'unico modo di fruirne per chi programma (ahilui) in FORTRAN).

Resta inteso che, in base alle regole fondamentali della libreria, le citate costanti NON POSSONO ESSERE TRASFERITE DIRETTAMENTE ALLE FUNZIONI COME ARGOMENTI, ma devono essere assegnate per valore a puntatori a intero (da usare a loro volta come argomenti).

COSTANTI UTILI ALLA SCELTA DEL SIMBOLO
DA TRACCIARE (cfr. m_symbol)

nome valore
PUNTINO 0
PUNTONE 1
TONDINO_VUOTO2
TONDINO_PIENO3
QUADRETTO_VUOTO4
QUADRETTO_PIENO5
ROMBETTO_VUOTO6
ROMBETTO_PIENO7
ASTERISCO8
STELLINA_VUOTA9
STELLINA_PIENA10
CROCETTA11
CROCE_S_ANDREA12
QUADRO_E_CROCE13
TRIANGOLO_VUOTO14
TRIANGOLO_PIENO15
NABLA_VUOTO16
NABLA_PIENO17
PENTAGONO_VUOTO18
PENTAGONO_PIENO19
PENTAGONO_DRITTO_VUOTO20
PENTAGONO_DRITTO_PIENO21
ESAGONO_VUOTO22
ESAGONO_PIENO23
ESAGONO_RUOTATO_VUOTO24
ESAGONO_RUOTATO_PIENO25
OTTAGONO_VUOTO26
OTTAGONO_PIENO27
STELLA_DI_DAVIDE_VUOTA28
STELLA_DI_DAVIDE_PIENA29
NIDO_D_APE_VUOTO30
NIDO_D_APE_PIENO31
CUSTOM_VUOTO42
CUSTOM_PIENO43
CIFRA_048 oppure '0'
CIFRA_149 oppure '1'
CIFRA_250 oppure '2'
CIFRA_351 oppure '3'
CIFRA_452 oppure '4'
CIFRA_553 oppure '5'
CIFRA_654 oppure '6'
CIFRA_755 oppure '7'
CIFRA_856 oppure '8'
CIFRA_957 oppure '9'



COSTANTI UTILI ALLA COLLOCAZIONE DELLE LEGENDE (cfr. m_legend)

nomevalore
DA_QUI_A_SINISTRA_ALTO0
DA_QUI_A_DESTRA_BASSO1
DA_QUI_A_DESTRA_ALTO2
DA_QUI_A_SINISTRA_BASSO3
DA_SINISTRA_ALTO4
DA_DESTRA_ALTO5
DA_DESTRA_BASSO6
DA_SINISTRA_BASSO7



COSTANTI UTILI AL BITMASKING CONNESSO
CON LE LEGENDE (cfr. m_legend)

nomevalore
COLORA_RIQUADRO0x20000000
RIQUADRO_OPACO0x40000000
RICHIEDO_LEGENDA0x800000
RIDUCI_FONTE0x10000000



COSTANTI UTILI ALLA SELEZIONE DI CLASSI DI BITMAP
(cfr. mclasse_bitmap)

nomevalore
GRIGIO_22
GRIGIO_44
GRIGIO_88
COLORE_1-1
COLORE_2-2
COLORE_4-4
COLORE_8-8



COSTANTI UTILI ALLA SELEZIONE DEGLI INDICI DEI
COLORI FONDAMENTALI (cfr. m_color e mcolore_ps)

nomevalore
NERO0
ROSSO1
VERDE2
BLU4
GIALLO3
CIANO6
MAGENTA5
BIANCO7



COSTANTI PER RILEVAMENTO DI EVENTI CON MODIFICATORI (cfr. m_modified_key_events)

nomevalore
CONTROL_L0x100
CONTROL_R0x200
CONTROL_A0x300
ALT_L0x400
ALT_R0x800
ALT_A0xc00



COSTANTI PER IDENTIFICARE I TASTI FRECCIA (cfr. m_loop_for_events)

nomevalore
FRECCIA_ALTO127
FRECCIA_DESTRA128
FRECCIA_BASSO129
FRECCIA_SINISTRA130



COSTANTI PER RILEVAMENTO DI EVENTI BASE (cfr. m_wait_for_events)

nomevalore
EVENTO_MOUSE0
EVENTO_ENTER999



COSTANTE PER ATTIVAZIONE DEL DOUBLE BUFFERING (cfr. m_window)

nomevalore
FINESTRA_DOPPIA0x400000



COSTANTE PER ATTIVAZIONE DELLE TRASPARENZE (cfr. m_opacity)

nomevalore
ATTIVA_TRASPARENZA0x800



COSTANTE PER OPACIZZAZIONE DELLO SFONDO (cfr. m_opacity)

nomevalore
SFONDO_OPACO0x1



COSTANTI PER MODALITÀ DELLE ANIMAZIONI (cfr. m_animate)

nomevalore
ORDINE_NATURALE0xffffffff
A_RITROSO0xefffffff
A_CASACCIO0xdfffffff
FOTOGRAMMA_PER_FOTOGRAMMA0xcfffffff
FOTOGRAMMA_PER_FOTOGRAMMA_A_ROVESCIO0xbfffffff
DA_FOTOGRAMMA_A_FOTOGRAMMA0xafffffff
ASPETTA_ORDINI0x9fffffff



COSTANTI PER I COLORI DELLA TASTIERA (cfr. m_animate)

nomevalore
RISALTO0x100
STOP0x200
PLAY0x300
REPLAY0x400
FRECCE0x500
STELLA0x600
MOVIOLA0x700
REMOVIOLA0x800
TIMELINE0x900
SFONDO0xa00
START0xb00
END0xc00
CORRENTE0xd00
CURSORE0xe00
XSTOP0xf00



COSTANTE PER ATTIVAZIONE DEL FILE POSTSCRIPT OMBRA (cfr. m_window)

nomevalore
OMBREGGIA_FINESTRA0x80000000



COSTANTE PER TITOLI PS ADERENTI ALL'ASSE VERTICALE
(cfr. mquotature_ps)

nomevalore
ADERISCI_ASSE_SINISTRO0x40000000



COSTANTI CONNESSE AL WIDGET SET (cfr. ivi)

torna daccapo
















































































































Interazioni con mouse e tastiera

Il gestore di eventi interno della libreria viene attivato ogni volta che si eseguono le funzioni m_mouse, m_mouse_int, m_loop_for_events, m_string_for_events e m_wait_for_events (cfr. le descrizioni di ciascuna delle funzioni citate).
Ognuna di queste funzioni viene interrotta da un particolare evento, come riportato nelle loro descrizioni, restituendo il controllo al programma chiamante, ma ciò ovviamente non vuol dire che non vengano riconosciuti e processati anche altri eventi, in attesa che si verifichi quello che le interrompe.

In particolare, la pressione del tasto '?' (punto di domanda) sulla finestra che detiene l'"input focus" implica che ogni susseguente movimento del puntatore del mouse entro quella finestra faccia comparire, al posto del titolo, le coordinate utente del punto su cui esso si trova.

Quando tale finestra perde l'"input focus" il titolo originale viene automaticamente ripristinato, mentre appena la finestra lo riottiene la visualizzazione delle coordinate correnti al posto del titolo riprende e così di seguito.

Va osservato che la percezione dell'evento di uscita dalla funzione "bloccante" è sospesa finché non si digita da tastiera una '/' (slash, posto sotto il punto interrogativo nella tastiera USA/ascii), naturalmente in una fase in cui la finestra detiene l'"input focus".

La questione dell'attribuzione dell'input focus a una finestra potrebbe essere delicata, in quanto dipende dalle transazioni con il window manager in uso e quindi la libreria si comporta diversamente (sotto questo solo punto di vista) secondo il window manager in esercizio e i protocolli standard con esso stabiliti (si ricorda che la libreria NON instaura alcun proprio protocollo col window manager).

Per spostare l'input focus da una finestra a un'altra ci sono essenzialmente due metodi (protocolli) che coinvolgono entrambi il mouse: si tratta di focus on enter e focus on click (il cui significato dovrebbe essere intuitivo). Altrettanto dovrebbe ora apparire intuitivo perché viene sospesa la percezione dell'evento di uscita: infatti se il protocollo fosse focus on click lo stesso evento che cagiona il cambio di focus farebbe anche ritornare la funzione bloccante (se questa fosse ad esempio, m_mouse).

Ulteriori interazioni con mouse e tastiera sono descritte in maniera dettagliata nella documentazione delle funzioni che ne fanno uso specifico.

torna daccapo

Torna in cima alla pagina