/*==============================================================================
TAVOLA PITAGORICA
di Aldo Carpanelli
1.0 - agosto 2017
Compila in un file in formato svg una tavola pitagorica, con caratteristiche
personalizzabili tramite un file testuale di impostazioni.
Il file in uscita ha nome "Tavola pitagorica.svg" e viene creato nella stessa
cartella ove si trova l'eseguibile del programma, sovrascrivendo l'eventuale
file con lo stesso nome che li' si trovasse.
Il file delle impostazioni deve avere nome "impostazioni.txt" e trovarsi nella
cartella ove si trova l'eseguibile del programma. Se il file e' assente, il
programma funziona ugualmente, impiegando impostazioni predefinite.
Il file delle impostazioni deve contenere esattamente 12 righe, la prima delle
quali ("Tavola pitagorica 1.0 - impostazioni") viene usata come stringa di
identificazione, da NON modificare ne' sopprimere.
All'inizio di ogni riga successiva deve trovarsi il valore numerico sul quale si
desidera impostare una serie di 11 variabili globali. Quel che, sulla riga,
segue il numero e' irrilevante.
I primi 7 valori possono essere numeri positivi interi o decimali che
identificano rispettivamente:
- la larghezza del foglio
- l'altezza del foglio
- il margine superiore della pagina
- il margine inferiore della pagina
- il margine sinistro della pagina
- il margine destro della pagina
- lo spessore del bordo delle caselle della tabella
I 4 valori successivi devono essere numeri positivi interi in formato
esadecimale con un massimo di 8 cifre ciascuno e identificano rispettivamente:
- i limiti della tavola (da 1 a ?)
- il colore del bordo delle caselle in formato 00RRGGBB
- il colore dei numeri nelle caselle in formato 00RRGGBB
- un flag 0/1 che disattiva/attiva la bordatura del foglio
==============================================================================*/
#include <stdio.h>
#include "impostazioni.h"
extern const char kNomeFileImpostazioni[];
const char kNomeFileOutput[] = "Tavola pitagorica.svg";
extern impostazioni_t imp;
/* prototipi delle funzioni */
void tavola_pitagorica( FILE *f, unsigned int q );
/* definizioni delle funzioni */
int main() {
FILE *fTavola = NULL;
if( !carica_impostazioni(kNomeFileImpostazioni) ) {
printf( "File delle impostazioni non valido,\n"
"uso i valori preimpostati.\n\n" );
}
fTavola = fopen( kNomeFileOutput, "w+" );
if( fTavola ) {
tavola_pitagorica( fTavola, imp.dimTavola );
printf( "Operazioni completate con successo.\n" );
printf( " Verifica il file \"%s\"\n"
" nella stessa cartella del programma.\n\n",
kNomeFileOutput );
} else printf( "Errore: file non aperto.\n\n" );
printf( "Premi \"invio\" per lasciare il programma... " );
getchar();
return 0;
}
/* chiamata da tavola_pitagorica() */
size_t calcola_quantita_cifre( size_t numero, size_t base ) {
size_t qc = 1; /* "qc" = quantita' delle cifre */
while( numero /= base ) ++qc;
return qc;
}
/* chiamata da tavola_pitagorica() */
int intesta_file_svg( FILE *f ) {
if( f ) {
fprintf( f, "<?xml version=\"1.0\" standalone=\"no\"?>\n" );
fprintf( f, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http:"
"//www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n\n" );
fprintf( f, "<svg viewBox=\"0 0 %.0f %.0f\" version=\"1.1\""
" xmlns=\"http://www.w3.org/2000/svg\""
" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\n",
imp.wFoglio, imp.hFoglio );
fprintf( f, "<desc>Creato da \"Tavole pitagoriche 1.0\"</desc>\n\n" );
return 1;
}
return 0;
}
/* chiamata da traccia_riquadri() */
void intesta_gruppo_riquadri( FILE *f ) {
fprintf( f, "<g id=\"riquadri\"" );
fprintf( f, " transform=\"translate(%.2f %.2f)\"", imp.margSx, imp.margSup );
fprintf( f, " fill=\"none\"" );
fprintf( f, " stroke=\"#%06lx\"", imp.colGriglia );
fprintf( f, " stroke-width=\"%.2f\"", imp.spGriglia );
fprintf( f, ">\n" );
}
/* chiamata da tavola_pitagorica() */
void traccia_riquadri( FILE *f, unsigned int q, float dimCas ) {
float x, y;
int i, j;
intesta_gruppo_riquadri( f );
for( y=0.0f, i=0; i<q; ++i ) {
for( x=0.0f, j=0; j<q; ++j ) {
fprintf( f, "\t<rect x=\"%.2f\"", x );
fprintf( f, " y=\"%.2f\"", y );
fprintf( f, " width=\"%.2f\"", dimCas );
fprintf( f, " height=\"%.2f\"", dimCas );
fprintf( f, " />\n" );
x += dimCas;
}
y += dimCas;
}
fprintf( f, "</g>\n\n" ); /* chiude */
}
/* chiamata da traccia_numeri() */
void intesta_gruppo_numeri( FILE *f, float dimCas, float dimFont ) {
fprintf( f, "<g id=\"numeri\"" );
fprintf( f, " transform=\"translate(%.2f %.2f)\"",
imp.margSx+dimCas*0.5f, imp.margSup+(dimCas+dimFont*0.705f)*0.5f );
fprintf( f, " fill=\"#%06lX\"", imp.colNumeri );
fprintf( f, " stroke=\"none\"" );
fprintf( f, " font-family=\"sans-serif\"" );
fprintf( f, " font-size=\"%.2f\"", dimFont );
fprintf( f, " text-anchor=\"middle\"" );
fprintf( f, ">\n" );
}
/* chiamata da tavola_pitagorica() */
void traccia_numeri( FILE *f, unsigned int q, float dimCas, float dimFont ) {
float x, y;
int i, j;
intesta_gruppo_numeri( f, dimCas, dimFont );
for( y=0.0f, i=0; i<q; ++i ) {
for( x=0.0f, j=0; j<q; ++j ) {
fprintf( f, "\t<text x=\"%.2f\"", x );
fprintf( f, " y=\"%.2f\"", y );
fprintf( f, ">%d</text>\n", (j+1)*(i+1) );
x += dimCas;
}
y += dimCas;
}
fprintf( f, "</g>\n" ); /* chiude */
}
/* chiamata da tavola_pitagorica() */
int riquadra_foglio( FILE *f ) {
if( f ) {
fprintf( f, "\n<rect x=\"%.2f\"", imp.spGriglia*0.25f );
fprintf( f, " y=\"%.2f\"", imp.spGriglia*0.25f );
fprintf( f, " width=\"%.2f\"", imp.wFoglio-imp.spGriglia*0.5f );
fprintf( f, " height=\"%.2f\"", imp.hFoglio-imp.spGriglia*0.5f );
fprintf( f, " fill=\"none\"" );
fprintf( f, " stroke=\"#666\"" );
fprintf( f, " stroke-width=\"%.2f\"", imp.spGriglia*0.5f );
fprintf( f, " opacity=\"0.5\"" );
fprintf( f, " />\n\n" );
return 1;
}
return 0;
}
/* chiamata da tavola_pitagorica() */
int termina_file_svg( FILE *f ) {
if( f ) {
fprintf( f, "</svg>\n" );
return 1;
}
return 0;
}
/* chiamata da main() */
void tavola_pitagorica( FILE *f, unsigned int q ) {
size_t qCifre = calcola_quantita_cifre( q*q, 10 );
float wPag = imp.wFoglio-(imp.margDx+imp.margSx);
float hPag = imp.hFoglio-(imp.margSup+imp.margInf);
float dimCas = (wPag<hPag) ?
(wPag-2.0f*imp.spGriglia)/q :
(hPag-2.0f*imp.spGriglia)/q;
float dimFont = dimCas/((float)qCifre)*1.25f;
intesta_file_svg( f );
traccia_riquadri( f, q, dimCas );
traccia_numeri( f, q, dimCas, dimFont );
if( imp.riquadraFoglio ) riquadra_foglio( f );
termina_file_svg( f );
}