$lettre - $code";
if (($code >= 54928 && $code <= 56767) || ($code >= 15707294 && $code <= 15711164)) {
$rtl = true;
} else {
$rtl = false;
}
if ($lettre == "٠" || $lettre == "١" || $lettre == "٢" || $lettre == "٣" || $lettre == "٤" || $lettre == "٥"
|| $lettre == "٦" || $lettre == "٧" || $lettre == "٨" || $lettre == "٩"
) {
$rtl = false;
}
if ($ponctuation[$lettre]) {
# le truc mega casse-gueule de l'inversion unicode:
# traiter le sens de placement en fonction de la lettre precedente
# (et non automatiquement le rtl_global)
$rtl = $rtl_prec;
if ($rtl) {
switch ($lettre) {
case "(":
$lettre = ")";
break;
case ")":
$lettre = "(";
break;
case "«":
$lettre = "»";
break;
case "»":
$lettre = "«";
break;
case "“":
$lettre = "”";
break;
case "”":
$lettre = "“";
break;
}
}
}
if ($rtl) {
$res = $lettre . $res;
} else {
$res = $res . $lettre;
}
$rtl_prec = $rtl;
}
return $res;
}
// https://code.spip.net/@rtl_visuel
function rtl_visuel($texte, $rtl_global) {
// hebreu + arabe: 54928 => 56767
// hebreu + presentation A: 15707294 => 15710140
// arabe presentation: 15708336 => 15711164
# echo hexdec("efb7bc");
// premiere passe pour determiner s'il y a du rtl
// de facon a placer ponctuation et mettre les mots dans l'ordre
$arabic_letters = array(
array(
"ي", // lettre 0
"ﻱ", // isolee 1
"ﻳ", // debut 2
"ﻴ", // milieu 3
"ﻲ"
),
array(
"ب", // lettre 0
"ﺏ", // isolee 1
"ﺑ", // debut 2
"ﺒ", // milieu 3
"ﺐ"
),
array(
"ا", // lettre 0
"ا", // isolee 1
"ﺍ", // debut 2
"ﺍ", // milieu 3
"ﺎ"
),
array(
"إ", // lettre 0
"إ", // isolee 1
"إ", // debut 2
"ﺈ", // milieu 3
"ﺈ"
),
array(
"ل", // lettre 0
"ﻝ", // isolee 1
"ﻟ", // debut 2
"ﻠ", // milieu 3
"ﻞ"
),
array(
"خ", // lettre 0
"ﺥ", // isolee 1
"ﺧ", // debut 2
"ﺨ", // milieu 3
"ﺦ"
),
array(
"ج", // lettre 0
"ﺝ", // isolee 1
"ﺟ", // debut 2
"ﺠ", // milieu 3
"ﺞ"
),
array(
"س", // lettre 0
"ﺱ", // isolee 1
"ﺳ", // debut 2
"ﺴ", // milieu 3
"ﺲ"
),
array(
"ن", // lettre 0
"ﻥ", // isolee 1
"ﻧ", // debut 2
"ﻨ", // milieu 3
"ﻦ"
),
array(
"ش", // lettre 0
"ﺵ", // isolee 1
"ﺷ", // debut 2
"ﺸ", // milieu 3
"ﺶ"
),
array(
"ق", // lettre 0
"ﻕ", // isolee 1
"ﻗ", // debut 2
"ﻘ", // milieu 3
"ﻖ"
),
array(
"ح", // lettre 0
"ﺡ", // isolee 1
"ﺣ", // debut 2
"ﺤ", // milieu 3
"ﺢ"
),
array(
"م", // lettre 0
"ﻡ", // isolee 1
"ﻣ", // debut 2
"ﻤ", // milieu 3
"ﻢ"
),
array(
"ر", // lettre 0
"ر", // isolee 1
"ﺭ", // debut 2
"ﺮ", // milieu 3
"ﺮ"
),
array(
"ع", // lettre 0
"ع", // isolee 1
"ﻋ", // debut 2
"ﻌ", // milieu 3
"ﻊ"
),
array(
"و", // lettre 0
"و", // isolee 1
"ﻭ", // debut 2
"ﻮ", // milieu 3
"ﻮ"
),
array(
"ة", // lettre 0
"ة", // isolee 1
"ة", // debut 2
"ﺔ", // milieu 3
"ﺔ"
),
array(
"ف", // lettre 0
"ﻑ", // isolee 1
"ﻓ", // debut 2
"ﻔ", // milieu 3
"ﻒ"
),
array(
"ﻻ", // lettre 0
"ﻻ", // isolee 1
"ﻻ", // debut 2
"ﻼ", // milieu 3
"ﻼ"
),
array(
"ح", // lettre 0
"ﺡ", // isolee 1
"ﺣ", // debut 2
"ﺤ", // milieu 3
"ﺢ"
),
array(
"ت", // lettre 0
"ﺕ", // isolee 1
"ﺗ", // debut 2
"ﺘ", // milieu 3
"ﺖ"
),
array(
"ض", // lettre 0
"ﺽ", // isolee 1
"ﺿ", // debut 2
"ﻀ", // milieu 3
"ﺾ"
),
array(
"ك", // lettre 0
"ك", // isolee 1
"ﻛ", // debut 2
"ﻜ", // milieu 3
"ﻚ"
),
array(
"ه", // lettre 0
"ﻩ", // isolee 1
"ﻫ", // debut 2
"ﻬ", // milieu 3
"ﻪ"
),
array(
"ي", // lettre 0
"ي", // isolee 1
"ﻳ", // debut 2
"ﻴ", // milieu 3
"ﻲ"
),
array(
"ئ", // lettre 0
"ﺉ", // isolee 1
"ﺋ", // debut 2
"ﺌ", // milieu 3
"ﺊ"
),
array(
"ص", // lettre 0
"ﺹ", // isolee 1
"ﺻ", // debut 2
"ﺼ", // milieu 3
"ﺺ"
),
array(
"ث", // lettre 0
"ﺙ", // isolee 1
"ﺛ", // debut 2
"ﺜ", // milieu 3
"ﺚ"
),
array(
"ﻷ", // lettre 0
"ﻷ", // isolee 1
"ﻷ", // debut 2
"ﻸ", // milieu 3
"ﻸ"
),
array(
"د", // lettre 0
"ﺩ", // isolee 1
"ﺩ", // debut 2
"ﺪ", // milieu 3
"ﺪ"
),
array(
"ذ", // lettre 0
"ﺫ", // isolee 1
"ﺫ", // debut 2
"ﺬ", // milieu 3
"ﺬ"
),
array(
"ط", // lettre 0
"ﻁ", // isolee 1
"ﻃ", // debut 2
"ﻄ", // milieu 3
"ﻂ"
),
array(
"آ", // lettre 0
"آ", // isolee 1
"آ", // debut 2
"ﺂ", // milieu 3
"ﺂ"
),
array(
"أ", // lettre 0
"أ", // isolee 1
"أ", // debut 2
"ﺄ", // milieu 3
"ﺄ"
),
array(
"ؤ", // lettre 0
"ؤ", // isolee 1
"ؤ", // debut 2
"ﺆ", // milieu 3
"ﺆ"
),
array(
"ز", // lettre 0
"ز", // isolee 1
"ز", // debut 2
"ﺰ", // milieu 3
"ﺰ"
),
array(
"ظ", // lettre 0
"ظ", // isolee 1
"ﻇ", // debut 2
"ﻈ", // milieu 3
"ﻆ"
),
array(
"غ", // lettre 0
"غ", // isolee 1
"ﻏ", // debut 2
"ﻐ", // milieu 3
"ﻎ"
),
array(
"ى", // lettre 0
"ى", // isolee 1
"ﯨ", // debut 2
"ﯩ", // milieu 3
"ﻰ"
),
array(
"پ", // lettre 0
"پ", // isolee 1
"ﭘ", // debut 2
"ﭙ", // milieu 3
"ﭗ"
),
array(
"چ", // lettre 0
"چ", // isolee 1
"ﭼ", // debut 2
"ﭽ", // milieu 3
"ﭻ"
)
);
if (init_mb_string() and mb_regex_encoding() !== "UTF-8") {
echo "Attention: dans php.ini, il faut indiquer:
mbstring.internal_encoding = UTF-8";
}
$texte = explode(" ", $texte);
foreach ($texte as $mot) {
$res = "";
// Inserer des indicateurs de debut/fin
$mot = "^" . $mot . "^";
$mot = preg_replace(", ,u", " ", $mot);
$mot = preg_replace(",«,u", "«", $mot);
$mot = preg_replace(",»,u", "»", $mot);
// ponctuations
$ponctuations = array("/", "-", "«", "»", "“", "”", ",", ".", " ", ":", ";", "(", ")", "،", "؟", "?", "!", " ");
foreach ($ponctuations as $ponct) {
$mot = str_replace("$ponct", "^$ponct^", $mot);
}
// lettres forcant coupure
$mot = preg_replace(",ا,u", "ا^", $mot);
$mot = preg_replace(",د,u", "د^", $mot);
$mot = preg_replace(",أ,u", "أ^", $mot);
$mot = preg_replace(",إ,u", "إ^", $mot);
$mot = preg_replace(",أ,u", "أ^", $mot);
$mot = preg_replace(",ر,u", "ر^", $mot);
$mot = preg_replace(",ذ,u", "ذ^", $mot);
$mot = preg_replace(",ز,u", "ز^", $mot);
$mot = preg_replace(",و,u", "و^", $mot);
$mot = preg_replace(",و,u", "و^", $mot);
$mot = preg_replace(",ؤ,u", "ؤ^", $mot);
$mot = preg_replace(",ة,u", "ة^", $mot);
// $mot = preg_replace(",ل,u", "^ل", $mot);
// $mot = preg_replace(",,", "^", $mot);
$mot = preg_replace(",٠,u", "^٠^", $mot);
$mot = preg_replace(",١,u", "^١^", $mot);
$mot = preg_replace(",٢,u", "^٢^", $mot);
$mot = preg_replace(",٣,u", "^٣^", $mot);
$mot = preg_replace(",٤,u", "^٤^", $mot);
$mot = preg_replace(",٥,u", "^٥^", $mot);
$mot = preg_replace(",٦,u", "^٦^", $mot);
$mot = preg_replace(",٧,u", "^٧^", $mot);
$mot = preg_replace(",٨,u", "^٨^", $mot);
$mot = preg_replace(",٩,u", "^٩^", $mot);
// Ligatures
$mot = preg_replace(",لا,u", "ﻻ", $mot);
$mot = preg_replace(",لأ,u", "ﻷ", $mot);
foreach ($arabic_letters as $a_l) {
$mot = preg_replace(",([^\^])" . $a_l[0] . "([^\^]),u", "\\1" . $a_l[3] . "\\2", $mot);
$mot = preg_replace(",\^" . $a_l[0] . "([^\^]),u", "^" . $a_l[2] . "\\1", $mot);
$mot = preg_replace(",([^\^])" . $a_l[0] . "\^,u", "\\1" . $a_l[4] . "^", $mot);
// il semble qu'il ne soit pas necessaire de remplacer
// la lettre isolee
// $mot = preg_replace(",\^".$a_l[0]."\^,u", "^".$a_l[1]."^", $mot);
}
$mot = preg_replace(",\^,u", "", $mot);
$res = $mot;
$res = rtl_reverse($mot, $rtl_global);
/*
$rtl = false;
for ($i = 0; $i < spip_strlen($mot); $i++) {
$lettre = spip_substr($mot, $i, 1);
$code = rtl_mb_ord($lettre);
if (($code >= 54928 && $code <= 56767) || ($code >= 15708336 && $code <= 15711164)) $rtl = true;
}
*/
if ($rtl_global) {
$retour = $res . " " . $retour;
} else {
$retour = $retour . " " . $res;
}
}
return $retour;
}
// https://code.spip.net/@printWordWrapped
function printWordWrapped(
$image,
$top,
$left,
$maxWidth,
$font,
$couleur,
$text,
$textSize,
$align = "left",
$hauteur_ligne = 0
) {
static $memps = array();
$fontps = false;
// imageftbbox exige un float, et settype aime le double pour php < 4.2.0
settype($textSize, 'double');
// calculer les couleurs ici, car fonctionnement different selon TTF ou PS
$black = imagecolorallocatealpha($image, hexdec("0x{" . substr($couleur, 0, 2) . "}"),
hexdec("0x{" . substr($couleur, 2, 2) . "}"), hexdec("0x{" . substr($couleur, 4, 2) . "}"), 0);
$grey2 = imagecolorallocatealpha($image, hexdec("0x{" . substr($couleur, 0, 2) . "}"),
hexdec("0x{" . substr($couleur, 2, 2) . "}"), hexdec("0x{" . substr($couleur, 4, 2) . "}"), 127);
// Gaffe, T1Lib ne fonctionne carrement pas bien des qu'on sort de ASCII
// C'est dommage, parce que la rasterisation des caracteres est autrement plus jolie qu'avec TTF.
// A garder sous le coude en attendant que ca ne soit plus une grosse bouse.
// Si police Postscript et que fonction existe...
if (
false and
strtolower(substr($font, -4)) == ".pfb"
and function_exists("imagepstext")
) {
// Traitement specifique pour polices PostScript (experimental)
$textSizePs = round(1.32 * $textSize);
if (!$fontps = $memps["$font"]) {
$fontps = imagepsloadfont($font);
// Est-ce qu'il faut reencoder? Pas testable proprement, alors...
// imagepsencodefont($fontps,find_in_path('polices/standard.enc'));
$memps["$font"] = $fontps;
}
}
$rtl_global = false;
for ($i = 0; $i < spip_strlen($text); $i++) {
$lettre = spip_substr($text, $i, 1);
$code = rtl_mb_ord($lettre);
if (($code >= 54928 && $code <= 56767) || ($code >= 15707294 && $code <= 15711164)) {
$rtl_global = true;
}
}
// split the text into an array of single words
$words = explode(' ', $text);
// les espaces
foreach ($words as $k => $v) {
$words[$k] = str_replace(array('~'), array(' '), $v);
}
if ($hauteur_ligne == 0) {
$lineHeight = floor($textSize * 1.3);
} else {
$lineHeight = $hauteur_ligne;
}
$dimensions_espace = imageftbbox($textSize, 0, $font, ' ', array());
if ($dimensions_espace[2] < 0) {
$dimensions_espace = imageftbbox($textSize, 0, $font, $line, array());
}
$largeur_espace = $dimensions_espace[2] - $dimensions_espace[0];
$retour["espace"] = $largeur_espace;
$line = '';
$lines = array();
while (count($words) > 0) {
$mot = $words[0];
if ($rtl_global) {
$mot = rtl_visuel($mot, $rtl_global);
}
$dimensions = imageftbbox($textSize, 0, $font, $line . ' ' . $mot, array());
$lineWidth = $dimensions[2] - $dimensions[0]; // get the length of this line, if the word is to be included
if ($lineWidth > $maxWidth) { // if this makes the text wider that anticipated
$lines[] = $line; // add the line to the others
$line = ''; // empty it (the word will be added outside the loop)
}
$line .= ' ' . $words[0]; // add the word to the current sentence
$words = array_slice($words, 1); // remove the word from the array
}
if ($line != '') {
$lines[] = $line;
} // add the last line to the others, if it isn't empty
$height = count($lines) * $lineHeight; // the height of all the lines total
// do the actual printing
$i = 0;
// Deux passes pour recuperer, d'abord, largeur_ligne
// necessaire pour alignement right et center
$largeur_max = 0;
foreach ($lines as $line) {
if ($rtl_global) {
$line = rtl_visuel($line, $rtl_global);
}
$dimensions = imageftbbox($textSize, 0, $font, $line, array());
$largeur_ligne = $dimensions[2] - $dimensions[0];
if ($largeur_ligne > $largeur_max) {
$largeur_max = $largeur_ligne;
}
}
foreach ($lines as $i => $line) {
if ($rtl_global) {
$line = rtl_visuel($line, $rtl_global);
}
$dimensions = imageftbbox($textSize, 0, $font, $line, array());
$largeur_ligne = $dimensions[2] - $dimensions[0];
if ($align == "right") {
$left_pos = $largeur_max - $largeur_ligne;
} else {
if ($align == "center") {
$left_pos = floor(($largeur_max - $largeur_ligne) / 2);
} else {
$left_pos = 0;
}
}
if ($fontps) {
$line = trim($line);
imagepstext($image, "$line", $fontps, $textSizePs, $black, $grey2, $left + $left_pos, $top + $lineHeight * $i, 0, 0, 0,
16);
} else {
imagefttext($image, $textSize, 0, $left + $left_pos, $top + $lineHeight * $i, $black, $font, trim($line), array());
}
}
$retour["height"] = $height;# + round(0.3 * $hauteur_ligne);
$retour["width"] = $largeur_max;
return $retour;
}
//array imagefttext ( resource image, float size, float angle, int x, int y, int col, string font_file, string text [, array extrainfo] )
//array imagettftext ( resource image, float size, float angle, int x, int y, int color, string fontfile, string text )
// https://code.spip.net/@produire_image_typo
function produire_image_typo() {
/*
arguments autorises:
$texte : le texte a transformer; attention: c'est toujours le premier argument, et c'est automatique dans les filtres
$couleur : la couleur du texte dans l'image - pas de dieze
$police: nom du fichier de la police (inclure terminaison)
$largeur: la largeur maximale de l'image ; attention, l'image retournee a une largeur inferieure, selon les limites reelles du texte
$hauteur_ligne: la hauteur de chaque ligne de texte si texte sur plusieurs lignes
(equivalent a "line-height")
$padding: forcer de l'espace autour du placement du texte; necessaire pour polices a la con qui "depassent" beaucoup de leur boite
$align: alignement left, right, center
*/
/**
* On définit les variables par défaut
*/
$variables_defaut = array(
'align' => false,
'police' => '',
'largeur' => 0,
'hauteur_ligne' => 0,
'padding' => 0,
);
// Recuperer les differents arguments
$numargs = func_num_args();
$arg_list = func_get_args();
$texte = $arg_list[0];
for ($i = 1; $i < $numargs; $i++) {
if (($p = strpos($arg_list[$i], "=")) !== false) {
$nom_variable = substr($arg_list[$i], 0, $p);
$val_variable = substr($arg_list[$i], $p + 1);
$variable["$nom_variable"] = $val_variable;
}
}
$variable = array_merge($variables_defaut, $variable);
// Construire requete et nom fichier
$text = str_replace(" ", "~", $texte);
$text = preg_replace(",(\r|\n)+,ms", " ", $text);
include_spip('inc/charsets');
$text = html2unicode(strip_tags($text));
if (strlen($text) == 0) {
return "";
}
$taille = $variable["taille"];
if ($taille < 1) {
$taille = 16;
}
$couleur = couleur_html_to_hex($variable["couleur"]);
if (strlen($couleur) < 6) {
$couleur = "000000";
}
$alt = $texte;
$align = $variable["align"];
if (!$variable["align"]) {
$align = "left";
}
$police = $variable["police"];
if (strlen($police) < 2) {
$police = "dustismo.ttf";
}
$largeur = $variable["largeur"];
if ($largeur < 5) {
$largeur = 600;
}
if ($variable["hauteur_ligne"] > 0) {
$hauteur_ligne = $variable["hauteur_ligne"];
} else {
$hauteur_ligne = 0;
}
if ($variable["padding"] > 0) {
$padding = $variable["padding"];
} else {
$padding = 0;
}
$string = "$text-$taille-$couleur-$align-$police-$largeur-$hauteur_ligne-$padding";
$query = md5($string);
$dossier = sous_repertoire(_DIR_VAR, 'cache-texte');
$fichier = "$dossier$query.png";
$flag_gd_typo = function_exists("imageftbbox")
&& function_exists('imageCreateTrueColor');
if (@file_exists($fichier)) {
$image = $fichier;
} else {
if (!$flag_gd_typo) {
return $texte;
} else {
$font = find_in_path('polices/' . $police);
if (!$font) {
spip_log(_T('fichier_introuvable', array('fichier' => $police)));
$font = find_in_path('polices/' . "dustismo.ttf");
}
$imgbidon = imageCreateTrueColor($largeur, 45);
$retour = printWordWrapped($imgbidon, $taille + 5, 0, $largeur, $font, $couleur, $text, $taille, 'left',
$hauteur_ligne);
$hauteur = $retour["height"];
$largeur_reelle = $retour["width"];
$espace = $retour["espace"];
imagedestroy($imgbidon);
$im = imageCreateTrueColor($largeur_reelle - $espace + (2 * $padding), $hauteur + 5 + (2 * $padding));
imagealphablending($im, false);
imagesavealpha($im, true);
// Creation de quelques couleurs
$grey2 = imagecolorallocatealpha($im, hexdec("0x{" . substr($couleur, 0, 2) . "}"),
hexdec("0x{" . substr($couleur, 2, 2) . "}"), hexdec("0x{" . substr($couleur, 4, 2) . "}"), 127);
ImageFilledRectangle($im, 0, 0, $largeur_reelle + (2 * $padding), $hauteur + 5 + (2 * $padding), $grey2);
// Le texte a dessiner
printWordWrapped($im, $taille + 5 + $padding, $padding, $largeur, $font, $couleur, $text, $taille, $align,
$hauteur_ligne);
// Utiliser imagepng() donnera un texte plus claire,
// compare a l'utilisation de la fonction imagejpeg()
_image_gd_output($im, array('fichier_dest' => $fichier, 'format_dest' => 'png'));
imagedestroy($im);
$image = $fichier;
}
}
$dimensions = getimagesize($image);
$largeur = $dimensions[0];
$hauteur = $dimensions[1];
return inserer_attribut("",
'alt', $alt);
}