From de726cae2f4c8010072b05e55a1f06edd4b53423 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 8 Dec 2008 20:28:38 +0000 Subject: [PATCH] Some small optimisations to speed up the color reduction algorithm... still a little bit slow for me ... git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@373 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- op_c.c | 156 +------- op_c.h | 2 +- operatio.c | 1 - pages.c | 1 + texte.c | 1020 ++++++++++++++++++++++++++-------------------------- 5 files changed, 521 insertions(+), 659 deletions(-) diff --git a/op_c.c b/op_c.c index b4326525..6f29f86b 100644 --- a/op_c.c +++ b/op_c.c @@ -370,29 +370,18 @@ void Cluster_Analyser(Cluster * c,Table_occurence * to) // On cherche les mins et les maxs de chaque composante sur la couverture -#ifdef OPTIMISATIONS_ASSEMBLEUR - - rmin=(c->rmin << to->dec_r); rmax=(c->rmax << to->dec_r); - vmin=(c->vmin << to->dec_v); vmax=(c->vmax << to->dec_v); - bmin=(c->bmin << to->dec_b); bmax=(c->bmax << to->dec_b); - OPASM_Analyser_cluster(to->table,&rmin,&vmin,&bmin,&rmax,&vmax,&bmax, - to->dec_r,to->dec_v,to->dec_b, - (1 << to->dec_r),(1 << to->dec_v),(1 << to->dec_b), - &c->occurences); - -#else - int nbocc; - rmin=c->rmax; rmax=c->rmin; - vmin=c->vmax; vmax=c->vmin; + // On prédécale tout pour éviter de faire trop de bazar en se forçant à utiliser TO_Get, plus rapide + rmin=c->rmax <<16; rmax=c->rmin << 16; + vmin=c->vmax << 8; vmax=c->vmin << 8; bmin=c->bmax; bmax=c->bmin; c->occurences=0; - for (r=c->rmin;r<=c->rmax;r++) - for (v=c->vmin;v<=c->vmax;v++) + for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) + for (v=c->vmin<<8;v<=c->vmax<<8;v+=1<<8) for (b=c->bmin;b<=c->bmax;b++) { - nbocc=TO_Get(to,r,v,b); + nbocc=to->table[r + v + b]; // TO_Get if (nbocc) { if (rrmin=rmin; c->rmax=rmax; - c->vmin=vmin; c->vmax=vmax; + c->rmin=rmin>>16; c->rmax=rmax>>16; + c->vmin=vmin>>8; c->vmax=vmax>>8; c->bmin=bmin; c->bmax=bmax; // On regarde la composante qui a la variation la plus grande @@ -456,18 +443,6 @@ void Cluster_Split(Cluster * c,Cluster * c1,Cluster * c2,int teinte,Table_occure cumul=0; if (teinte==0) { - -#ifdef OPTIMISATIONS_ASSEMBLEUR - - OPASM_Split_cluster_Rouge(to->table, - (c->rmin << to->dec_r),(c->vmin << to->dec_v), - (c->bmin << to->dec_b),(c->rmax << to->dec_r), - (c->vmax << to->dec_v),(c->bmax << to->dec_b), - (1 << to->dec_r),(1 << to->dec_v), - (1 << to->dec_b),limite,to->dec_r,&r); - -#else - for (r=c->rmin;r<=c->rmax;r++) { for (v=c->vmin;v<=c->vmax;v++) @@ -485,8 +460,6 @@ void Cluster_Split(Cluster * c,Cluster * c1,Cluster * c2,int teinte,Table_occure break; } -#endif - if (r==c->rmin) r++; // R est la valeur de d‚but du 2nd cluster @@ -508,17 +481,6 @@ void Cluster_Split(Cluster * c,Cluster * c1,Cluster * c2,int teinte,Table_occure if (teinte==1) { -#ifdef OPTIMISATIONS_ASSEMBLEUR - - OPASM_Split_cluster_Vert(to->table, - (c->rmin << to->dec_r),(c->vmin << to->dec_v), - (c->bmin << to->dec_b),(c->rmax << to->dec_r), - (c->vmax << to->dec_v),(c->bmax << to->dec_b), - (1 << to->dec_r),(1 << to->dec_v), - (1 << to->dec_b),limite,to->dec_v,&v); - -#else - for (v=c->vmin;v<=c->vmax;v++) { for (r=c->rmin;r<=c->rmax;r++) @@ -536,8 +498,6 @@ void Cluster_Split(Cluster * c,Cluster * c1,Cluster * c2,int teinte,Table_occure break; } -#endif - if (v==c->vmin) v++; // V est la valeur de d‚but du 2nd cluster @@ -558,17 +518,6 @@ void Cluster_Split(Cluster * c,Cluster * c1,Cluster * c2,int teinte,Table_occure else { -#ifdef OPTIMISATIONS_ASSEMBLEUR - - OPASM_Split_cluster_Bleu(to->table, - (c->rmin << to->dec_r),(c->vmin << to->dec_v), - (c->bmin << to->dec_b),(c->rmax << to->dec_r), - (c->vmax << to->dec_v),(c->bmax << to->dec_b), - (1 << to->dec_r),(1 << to->dec_v), - (1 << to->dec_b),limite,to->dec_b,&b); - -#else - for (b=c->bmin;b<=c->bmax;b++) { for (v=c->vmin;v<=c->vmax;v++) @@ -586,8 +535,6 @@ void Cluster_Split(Cluster * c,Cluster * c1,Cluster * c2,int teinte,Table_occure break; } -#endif - if (b==c->bmin) b++; // B est la valeur de d‚but du 2nd cluster @@ -1030,91 +977,6 @@ Table_conversion * Optimiser_palette(Bitmap24B image,int taille,struct Composant return 0; } - - - - - -#ifdef OPTIMISATIONS_ASSEMBLEUR - -void Convert_bitmap_24B_to_256_Floyd_Steinberg(Bitmap256 dest,Bitmap24B source,int largeur,int hauteur,struct Composantes * palette,Table_conversion * tc) -// Cette fonction dégrade au fur et à mesure le bitmap source, donc soit on ne -// s'en ressert pas, soit on passe à la fonction une copie de travail du -// bitmap original. -{ - Bitmap24B courant; - Bitmap256 d; - int y; - - - // On initialise les variables de parcours: - courant=source; - d =dest; - - if ((largeur>0) && (hauteur>0)) - { - if (hauteur>1) - { - // Traitement de la 1ère ligne à l'avant-dernière - - if (largeur>1) - { - // Il y a plusieurs colonnes - for (y=0;ytable, - tc->red_r,tc->red_v,tc->red_b, - tc->nbb_v,tc->nbb_b); - courant++; - d++; - // Pixels interm‚diaires de la ligne - if (largeur>2) - { - OPASM_DitherFS_6123(d,courant,largeur-2,palette,tc->table, - tc->red_r,tc->red_v,tc->red_b, - tc->nbb_v,tc->nbb_b); - courant+=largeur-2; - d+=largeur-2; - } - // Dernier pixel de la ligne - OPASM_DitherFS_12(d,courant,largeur-2,palette,tc->table, - tc->red_r,tc->red_v,tc->red_b, - tc->nbb_v,tc->nbb_b); - courant++; - d++; - } - } - else - { - OPASM_DitherFS_2(d,courant,hauteur-1,palette,tc->table, - tc->red_r,tc->red_v,tc->red_b, - tc->nbb_v,tc->nbb_b); - courant+=hauteur-1; - d+=hauteur-1; - } - } - - // Traitement de la derniŠre ligne - - if (largeur>1) - { - // Il y a plusieurs colonnes - OPASM_DitherFS_6(d,courant,largeur-1,palette,tc->table, - tc->red_r,tc->red_v,tc->red_b, - tc->nbb_v,tc->nbb_b); - courant+=largeur-1; - d+=largeur-1; - } - // Le dernier pixel - OPASM_DitherFS(d,courant,tc->table, - tc->red_r,tc->red_v,tc->red_b, - tc->nbb_v,tc->nbb_b); - } -} - -#else - int Valeur_modifiee(int valeur,int modif) { valeur+=modif; @@ -1225,8 +1087,6 @@ void Convert_bitmap_24B_to_256_Floyd_Steinberg(Bitmap256 Dest,Bitmap24B Source,i } -#endif - static const byte precision_24b[]= diff --git a/op_c.h b/op_c.h index d61bd1f2..1c664c13 100644 --- a/op_c.h +++ b/op_c.h @@ -158,7 +158,7 @@ void HSLtoRGB(byte h, byte s, byte l, byte* r, byte* g, byte* b); void TO_Init(Table_occurence * t); Table_occurence * TO_New(int nbb_r,int nbb_v,int nbb_b); void TO_Delete(Table_occurence * t); -int TO_Get(Table_occurence * t,int r,int v,int b); +inline int TO_Get(Table_occurence * t,int r,int v,int b); void TO_Set(Table_occurence * t,int r,int v,int b,int i); void TO_Inc(Table_occurence * t,int r,int v,int b); void TO_Compter_occurences(Table_occurence * t,Bitmap24B image,int taille); diff --git a/operatio.c b/operatio.c index f2243995..c940ba92 100644 --- a/operatio.c +++ b/operatio.c @@ -748,7 +748,6 @@ void Loupe_12_0(void) // On fait de notre mieux pour restaurer l'ancienne opération: Demarrer_pile_operation(Operation_avant_interruption); - DEBUG("OP",0); } /////////////////////////////////////////////////// OPERATION_RECTANGLE_????? diff --git a/pages.c b/pages.c index edb90488..2dd516f7 100644 --- a/pages.c +++ b/pages.c @@ -714,6 +714,7 @@ int Initialiser_les_listes_de_backups_en_debut_de_programme(int Taille,int Large // On ne peut pas démarrer le programme avec ne serait-ce qu'une // page de la dimension souhaitée, donc on laisse tout tomber et on // le renvoie chier. + free(Page); Retour=0; } } diff --git a/texte.c b/texte.c index 540ee627..a4b1641a 100644 --- a/texte.c +++ b/texte.c @@ -1,511 +1,513 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 Yves Rizoud - Copyright 2008 Franck Charlet - Copyright 2008 Adrien Destugues - Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) - - Grafx2 is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; version 2 - of the License. - - Grafx2 is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Grafx2; if not, see or - write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -// Pour désactiver le support TrueType, définir NOTTF -// To disable TrueType support, define NOTTF - -#include -#include -#include // tolower() - -// TrueType -#ifndef NOTTF -#ifdef __macosx__ - #include -#else - #include -#endif - -#ifdef __linux__ -#ifdef __macosx__ - #include - #import - #import -#else - #include -#endif -#endif -#endif -#include -// SFont -#include "SFont.h" - -#include "struct.h" -#include "global.h" -#include "sdlscreen.h" -#include "io.h" -#include "files.h" - -typedef struct T_FONTE -{ - char * Nom; - int EstTrueType; - int EstImage; - char Libelle[22]; - - // Liste chainée simple - struct T_FONTE * Suivante; - struct T_FONTE * Precedente; -} T_FONTE; -// Liste chainée des polices de texte -T_FONTE * Liste_fontes_debut; -int Fonte_nombre; - -// Inspiré par Allegro -#define EXTID(a,b,c) ((((a)&255)<<16) | (((b)&255)<<8) | (((c)&255))) -#define EXTID4(a,b,c,d) ((((a)&255)<<24) | (((b)&255)<<16) | (((c)&255)<<8) | (((d)&255))) - -int Compare_fontes(T_FONTE * Fonte1, T_FONTE * Fonte2) -{ - if (Fonte1->EstImage && !Fonte2->EstImage) - return -1; - if (Fonte2->EstImage && !Fonte1->EstImage) - return 1; - return strcmp(Fonte1->Libelle, Fonte2->Libelle); -} - -// Ajout d'une fonte à la liste. -void Ajout_fonte(const char *Nom) -{ - char * Nom_fonte; - T_FONTE * Fonte = (T_FONTE *)malloc(sizeof(T_FONTE)); - int Taille=strlen(Nom)+1; - int Indice; - - // Détermination du type: - -#ifdef __macosx__ - - if (Taille < 6) return; - - char strFontName[512]; - CFStringRef CFSFontName;// = CFSTR(Nom); - - CFSFontName = CFStringCreateWithBytes(NULL, (UInt8 *) Nom, Taille - 1, kCFStringEncodingASCII, false); - // Fix some funny names - CFStringGetCString(CFSFontName, strFontName, 512, kCFStringEncodingASCII); - - // Now we have a printable font name, use it - Nom = strFontName; - -#else - if (Taille<5 || - Nom[Taille-5]!='.') - return; -#endif - - switch (EXTID(tolower(Nom[Taille-4]), tolower(Nom[Taille-3]), tolower(Nom[Taille-2]))) - { - case EXTID('t','t','f'): - case EXTID('f','o','n'): - case EXTID('o','t','f'): - case EXTID('p','f','b'): - Fonte->EstTrueType = 1; - Fonte->EstImage = 0; - break; - case EXTID('b','m','p'): - case EXTID('g','i','f'): - case EXTID('j','p','g'): - case EXTID('l','b','m'): - case EXTID('p','c','x'): - case EXTID('p','n','g'): - case EXTID('t','g','a'): - case EXTID('t','i','f'): - case EXTID('x','c','f'): - case EXTID('x','p','m'): - case EXTID('.','x','v'): - Fonte->EstTrueType = 0; - Fonte->EstImage = 1; - break; - default: - #ifdef __macosx__ - if(strcasecmp(&Nom[Taille-6], "dfont") == 0) - { - Fonte->EstTrueType = 1; - Fonte->EstImage = 0; - } - else - { - return; - } - #else - return; - #endif - } - - Fonte->Nom = (char *)malloc(Taille); - strcpy(Fonte->Nom, Nom); - // Libelle - strcpy(Fonte->Libelle, " "); - if (Fonte->EstTrueType) - Fonte->Libelle[17]=Fonte->Libelle[18]='T'; // Logo TT - Nom_fonte=Position_dernier_slash(Fonte->Nom); - if (Nom_fonte==NULL) - Nom_fonte=Fonte->Nom; - else - Nom_fonte++; - for (Indice=0; Indice < 17 && Nom_fonte[Indice]!='\0' && Nom_fonte[Indice]!='.'; Indice++) - Fonte->Libelle[Indice]=Nom_fonte[Indice]; - - // Gestion Liste - Fonte->Suivante = NULL; - Fonte->Precedente = NULL; - if (Liste_fontes_debut==NULL) - { - // Premiere (liste vide) - Liste_fontes_debut = Fonte; - Fonte_nombre++; - } - else - { - int Compare; - Compare = Compare_fontes(Fonte, Liste_fontes_debut); - if (Compare<=0) - { - if (Compare==0 && !strcmp(Fonte->Nom, Liste_fontes_debut->Nom)) - { - // Doublon - free(Fonte->Nom); - free(Fonte); - return; - } - // Avant la premiere - Fonte->Suivante=Liste_fontes_debut; - Liste_fontes_debut=Fonte; - Fonte_nombre++; - } - else - { - T_FONTE *Fonte_cherchee; - Fonte_cherchee=Liste_fontes_debut; - while (Fonte_cherchee->Suivante && (Compare=Compare_fontes(Fonte, Fonte_cherchee->Suivante))>0) - Fonte_cherchee=Fonte_cherchee->Suivante; - // Après Fonte_cherchee - if (Compare==0 && strcmp(Fonte->Nom, Fonte_cherchee->Suivante->Nom)==0) - { - // Doublon - free(Fonte->Nom); - free(Fonte); - return; - } - Fonte->Suivante=Fonte_cherchee->Suivante; - Fonte_cherchee->Suivante=Fonte; - Fonte_nombre++; - } - } -} - - -// Trouve le nom d'une fonte par son numéro -char * Nom_fonte(int Indice) -{ - T_FONTE *Fonte = Liste_fontes_debut; - if (Indice<0 ||Indice>=Fonte_nombre) - return ""; - while (Indice--) - Fonte = Fonte->Suivante; - return Fonte->Nom; -} - - -// Trouve le libellé d'affichage d'une fonte par son numéro -// Renvoie un pointeur sur un buffer statique de 20 caracteres. -char * Libelle_fonte(int Indice) -{ - T_FONTE *Fonte; - static char Libelle[20]; - - strcpy(Libelle, " "); - - // Recherche de la fonte - Fonte = Liste_fontes_debut; - if (Indice<0 ||Indice>=Fonte_nombre) - return Libelle; - while (Indice--) - Fonte = Fonte->Suivante; - - // Libellé - strcpy(Libelle, Fonte->Libelle); - return Libelle; -} - - -// Vérifie si une fonte donnée est TrueType -int TrueType_fonte(int Indice) -{ - T_FONTE *Fonte = Liste_fontes_debut; - if (Indice<0 ||Indice>=Fonte_nombre) - return 0; - while (Indice--) - Fonte = Fonte->Suivante; - return Fonte->EstTrueType; -} - - - -// Initialisation à faire une fois au début du programme -void Initialisation_Texte(void) -{ - char Nom_repertoire[TAILLE_CHEMIN_FICHIER]; - #ifndef NOTTF - // Initialisation de TTF - TTF_Init(); - #endif - - // Initialisation des fontes - Liste_fontes_debut = NULL; - Fonte_nombre=0; - // Parcours du répertoire "fonts" - strcpy(Nom_repertoire, Repertoire_des_donnees); - strcat(Nom_repertoire, "fonts"); - for_each_file(Nom_repertoire, Ajout_fonte); - - #ifdef __WIN32__ - // Parcours du répertoire systeme windows "fonts" - #ifndef NOTTF - { - char * WindowsPath=getenv("windir"); - if (WindowsPath) - { - sprintf(Nom_repertoire, "%s\\FONTS", WindowsPath); - for_each_file(Nom_repertoire, Ajout_fonte); - } - } - #endif - #elif defined(__linux__) - // Récupération de la liste des fonts avec fontconfig - #ifndef NOTTF - - #ifdef __macosx__ - - int i,number; - char home_dir[MAXPATHLEN]; - char *font_path_list[3] = { - "/System/Library/Fonts", - "/Library/Fonts" - }; - number = 3; - // Make sure we also search into the user's fonts directory - CFURLRef url = (CFURLRef) CFCopyHomeDirectoryURLForUser(NULL); - CFURLGetFileSystemRepresentation(url, true, (UInt8 *) home_dir, MAXPATHLEN); - strcat(home_dir, "/Library/Fonts"); - font_path_list[2] = home_dir; - - for(i=0;i or + write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// Pour désactiver le support TrueType, définir NOTTF +// To disable TrueType support, define NOTTF + +#include +#include +#include // tolower() + +// TrueType +#ifndef NOTTF +#ifdef __macosx__ + #include +#else + #include +#endif + +#ifdef __linux__ +#ifdef __macosx__ + #include + #import + #import +#else + #include +#endif +#endif +#endif +#include +// SFont +#include "SFont.h" + +#include "struct.h" +#include "global.h" +#include "sdlscreen.h" +#include "io.h" +#include "files.h" + +typedef struct T_FONTE +{ + char * Nom; + int EstTrueType; + int EstImage; + char Libelle[22]; + + // Liste chainée simple + struct T_FONTE * Suivante; + struct T_FONTE * Precedente; +} T_FONTE; +// Liste chainée des polices de texte +T_FONTE * Liste_fontes_debut; +int Fonte_nombre; + +// Inspiré par Allegro +#define EXTID(a,b,c) ((((a)&255)<<16) | (((b)&255)<<8) | (((c)&255))) +#define EXTID4(a,b,c,d) ((((a)&255)<<24) | (((b)&255)<<16) | (((c)&255)<<8) | (((d)&255))) + +int Compare_fontes(T_FONTE * Fonte1, T_FONTE * Fonte2) +{ + if (Fonte1->EstImage && !Fonte2->EstImage) + return -1; + if (Fonte2->EstImage && !Fonte1->EstImage) + return 1; + return strcmp(Fonte1->Libelle, Fonte2->Libelle); +} + +// Ajout d'une fonte à la liste. +void Ajout_fonte(const char *Nom) +{ + char * Nom_fonte; + T_FONTE * Fonte; + int Taille=strlen(Nom)+1; + int Indice; + + // Détermination du type: + +#ifdef __macosx__ + + if (Taille < 6) return; + + char strFontName[512]; + CFStringRef CFSFontName;// = CFSTR(Nom); + + CFSFontName = CFStringCreateWithBytes(NULL, (UInt8 *) Nom, Taille - 1, kCFStringEncodingASCII, false); + // Fix some funny names + CFStringGetCString(CFSFontName, strFontName, 512, kCFStringEncodingASCII); + + // Now we have a printable font name, use it + Nom = strFontName; + +#else + if (Taille<5 || + Nom[Taille-5]!='.') + return; +#endif + + Fonte = (T_FONTE *)malloc(sizeof(T_FONTE)); + + switch (EXTID(tolower(Nom[Taille-4]), tolower(Nom[Taille-3]), tolower(Nom[Taille-2]))) + { + case EXTID('t','t','f'): + case EXTID('f','o','n'): + case EXTID('o','t','f'): + case EXTID('p','f','b'): + Fonte->EstTrueType = 1; + Fonte->EstImage = 0; + break; + case EXTID('b','m','p'): + case EXTID('g','i','f'): + case EXTID('j','p','g'): + case EXTID('l','b','m'): + case EXTID('p','c','x'): + case EXTID('p','n','g'): + case EXTID('t','g','a'): + case EXTID('t','i','f'): + case EXTID('x','c','f'): + case EXTID('x','p','m'): + case EXTID('.','x','v'): + Fonte->EstTrueType = 0; + Fonte->EstImage = 1; + break; + default: + #ifdef __macosx__ + if(strcasecmp(&Nom[Taille-6], "dfont") == 0) + { + Fonte->EstTrueType = 1; + Fonte->EstImage = 0; + } + else + { + return; + } + #else + return; + #endif + } + + Fonte->Nom = (char *)malloc(Taille); + strcpy(Fonte->Nom, Nom); + // Libelle + strcpy(Fonte->Libelle, " "); + if (Fonte->EstTrueType) + Fonte->Libelle[17]=Fonte->Libelle[18]='T'; // Logo TT + Nom_fonte=Position_dernier_slash(Fonte->Nom); + if (Nom_fonte==NULL) + Nom_fonte=Fonte->Nom; + else + Nom_fonte++; + for (Indice=0; Indice < 17 && Nom_fonte[Indice]!='\0' && Nom_fonte[Indice]!='.'; Indice++) + Fonte->Libelle[Indice]=Nom_fonte[Indice]; + + // Gestion Liste + Fonte->Suivante = NULL; + Fonte->Precedente = NULL; + if (Liste_fontes_debut==NULL) + { + // Premiere (liste vide) + Liste_fontes_debut = Fonte; + Fonte_nombre++; + } + else + { + int Compare; + Compare = Compare_fontes(Fonte, Liste_fontes_debut); + if (Compare<=0) + { + if (Compare==0 && !strcmp(Fonte->Nom, Liste_fontes_debut->Nom)) + { + // Doublon + free(Fonte->Nom); + free(Fonte); + return; + } + // Avant la premiere + Fonte->Suivante=Liste_fontes_debut; + Liste_fontes_debut=Fonte; + Fonte_nombre++; + } + else + { + T_FONTE *Fonte_cherchee; + Fonte_cherchee=Liste_fontes_debut; + while (Fonte_cherchee->Suivante && (Compare=Compare_fontes(Fonte, Fonte_cherchee->Suivante))>0) + Fonte_cherchee=Fonte_cherchee->Suivante; + // Après Fonte_cherchee + if (Compare==0 && strcmp(Fonte->Nom, Fonte_cherchee->Suivante->Nom)==0) + { + // Doublon + free(Fonte->Nom); + free(Fonte); + return; + } + Fonte->Suivante=Fonte_cherchee->Suivante; + Fonte_cherchee->Suivante=Fonte; + Fonte_nombre++; + } + } +} + + +// Trouve le nom d'une fonte par son numéro +char * Nom_fonte(int Indice) +{ + T_FONTE *Fonte = Liste_fontes_debut; + if (Indice<0 ||Indice>=Fonte_nombre) + return ""; + while (Indice--) + Fonte = Fonte->Suivante; + return Fonte->Nom; +} + + +// Trouve le libellé d'affichage d'une fonte par son numéro +// Renvoie un pointeur sur un buffer statique de 20 caracteres. +char * Libelle_fonte(int Indice) +{ + T_FONTE *Fonte; + static char Libelle[20]; + + strcpy(Libelle, " "); + + // Recherche de la fonte + Fonte = Liste_fontes_debut; + if (Indice<0 ||Indice>=Fonte_nombre) + return Libelle; + while (Indice--) + Fonte = Fonte->Suivante; + + // Libellé + strcpy(Libelle, Fonte->Libelle); + return Libelle; +} + + +// Vérifie si une fonte donnée est TrueType +int TrueType_fonte(int Indice) +{ + T_FONTE *Fonte = Liste_fontes_debut; + if (Indice<0 ||Indice>=Fonte_nombre) + return 0; + while (Indice--) + Fonte = Fonte->Suivante; + return Fonte->EstTrueType; +} + + + +// Initialisation à faire une fois au début du programme +void Initialisation_Texte(void) +{ + char Nom_repertoire[TAILLE_CHEMIN_FICHIER]; + #ifndef NOTTF + // Initialisation de TTF + TTF_Init(); + #endif + + // Initialisation des fontes + Liste_fontes_debut = NULL; + Fonte_nombre=0; + // Parcours du répertoire "fonts" + strcpy(Nom_repertoire, Repertoire_des_donnees); + strcat(Nom_repertoire, "fonts"); + for_each_file(Nom_repertoire, Ajout_fonte); + + #ifdef __WIN32__ + // Parcours du répertoire systeme windows "fonts" + #ifndef NOTTF + { + char * WindowsPath=getenv("windir"); + if (WindowsPath) + { + sprintf(Nom_repertoire, "%s\\FONTS", WindowsPath); + for_each_file(Nom_repertoire, Ajout_fonte); + } + } + #endif + #elif defined(__linux__) + // Récupération de la liste des fonts avec fontconfig + #ifndef NOTTF + + #ifdef __macosx__ + + int i,number; + char home_dir[MAXPATHLEN]; + char *font_path_list[3] = { + "/System/Library/Fonts", + "/Library/Fonts" + }; + number = 3; + // Make sure we also search into the user's fonts directory + CFURLRef url = (CFURLRef) CFCopyHomeDirectoryURLForUser(NULL); + CFURLGetFileSystemRepresentation(url, true, (UInt8 *) home_dir, MAXPATHLEN); + strcat(home_dir, "/Library/Fonts"); + font_path_list[2] = home_dir; + + for(i=0;iw * Texte8Bit->h; Indice++) - { - if (*(BrosseRetour+Indice) == CM_Noir) - *(BrosseRetour+Indice)=Back_color; - else if (*(BrosseRetour+Indice) == CM_Blanc) - *(BrosseRetour+Indice)=Fore_color; - } - } - *Largeur=Texte8Bit->w; - *Hauteur=Texte8Bit->h; - SDL_FreeSurface(Texte8Bit); - TTF_CloseFont(Fonte); - return BrosseRetour; -} -#endif - - -byte *Rendu_Texte_SFont(const char *Chaine, int Numero_fonte, int *Largeur, int *Hauteur) -{ - SFont_Font *Fonte; - SDL_Surface * TexteColore; - SDL_Surface * Texte8Bit; - SDL_Surface *Surface_fonte; - byte * BrosseRetour; - - // Chargement de la fonte - Surface_fonte=IMG_Load(Nom_fonte(Numero_fonte)); - if (!Surface_fonte) - return NULL; - Fonte=SFont_InitFont(Surface_fonte); - if (!Fonte) - { - return NULL; - } - - // Calcul des dimensions - *Hauteur=SFont_TextHeight(Fonte); - *Largeur=SFont_TextWidth(Fonte, Chaine); - // Allocation d'une surface SDL - TexteColore=SDL_CreateRGBSurface(SDL_SWSURFACE, *Largeur, *Hauteur, 24, 0, 0, 0, 0); - // Rendu du texte - SFont_Write(TexteColore, Fonte, 0, 0, Chaine); - if (!TexteColore) - { - SFont_FreeFont(Fonte); - return NULL; - } - - Texte8Bit=SDL_DisplayFormat(TexteColore); - SDL_FreeSurface(TexteColore); - - BrosseRetour=Surface_en_bytefield(Texte8Bit, NULL); - if (!BrosseRetour) - { - SDL_FreeSurface(TexteColore); - SDL_FreeSurface(Texte8Bit); - SFont_FreeFont(Fonte); - return NULL; - } - SDL_FreeSurface(Texte8Bit); - SFont_FreeFont(Fonte); - - return BrosseRetour; -} - - -// Crée une brosse à partir des paramètres de texte demandés. -// Si cela réussit, la fonction place les dimensions dans Largeur et Hauteur, -// et retourne l'adresse du bloc d'octets. -byte *Rendu_Texte(const char *Chaine, int Numero_fonte, int Taille, int AntiAlias, int Bold, int Italic, int *Largeur, int *Hauteur) -{ - T_FONTE *Fonte = Liste_fontes_debut; - int Indice=Numero_fonte; - - // Verification type de la fonte - if (Numero_fonte<0 ||Numero_fonte>=Fonte_nombre) - return NULL; - - while (Indice--) - Fonte = Fonte->Suivante; - if (Fonte->EstTrueType) - { - #ifndef NOTTF - return Rendu_Texte_TTF(Chaine, Numero_fonte, Taille, AntiAlias, Bold, Italic, Largeur, Hauteur); - #else - return NULL; - #endif - } - else - { - return Rendu_Texte_SFont(Chaine, Numero_fonte, Largeur, Hauteur); - } -} - - + } + #endif + #endif + + + #endif + #endif +} + +// Informe si texte.c a été compilé avec l'option de support TrueType ou pas. +int Support_TrueType() +{ + #ifdef NOTTF + return 0; + #else + return 1; + #endif +} + + +#ifndef NOTTF +byte *Rendu_Texte_TTF(const char *Chaine, int Numero_fonte, int Taille, int AntiAlias, int Bold, int Italic, int *Largeur, int *Hauteur) +{ + TTF_Font *Fonte; + SDL_Surface * TexteColore; + SDL_Surface * Texte8Bit; + byte * BrosseRetour; + int Indice; + int Style; + + SDL_Color Couleur_Avant; + SDL_Color Couleur_Arriere; + + // Chargement de la fonte + Fonte=TTF_OpenFont(Nom_fonte(Numero_fonte), Taille); + if (!Fonte) + { + return NULL; + } + // Style + Style=0; + if (Italic) + Style|=TTF_STYLE_ITALIC; + if (Bold) + Style|=TTF_STYLE_BOLD; + TTF_SetFontStyle(Fonte, Style); + // Couleurs + if (AntiAlias) + { + Couleur_Avant = Conversion_couleur_SDL(Fore_color); + Couleur_Arriere = Conversion_couleur_SDL(Back_color); + } + else + { + Couleur_Avant = Conversion_couleur_SDL(CM_Blanc); + Couleur_Arriere = Conversion_couleur_SDL(CM_Noir); + } + + + // Rendu du texte: crée une surface SDL RGB 24bits + if (AntiAlias) + TexteColore=TTF_RenderText_Shaded(Fonte, Chaine, Couleur_Avant, Couleur_Arriere ); + else + TexteColore=TTF_RenderText_Solid(Fonte, Chaine, Couleur_Avant); + if (!TexteColore) + { + TTF_CloseFont(Fonte); + return NULL; + } + + Texte8Bit=SDL_DisplayFormat(TexteColore); + + SDL_FreeSurface(TexteColore); + + BrosseRetour=Surface_en_bytefield(Texte8Bit, NULL); + if (!BrosseRetour) + { + SDL_FreeSurface(TexteColore); + SDL_FreeSurface(Texte8Bit); + TTF_CloseFont(Fonte); + return NULL; + } + if (!AntiAlias) + { + // Mappage des couleurs + for (Indice=0; Indice < Texte8Bit->w * Texte8Bit->h; Indice++) + { + if (*(BrosseRetour+Indice) == CM_Noir) + *(BrosseRetour+Indice)=Back_color; + else if (*(BrosseRetour+Indice) == CM_Blanc) + *(BrosseRetour+Indice)=Fore_color; + } + } + *Largeur=Texte8Bit->w; + *Hauteur=Texte8Bit->h; + SDL_FreeSurface(Texte8Bit); + TTF_CloseFont(Fonte); + return BrosseRetour; +} +#endif + + +byte *Rendu_Texte_SFont(const char *Chaine, int Numero_fonte, int *Largeur, int *Hauteur) +{ + SFont_Font *Fonte; + SDL_Surface * TexteColore; + SDL_Surface * Texte8Bit; + SDL_Surface *Surface_fonte; + byte * BrosseRetour; + + // Chargement de la fonte + Surface_fonte=IMG_Load(Nom_fonte(Numero_fonte)); + if (!Surface_fonte) + return NULL; + Fonte=SFont_InitFont(Surface_fonte); + if (!Fonte) + { + return NULL; + } + + // Calcul des dimensions + *Hauteur=SFont_TextHeight(Fonte); + *Largeur=SFont_TextWidth(Fonte, Chaine); + // Allocation d'une surface SDL + TexteColore=SDL_CreateRGBSurface(SDL_SWSURFACE, *Largeur, *Hauteur, 24, 0, 0, 0, 0); + // Rendu du texte + SFont_Write(TexteColore, Fonte, 0, 0, Chaine); + if (!TexteColore) + { + SFont_FreeFont(Fonte); + return NULL; + } + + Texte8Bit=SDL_DisplayFormat(TexteColore); + SDL_FreeSurface(TexteColore); + + BrosseRetour=Surface_en_bytefield(Texte8Bit, NULL); + if (!BrosseRetour) + { + SDL_FreeSurface(TexteColore); + SDL_FreeSurface(Texte8Bit); + SFont_FreeFont(Fonte); + return NULL; + } + SDL_FreeSurface(Texte8Bit); + SFont_FreeFont(Fonte); + + return BrosseRetour; +} + + +// Crée une brosse à partir des paramètres de texte demandés. +// Si cela réussit, la fonction place les dimensions dans Largeur et Hauteur, +// et retourne l'adresse du bloc d'octets. +byte *Rendu_Texte(const char *Chaine, int Numero_fonte, int Taille, int AntiAlias, int Bold, int Italic, int *Largeur, int *Hauteur) +{ + T_FONTE *Fonte = Liste_fontes_debut; + int Indice=Numero_fonte; + + // Verification type de la fonte + if (Numero_fonte<0 ||Numero_fonte>=Fonte_nombre) + return NULL; + + while (Indice--) + Fonte = Fonte->Suivante; + if (Fonte->EstTrueType) + { + #ifndef NOTTF + return Rendu_Texte_TTF(Chaine, Numero_fonte, Taille, AntiAlias, Bold, Italic, Largeur, Hauteur); + #else + return NULL; + #endif + } + else + { + return Rendu_Texte_SFont(Chaine, Numero_fonte, Largeur, Hauteur); + } +} + +