Pur utili in molte circostanze, è spesso facile osservare che la distanza fra i caratteri non è sempre uniforme.
La ragione risiede nella peculiarità dei caratteri ttf la cui dimensione, specie orizzontale, varia per ogni lettera mentre i caratteri incorporati GD hanno larghezza fissa, secondo la tabella seguente.
Numero font 1 2 3 4 5
Larghezza 5 6 7 8 9
Altezza 6 8 13 15 15
Quando, usando i caratteri ttf, le esigenze richiedono una formattazione giustificata occorre fare ricorso alla funzione
imagettfbbox() per misurare le dimensioni dei caratteri ed assegnare lo spazio/arco di conseguenza.
Questo script, utilizzando questo tipo di font, ne misura la larghezza, disegnandoli poi in modo proporzionale su di una circonferenza.
Del disegno si occupano tre funzioni.
Frase_TTF_SuCirconferenza(), si occupa del disegno secondo i parametri che le vengono passati
DimensioneOrizzontaleCarattere(), misura la dimensione di ciascun carattere
GeneraColori(), crea i colori per mettere in evidenza l'operazione.
Non strettamente necessaria, ha solo scopo esemplificativo delle dimensioni e proporzioni.
Il nome delle variabili è autesplicativo ed il copdice interamente commentato.
<?php
// calcola dimensione di ciascun carattere per fare spaziatura nella circonferenza
// paragonato ad un grafico a torta
// ogni carattere è uno spicchio di diemnsioni diverse
function DimensioneOrizzontaleCarattere($text, $font, $size) {
// angolazione è sempre zero
// dimensioni del carattere/testo
$box =
imagettfbbox($size, 0, $font, $text);
$DimXcarattere = abs(max($box[2], $box[4])); // dimensione orizzontale
$DimYcarattere = abs(max($box[5], $box[7])); // dimensione verticale
return $DimXcarattere;
}
function GeneraColori($Numero) {
$Num32exa = md5('color' . $Numero); // Restituisce come numero esadecimale di 32 cifre.
// preleva codici per colore, crea e restituisce array come r g b
return array(hexdec(substr($Num32exa, 0, 2)), hexdec(substr($Num32exa, 2, 2)), hexdec(substr($Num32exa, 4, 2)));
}
function Frase_TTF_SuCirconferenza($Immagine,$Raggio, $Cx, $Cy,$Font,$FontDim,$Frase, $ArcoInizio,$ArcoGradi,$LetteraInclinazione){
// acquisisce dimensione orizzontale di ogni carattere della frase
// e lo inserisce nella variabile array $Valori
$Valori = array (); // totale valori rappresentati
// foreach($Frase as $text )
for($L = 0; $L < strlen($Frase); $L ++){
$Valori[$L] = DimensioneOrizzontaleCarattere($Frase[$L], $Font, $FontDim);;
};
$Totale = array_sum($Valori); // totale quintali rappresentati
$Colori = array();
$ColoreIniziale = 18;
for($i=$ColoreIniziale; $i < ($ColoreIniziale+ count($Valori)); $i++)
{$ColoreRGB = GeneraColori($i , $ColoreIniziale+ count($Valori)); // genera colori
$Colori[] =
imagecolorallocate($Immagine, $ColoreRGB[0], $ColoreRGB[1], $ColoreRGB[2]);
}
$SL = .70; // Spostamento lettere
foreach($Valori as $index => $V ) { // scorre array $Valori e $Colori, disegnando gli archi
$Arco = number_format(($ArcoGradi * $V) / $Totale); // dimensioni angolo/arco corrente
imagefilledarc($Immagine,
$Cx, $Cy, // coordinate x,y del centro
$Raggio, $Raggio,
$ArcoInizio,
($ArcoInizio + $Arco), // fine arco
$Colori[$index], // colore corrente
IMG_ARC_PIE // Connette angoli, area circoscritta è riempita con $Colori[$index]
);
// *** calcola X,Y sul piano cartesiano dei vertici archi per legenda circolare ***
$VerticeArco = ($ArcoInizio + $Arco/2) + 90; // primo arco inizio ore 3
// seno e coseno in radianti
$sin = sin(deg2rad($VerticeArco)); $cos = cos(deg2rad($VerticeArco));
$RadX = round($cos*(0) - $sin*($Raggio * $SL * -1)); // Vertice arco corrente, X su cartesiano
$RadY = round($sin*(0) + $cos*($Raggio * $SL * -1)); // Vertice arco corrente, Y su cartesiano
// scrive lettere intorno alla circonferenza
imagettftext ($Immagine,
$FontDim, // dimensione font
$ArcoGradi/2 - $LetteraInclinazione, // inclinazioen font
$Cx + $RadX, $Cy + $RadY, // posizione su cartesiano
$Colori[$index], // colore corrente
$Font,
$Frase[$index]); /// $index è la posizione della lettera all'interno della frase
$ArcoInizio += $Arco; // inizio nuovo arco
$LetteraInclinazione = $LetteraInclinazione + $Arco; // nuova inclinazione lettera
// segmento grafico/testo, , comando a scopo esplicativo può essere cancellato
imageline ($Immagine, $Cx , $Cy , $Cx + $RadX , $Cy + $RadY , $Colori[$index] );// segmento grafico/testo
}}
$Larghezza = 500; $Altezza = $Larghezza;
$Immagine =
imagecreate($Larghezza, $Altezza);
imagecolorallocate($Immagine, 254, 254, 233); // sfondo
$Raggio = $Larghezza * .6;
$Cx = $Larghezza * .5; $Cy = $Cx; // centro x,y
$Font = "font/arial.ttf";
$FontDim = 18;
$Frase = utf8_decode('AaBbCcDdEeFfGgHhIiLjMkNlOmPnQoRpSqTrUsVtXuYvZwaxbycz');
if(strlen($Frase) > 52){$Frase = substr($Frase,0,51);}; // numero massimo caratteri ammessi
$ArcoInizio = 180; // valore in gradi inizio primo arco, zero corrisponde a ore 3
$ArcoGradi = 360; // ampiezza arco sul quale disegnare le lettere
$LetteraInclinazione = 90;
Frase_TTF_SuCirconferenza($Immagine,$Raggio,$Cx,$Cy,$Font,$FontDim,$Frase,$ArcoInizio,$ArcoGradi,$LetteraInclinazione);
header("Content-Type: image/png");
imagepng($Immagine,"NomeFile.png"); // salva immagine
imagepng($Immagine); // al browser
imagedestroy($Immagine); // libera memoria
?>