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] = {};
00021
00022
00023 xf_textinfo_type xf_textinfo = {0, 1, ALIGN_LEFT, 32, 0};
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
00039 void XF_DoAlign(u16 start, s16 x, s16 maxx, u8 justify, u8 align){
00040 s16 i;
00041 s16 width = (maxx+1)-x;
00042
00043
00044 if(align == ALIGN_RIGHT){
00045 width++;
00046 for(i = start; i < XF_LetterPos.NLetters; i++) XF_LetterPos.Letter[i].X += width;
00047 }
00048 else if(align == ALIGN_CENTER){
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)){
00053
00054 u8 justify = 0;
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){
00061 quickadd = 1;
00062 width -= nletters;
00063 }
00064
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;
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;
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 != ' '))){
00098
00099
00100 width = x - basex;
00101
00102 if(letter == '\n')XF_AddLetterPos(letter, x, y);
00103 else if(letter == ' ') XF_AddLetterPos(letter, x, y);
00104 else {
00105
00106 while(text[i-1] != ' ') { i--; x -= xf_fonts[size]->LetterWidth[letter] + letterspacing; XF_LetterPos.NLetters--;}
00107 letter = text[i];
00108 lx = xf_fonts[size]->LetterWidth[letter] + letterspacing;
00109 x--;
00110 }
00111
00112
00113
00114 if(text[i-1] == ' ') x-= xf_fonts[size]->LetterWidth[' '];
00115
00116 if(y+ xf_fonts[size]->LetterHeight * 2 > maxy) {
00117 break;
00118 }
00119
00120
00121 XF_DoAlign(letterstart, x, maxx, (letter != '\n'), align);
00122
00123
00124 x = basex;
00125 y += xf_fonts[size]->LetterHeight +linespacing;
00126
00127
00128
00129
00130 letterstart = XF_LetterPos.NLetters;
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[' '];
00144 XF_DoAlign(letterstart, x, maxx, (y + xf_fonts[size]->LetterHeight * 2 > maxy), align);
00145
00146
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
00157 xf_fonts[size] = (XF_Font*)malloc(sizeof(XF_Font));
00158
00159 xf_fonts[size]->LetterStart = xf_deffonts[size]->LetterStart;
00160 xf_fonts[size]->LetterWidth = xf_deffonts[size]->LetterWidth;
00161 xf_fonts[size]->LetterHeight = xf_deffonts[size]->LetterHeight;
00162
00163 xf_fonts[size]->Image = (u16*)malloc(xf_deffontsize[size]*16);
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
00171 for(j = 0; j < 8; j++){
00172 temp = ((img[i])>>j)&1;
00173 buffer[i*8+j] = temp*0xFFFF;
00174
00175 }
00176
00177 }
00178
00179
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
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
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
00213
00214
00215
00216
00217
00218
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
00230
00231 if(xf_fonts[size] == 0) {
00232 if(size < 5) xf_textdecompress(size);
00233 else return 0;
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;
00248 XF_LetterPos.NLetters = limit;
00249
00250
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;
00254 XF_TextSlot[bg][slot].Letter = (XF_Letter*)malloc(sizeof(XF_Letter)*(XF_TextSlot[bg][slot].MallocSize+1));
00255 }
00256
00257
00258
00259
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];
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
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;
00306
00307 xf_bg[number].ScrollX = 0;
00308 xf_bg[number].ScrollY = 0;
00309
00310
00311 xf_bg[number].Alpha = ALPHA_MAX;
00312
00313 xf_bg[number].Full = 0;
00314 XF_LetterPos.NLetters = 0;
00315
00316 XF_SetDefaultTextBg(number);
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
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
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;
00368 }
00369
00370
00371
00372 #ifdef __cplusplus
00373 }
00374 #endif
00375
00376
00377