E:/PPC/XFlib/source/xf_text.c

Go to the documentation of this file.
00001 
00002 #ifdef __cplusplus
00003 extern "C" {
00004 #endif
00005 
00006 
00007 #include "xf_text.h"
00008 #include "xf_bg.h"
00009 #include "xf_params.h"
00010 #include <malloc.h>
00011 
00012 #include "Text/all_gfx.h"
00013 
00014 XF_Font *xf_deffonts[5] = {&xf_text0, &xf_text1, &xf_text2, &xf_text3, &xf_text4};
00015 u32 xf_deffontsize[5] = {sizeof(xf_text0_Font), sizeof(xf_text1_Font), sizeof(xf_text2_Font), sizeof(xf_text3_Font), sizeof(xf_text4_Font)};
00016         
00017 XF_Font *xf_fonts[16] = {};
00018 
00019 XF_TextTemp XF_LetterPos;
00020 XF_TextSlot_type *XF_TextSlot[N_BG] = {}; // Vide /*[256]*/;
00021 
00022 
00023 xf_textinfo_type xf_textinfo = {0, 1, ALIGN_LEFT, 32, 0}; // Alpha = 32, bg !
00024 
00025 
00026 
00027 
00028 
00029 extern inline void XF_AddLetterPos(s16 Letter, s16 x, s16 y){
00030         XF_LetterPos.Letter[XF_LetterPos.NLetters].Letter = Letter;
00031         XF_LetterPos.Letter[XF_LetterPos.NLetters].X = x;
00032         XF_LetterPos.Letter[XF_LetterPos.NLetters].Y = y;
00033         XF_LetterPos.NLetters++;        
00034 }
00035 
00036 
00037 
00038 /* Michoko EDITION */
00039 void XF_DoAlign(u16 start, s16 x, s16 maxx, u8 justify, u8 align){
00040    s16 i;
00041    s16 width = (maxx+1)-x;
00042 //   XF_Print(0, "%d   \n", width);
00043    
00044         if(align == ALIGN_RIGHT){ // Cas simple, on rajoute la différence de largeur à toutes les lettres...
00045                 width++;
00046                 for(i = start; i < XF_LetterPos.NLetters; i++) XF_LetterPos.Letter[i].X += width;
00047         }     
00048         else if(align == ALIGN_CENTER){ // Cas simple, on rajoute la moitié de la largeur à toutes les lettres...
00049                 width = (width+1)>>1;
00050                 for(i = start; i < XF_LetterPos.NLetters; i++) XF_LetterPos.Letter[i].X += width;
00051         }    
00052         else if(justify && (align == ALIGN_JUSTIFY)){ // Cas relou ^^
00053                 //u8 nletters = XF_LetterPos.NLetters-start; // Nombre de lettres
00054                 u8 justify = 0; // Décallage à faire au début...
00055                 u8 spaces = 0;
00056                 u8 change = 0;
00057                 u8 quickadd = 0;
00058                 
00059                 u8 nletters = XF_LetterPos.NLetters-1 - start;
00060                 if(nletters < width){ // Less letters than the width to add, add 1 pixel/letter...
00061                         quickadd = 1;
00062                         width -= nletters;
00063                 }
00064                 // Compter le nombre d'espaces
00065                 for(i = start; i < XF_LetterPos.NLetters-1; i++) if(XF_LetterPos.Letter[i].Letter == ' ') spaces++;
00066                 
00067                 for(i = start; i < XF_LetterPos.NLetters; i++) {
00068                         justify+= quickadd;
00069                    XF_LetterPos.Letter[i].X += justify;
00070                    if((XF_LetterPos.Letter[i].Letter == ' ')&&width){
00071                       change = (width+(spaces>>1))/spaces;
00072                                 justify+=change;                 
00073                                 width-=change; // Moins à corriger par la suite...  
00074                                 spaces--;   
00075                    }   
00076                 }   
00077         }    
00078                 
00079 }   
00080 
00081 
00082 void XF_DoLetterPos(s16 basex, s16 basey, s16 maxx, s16 maxy, char* text, u8 size, u8 alpha, s8 letterspacing, s8 linespacing, s8 align, s32 limit){
00083         s16 x = basex; s16 y = basey;
00084         s16 width, letterstart;
00085         u8 lx, letter;
00086         s16 i;
00087         
00088         XF_LetterPos.NLetters = 0;
00089         letterstart = 0;
00090         
00091         if((align == ALIGN_JUSTIFY)||(align == ALIGN_LEFT)) limit += 100; // Pour bien caler la ligne
00092         
00093         for(i = 0; (i < limit+100)&&(text[i]); i++){
00094            letter = text[i]; 
00095            lx = xf_fonts[size]->LetterWidth[letter]+letterspacing;
00096            
00097            if((letter == '\n') || ((x+lx > maxx)&&(letter != ' '))){ // retour ligne, ou on dépasse...
00098                 
00099                         
00100                         width = x - basex; // LARGEUR !
00101 
00102       if(letter == '\n')XF_AddLetterPos(letter, x, y); // Retour ligne à mettre dans le tableau
00103       else if(letter == ' ') XF_AddLetterPos(letter, x, y); // Si espace, on met à la suite
00104       else {
00105          // Sinon, on revient en arrière pour pas couper un mot !
00106          while(text[i-1] != ' ') { i--; x -= xf_fonts[size]->LetterWidth[letter] + letterspacing; XF_LetterPos.NLetters--;} // Retirer les lettres et la largeur
00107                    letter = text[i]; 
00108                    lx = xf_fonts[size]->LetterWidth[letter] + letterspacing;     
00109                         x--; // Moins de largeur        
00110       }  
00111                           
00112    
00113               // Calculer différence de largeur...
00114                         if(text[i-1] == ' ') x-= xf_fonts[size]->LetterWidth[' ']; // Retirer la largeur de l'espace      
00115                 
00116                    if(y+ xf_fonts[size]->LetterHeight * 2 > maxy) {
00117                 break; // EXIT !        
00118                         }   
00119                                               
00120               // Retour ligne ! Voir si besoin d'aligne le texte d'un côté ou de l'autre, centrer, etc...
00121                         XF_DoAlign(letterstart, x, maxx, (letter != '\n'), align); // Autorise le justify que si pas '\'n
00122    
00123    
00124               x = basex;
00125               y += xf_fonts[size]->LetterHeight +linespacing;
00126               
00127            
00128               
00129               
00130               letterstart = XF_LetterPos.NLetters; // Première lettre de cette ligne !
00131               if(letter > 32) {
00132                            XF_AddLetterPos(letter, x, y);
00133                            x += lx;              
00134               }               
00135 
00136                    
00137            }   
00138            else{
00139                    XF_AddLetterPos(letter, x, y);
00140                    x += lx;   
00141                 }               
00142         }   
00143         if(text[i-1] == ' ') x-= xf_fonts[size]->LetterWidth[' ']; // Retirer la largeur de l'espace     
00144         XF_DoAlign(letterstart, x, maxx, (y + xf_fonts[size]->LetterHeight * 2 > maxy), align);
00145 
00146         // End Position
00147         XF_LetterPos.Letter[XF_LetterPos.NLetters].X = x;
00148         XF_LetterPos.Letter[XF_LetterPos.NLetters].Y = y;
00149 
00150 }
00151 
00152 
00153 void xf_textdecompress(u8 size){
00154         u16 temp;
00155 
00156         // On malloc la structure
00157         xf_fonts[size] = (XF_Font*)malloc(sizeof(XF_Font));
00158         
00159         xf_fonts[size]->LetterStart = xf_deffonts[size]->LetterStart; // On pointe au même endroit
00160         xf_fonts[size]->LetterWidth = xf_deffonts[size]->LetterWidth; // On pointe au même endroit
00161         xf_fonts[size]->LetterHeight = xf_deffonts[size]->LetterHeight; // Meme valeur
00162                 
00163         xf_fonts[size]->Image = (u16*)malloc(xf_deffontsize[size]*16); // Gros malloc... on va en faire le mask :D
00164         
00165         s32 i, j;
00166         u16 *buffer = (u16*)xf_fonts[size]->Image;
00167         u8 *img = (u8*)xf_deffonts[size]->Image;
00168         
00169         for(i = 0; i < xf_deffontsize[size]; i++){
00170                 // On fout en 8 pixels...
00171                 for(j = 0; j < 8; j++){
00172                         temp = ((img[i])>>j)&1;
00173                         buffer[i*8+j] = temp*0xFFFF;
00174                         //XF_DebugText(j, 2, "%d", temp);
00175                 }       
00176                 //XF_WaitFor(Stylus.Held);
00177         }
00178         
00179         //XF_DebugText(0, 3, "%d => %d   ", size, xf_deffontsize[size]);
00180 
00181 
00182 }
00183 
00184 void xf_cleanfonts(void){
00185         u8 i;
00186         
00187         
00188         for(i = 0; i < 5; i++){
00189                 if(xf_fonts[i] != 0){
00190                         // On libère !
00191                         free(xf_fonts[i]->Image);
00192                         free(xf_fonts[i]);
00193                 }
00194                 
00195                 xf_fonts[i] = 0;
00196         }
00197 
00198         for(i = 5; i < 16; i++){
00199                 if(xf_fonts[i] != 0){
00200                         // On libère !
00201                         free(xf_fonts[i]->Image);
00202                         free(xf_fonts[i]->LetterStart);                 
00203                         free(xf_fonts[i]->LetterWidth);                 
00204                         free(xf_fonts[i]);              
00205                 }
00206                 xf_fonts[i] = 0;
00207         }
00208 }
00209 
00210 /*
00211 
00212 typedef struct{
00213         s32 NLetters;
00214         u8 Size;
00215         u16 Color;
00216         XF_Letter *Letter;
00217 } XF_TextSlot_type;
00218 XF_TextSlot_type XF_TextSlot[32];*/
00219 
00220 
00221 
00222 
00223 s16 XF_CreateTextEx(u8 bg, u8 slot, s16 basex, s16 basey, s16 maxx, s16 maxy, char* text, u16 color, u8 size, u8 alpha, s8 letterspacing, s8 linespacing, s8 align, s32 limit){
00224         s16 i;
00225         
00226         
00227 
00228         
00229 //      return 0;
00230         
00231         if(xf_fonts[size] == 0) {
00232                 if(size < 5) xf_textdecompress(size);
00233                 else return 0; // On ne fait rien !
00234         }
00235         
00236 
00237         XF_TextSlot[bg][slot].Color = color;
00238         XF_TextSlot[bg][slot].Size = size;      
00239         
00240         XF_TextSlot[bg][slot].letterspacing = letterspacing;
00241         XF_TextSlot[bg][slot].linespacing = linespacing;
00242         XF_TextSlot[bg][slot].align = align;
00243         XF_TextSlot[bg][slot].alpha = alpha;
00244                 
00245         XF_DoLetterPos(basex, basey, maxx, maxy, text, size, alpha, letterspacing, linespacing, align, limit);
00246         
00247         if(limit > XF_LetterPos.NLetters) limit = XF_LetterPos.NLetters; // Plus short que prévu
00248         XF_LetterPos.NLetters = limit;
00249         
00250         // On compare à la taille d'avant...
00251         if((XF_TextSlot[bg][slot].Letter == 0) || (limit > XF_TextSlot[bg][slot].MallocSize)){
00252                 if(XF_TextSlot[bg][slot].Letter == 0) free(XF_TextSlot[bg][slot].Letter);
00253                 XF_TextSlot[bg][slot].MallocSize = XF_LetterPos.NLetters + 16; // Un peu de marge
00254                 XF_TextSlot[bg][slot].Letter = (XF_Letter*)malloc(sizeof(XF_Letter)*(XF_TextSlot[bg][slot].MallocSize+1));
00255         }
00256 
00257 
00258 
00259         // Enregistrer les limites
00260         XF_TextSlot[bg][slot].x0 = basex;
00261         XF_TextSlot[bg][slot].y0 = basey;
00262         XF_TextSlot[bg][slot].x1 = maxx;
00263         XF_TextSlot[bg][slot].y1 = maxy;        
00264         
00265         for(i = 0; i < limit; i++) XF_TextSlot[bg][slot].Letter[i] = XF_LetterPos.Letter[i]; // On copie tout !
00266         XF_TextSlot[bg][slot].NLetters = XF_LetterPos.NLetters;
00267         XF_TextSlot[bg][slot].Alpha = xf_textinfo.alpha;
00268         
00269         return limit;
00270 }
00271 
00272 
00273 
00274 void XF_ResetTextBg(u8 bg){
00275         u16 slot;
00276         
00277 //      return;
00278         
00279         for(slot = 0; slot < TEXT_SLOTS; slot++)        {
00280                 XF_TextSlot[bg][slot].NLetters = 0;
00281                 if(XF_TextSlot[bg][slot].Letter != 0) free(XF_TextSlot[bg][slot].Letter);
00282                 XF_TextSlot[bg][slot].Letter = 0;
00283         }
00284 }
00285 
00286 
00287 
00288 void XF_LoadTextBg(u8 number){
00289 
00290         if(XF_TextSlot[number] == 0) {
00291                 XF_TextSlot[number] = (XF_TextSlot_type*)malloc(sizeof(XF_TextSlot_type)*TEXT_SLOTS);
00292                 s32 i;
00293                 for(i = 0; i < TEXT_SLOTS; i++) {
00294                         XF_TextSlot[number][i].NLetters = 0;
00295                         XF_TextSlot[number][i].Letter = 0;
00296                 }
00297         }
00298 
00299         XF_BgDelete(number);
00300         
00301 
00302         xf_bg[number].Alive = 1;
00303         xf_bg[number].BgMode = BG_FONT;
00304 
00305         xf_bg[number].Priority = number; // Priorité classique
00306         
00307         xf_bg[number].ScrollX = 0;
00308         xf_bg[number].ScrollY = 0;
00309 
00310 
00311         xf_bg[number].Alpha = ALPHA_MAX; // Fully visible
00312 
00313         xf_bg[number].Full = 0; // Never full, uses tiles
00314         XF_LetterPos.NLetters = 0; // Rien
00315         
00316         XF_SetDefaultTextBg(number); // Ecrire sur ce fond à l'avenir :p
00317 }
00318 
00319 
00320 
00321 void XF_CopyLetter(u16 *buffer, u16 color, s32 width, s32 height, s32 x, s32 y, u8 alpha);
00322 void XF_CopyPlainLetter(u16 *mask, u16 color, s32 width, s32 height, s32 x, s32 y, u8 alpha) ;
00323 
00324 
00325 void XF_ShowTextBg(u8 number){
00326         s16 i, slot;
00327         u8 letter, size, height;
00328         u16 color;
00329         u8 alpha;
00330         XF_TextSlot_type *txtslot;
00331 //      return;
00332         
00333         for(slot = 0; slot < TEXT_SLOTS; slot++){
00334                 txtslot = &XF_TextSlot[number][slot];
00335                 
00336                 
00337                 if((txtslot != 0) && (txtslot->NLetters > 0) && (txtslot->Alpha > 0)){
00338                         alpha = txtslot->Alpha;
00339                         size = txtslot->Size;   
00340                         u16 *data = xf_fonts[size]->Image;
00341                         height = xf_fonts[size]->LetterHeight;
00342                                 
00343                         if(size < 5){
00344                                 color = txtslot->Color;
00345 
00346                                 // Pas de couleurs farfelues
00347                                 for(i = 0; i < XF_TextSlot[number][slot].NLetters; i++) {
00348                                         letter = txtslot->Letter[i].Letter;
00349                                         XF_CopyPlainLetter((u16*)(data + ((xf_fonts[size]->LetterStart[letter])>>1)), color, xf_fonts[size]->LetterWidth[letter], height, txtslot->Letter[i].X, txtslot->Letter[i].Y, alpha);
00350 
00351                                 }
00352                         }
00353                         else{
00354                                 for(i = 0; i < XF_TextSlot[number][slot].NLetters; i++) {
00355                                         letter = txtslot->Letter[i].Letter;
00356                                         XF_CopyLetter((u16*)(data + xf_fonts[size]->LetterStart[letter]), 1, xf_fonts[size]->LetterWidth[letter], height, txtslot->Letter[i].X, txtslot->Letter[i].Y, alpha);
00357 
00358                                 }       
00359                         }
00360                 }
00361         }
00362 
00363 
00364 }
00365 
00366 void XF_ClearText(u8 slot){
00367         XF_TextSlot[xf_textinfo.bg][slot].NLetters = 0; // POUF
00368 }
00369 
00370 
00371 
00372 #ifdef __cplusplus
00373 }
00374 #endif
00375 
00376 
00377 

Generated on Wed Dec 12 23:46:38 2007 for XFlib by  doxygen 1.5.4