~ubuntu-branches/ubuntu/maverick/grafx2/maverick

« back to all changes in this revision

Viewing changes to src/text.c

  • Committer: Bazaar Package Importer
  • Author(s): Gürkan Sengün
  • Date: 2010-03-22 12:07:47 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100322120747-g0jel6vf6mjkc53s
Tags: 2.2-1
* New upstream version, fixes FTBFS with binutils-gold. (Closes: #554742)
* Bump standards version to 3.8.4.
* debian/control: Add liblua5.1-0-dev and pkg-config to build depends.
* debian/rules: Drop dh_desktop call.
* debian/copyright: Update years.
* Switch to dpkg-source format version 3.0 (quilt).
* debian/watch: Added.
* Added patch to fix spelling errors in source code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* vim:expandtab:ts=2 sw=2:
 
2
*/
 
3
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 
4
 
 
5
    Copyright 2008 Yves Rizoud
 
6
    Copyright 2008 Franck Charlet
 
7
    Copyright 2008 Adrien Destugues
 
8
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 
9
 
 
10
    Grafx2 is free software; you can redistribute it and/or
 
11
    modify it under the terms of the GNU General Public License
 
12
    as published by the Free Software Foundation; version 2
 
13
    of the License.
 
14
 
 
15
    Grafx2 is distributed in the hope that it will be useful,
 
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
    GNU General Public License for more details.
 
19
 
 
20
    You should have received a copy of the GNU General Public License
 
21
    along with Grafx2; if not, see <http://www.gnu.org/licenses/>
 
22
*/
 
23
 
 
24
// Pour d�sactiver le support TrueType, d�finir NOTTF
 
25
// To disable TrueType support, define NOTTF
 
26
 
 
27
#include <string.h>
 
28
#include <stdlib.h>
 
29
#include <ctype.h> // tolower()
 
30
 
 
31
// TrueType
 
32
#ifndef NOTTF
 
33
#if defined(__macosx__)
 
34
  #include <SDL_ttf/SDL_ttf.h>
 
35
#else
 
36
  #include <SDL_ttf.h>
 
37
#endif
 
38
 
 
39
#if defined(__linux__)
 
40
#if defined(__macosx__)
 
41
  #include <Carbon/Carbon.h>
 
42
  #import <corefoundation/corefoundation.h>
 
43
  #import <sys/param.h>
 
44
#else
 
45
  #include <X11/Xlib.h>
 
46
#endif
 
47
#endif
 
48
#endif
 
49
 
 
50
#include <SDL_image.h>
 
51
// SFont
 
52
#include "SFont.h"
 
53
 
 
54
#include "struct.h"
 
55
#include "global.h"
 
56
#include "sdlscreen.h"
 
57
#include "io.h"
 
58
#include "errors.h"
 
59
 
 
60
typedef struct T_Font
 
61
{
 
62
  char * Name;
 
63
  int    Is_truetype;
 
64
  int    Is_bitmap;
 
65
  char   Label[22];
 
66
  
 
67
  // Liste chain�e simple
 
68
  struct T_Font * Next;
 
69
  struct T_Font * Previous;
 
70
} T_Font;
 
71
// Liste chain�e des polices de texte
 
72
T_Font * font_list_start;
 
73
int Nb_fonts;
 
74
 
 
75
// Inspir� par Allegro
 
76
#define EXTID(a,b,c) ((((a)&255)<<16) | (((b)&255)<<8) | (((c)&255)))
 
77
#define EXTID4(a,b,c,d) ((((a)&255)<<24) | (((b)&255)<<16) | (((c)&255)<<8) | (((d)&255)))
 
78
 
 
79
int Compare_fonts(T_Font * font_1, T_Font * font_2)
 
80
{
 
81
  if (font_1->Is_bitmap && !font_2->Is_bitmap)
 
82
    return -1;
 
83
  if (font_2->Is_bitmap && !font_1->Is_bitmap)
 
84
    return 1;
 
85
  return strcmp(font_1->Label, font_2->Label);
 
86
}
 
87
 
 
88
// Ajout d'une fonte � la liste.
 
89
void Add_font(const char *name)
 
90
{
 
91
  char * font_name;
 
92
  T_Font * font;
 
93
  int size=strlen(name)+1;
 
94
  int index;
 
95
  
 
96
  // D�termination du type:
 
97
 
 
98
#if defined(__macosx__)
 
99
 
 
100
  if (size < 6) return;
 
101
  
 
102
  char strFontName[512];
 
103
  CFStringRef CFSFontName;// = CFSTR(name);
 
104
 
 
105
  CFSFontName = CFStringCreateWithBytes(NULL, (UInt8 *) name, size - 1, kCFStringEncodingASCII, false);
 
106
  // Fix some funny names
 
107
  CFStringGetCString(CFSFontName, strFontName, 512, kCFStringEncodingASCII);
 
108
 
 
109
  // Now we have a printable font name, use it
 
110
  name = strFontName;
 
111
 
 
112
#else
 
113
  if (size<5 ||
 
114
      name[size-5]!='.')
 
115
    return;
 
116
#endif
 
117
 
 
118
  font = (T_Font *)malloc(sizeof(T_Font));
 
119
 
 
120
  switch (EXTID(tolower(name[size-4]), tolower(name[size-3]), tolower(name[size-2])))
 
121
  {
 
122
    case EXTID('t','t','f'):
 
123
    case EXTID('f','o','n'):
 
124
    case EXTID('o','t','f'):
 
125
    case EXTID('p','f','b'):
 
126
      font->Is_truetype = 1;
 
127
      font->Is_bitmap = 0;
 
128
      break;
 
129
    case EXTID('b','m','p'):
 
130
    case EXTID('g','i','f'):
 
131
    case EXTID('j','p','g'):
 
132
    case EXTID('l','b','m'):
 
133
    case EXTID('p','c','x'):
 
134
    case EXTID('p','n','g'):
 
135
    case EXTID('t','g','a'):
 
136
    case EXTID('t','i','f'):
 
137
    case EXTID('x','c','f'):
 
138
    case EXTID('x','p','m'):
 
139
    case EXTID('.','x','v'):
 
140
      font->Is_truetype = 0;
 
141
      font->Is_bitmap = 1;
 
142
      break;
 
143
    default:
 
144
      #if defined(__macosx__)
 
145
         if(strcasecmp(&name[size-6], "dfont") == 0)
 
146
         {
 
147
           font->Is_truetype = 1;
 
148
           font->Is_bitmap = 0;
 
149
         }
 
150
         else
 
151
         {
 
152
            free(font);
 
153
            return;
 
154
         }
 
155
      #else
 
156
         free(font);
 
157
         return;
 
158
      #endif
 
159
  }
 
160
 
 
161
  font->Name = (char *)malloc(size);
 
162
  strcpy(font->Name, name);
 
163
  // Label
 
164
  strcpy(font->Label, "                   ");
 
165
  if (font->Is_truetype)
 
166
    font->Label[17]=font->Label[18]='T'; // Logo TT
 
167
  font_name=Find_last_slash(font->Name);
 
168
  if (font_name==NULL)
 
169
    font_name=font->Name;
 
170
  else
 
171
    font_name++;
 
172
  for (index=0; index < 17 && font_name[index]!='\0' && font_name[index]!='.'; index++)
 
173
    font->Label[index]=font_name[index];
 
174
 
 
175
  // Gestion Liste
 
176
  font->Next = NULL;
 
177
  font->Previous = NULL;
 
178
  if (font_list_start==NULL)
 
179
  {
 
180
    // Premiere (liste vide)
 
181
    font_list_start = font;
 
182
    Nb_fonts++;
 
183
  }
 
184
  else
 
185
  {
 
186
    int compare;
 
187
    compare = Compare_fonts(font, font_list_start);
 
188
    if (compare<=0)
 
189
    {
 
190
      if (compare==0 && !strcmp(font->Name, font_list_start->Name))
 
191
      {
 
192
        // Doublon
 
193
        free(font->Name);
 
194
        free(font);
 
195
        return;
 
196
      }
 
197
      // Avant la premiere
 
198
      font->Next=font_list_start;
 
199
      font_list_start=font;
 
200
      Nb_fonts++;
 
201
    }
 
202
    else
 
203
    {
 
204
      T_Font *searched_font;
 
205
      searched_font=font_list_start;
 
206
      while (searched_font->Next && (compare=Compare_fonts(font, searched_font->Next))>0)
 
207
        searched_font=searched_font->Next;
 
208
      // Apr�s searched_font
 
209
      if (compare==0 && strcmp(font->Name, searched_font->Next->Name)==0)
 
210
      {
 
211
        // Doublon
 
212
        free(font->Name);
 
213
        free(font);
 
214
        return;
 
215
      }
 
216
      font->Next=searched_font->Next;
 
217
      searched_font->Next=font;
 
218
      Nb_fonts++;
 
219
    }
 
220
  }
 
221
}
 
222
 
 
223
 
 
224
// Trouve le nom d'une fonte par son num�ro
 
225
char * Font_name(int index)
 
226
{
 
227
  T_Font *font = font_list_start;
 
228
  if (index<0 ||index>=Nb_fonts)
 
229
    return "";
 
230
  while (index--)
 
231
    font = font->Next;
 
232
  return font->Name;
 
233
}
 
234
 
 
235
 
 
236
// Trouve le libell� d'affichage d'une fonte par son num�ro
 
237
// Renvoie un pointeur sur un buffer statique de 20 caracteres.
 
238
char * Font_label(int index)
 
239
{
 
240
  T_Font *font;
 
241
  static char label[20];
 
242
  
 
243
  strcpy(label, "                   ");
 
244
  
 
245
  // Recherche de la fonte
 
246
  font = font_list_start;
 
247
  if (index<0 ||index>=Nb_fonts)
 
248
    return label;
 
249
  while (index--)
 
250
    font = font->Next;
 
251
  
 
252
  // Libell�
 
253
  strcpy(label, font->Label);
 
254
  return label;
 
255
}
 
256
 
 
257
 
 
258
// V�rifie si une fonte donn�e est TrueType
 
259
int TrueType_font(int index)
 
260
{
 
261
  T_Font *font = font_list_start;
 
262
  if (index<0 ||index>=Nb_fonts)
 
263
    return 0;
 
264
  while (index--)
 
265
    font = font->Next;
 
266
  return font->Is_truetype;
 
267
}
 
268
 
 
269
 
 
270
 
 
271
// Initialisation � faire une fois au d�but du programme
 
272
void Init_text(void)
 
273
{
 
274
  char directory_name[MAX_PATH_CHARACTERS];
 
275
  #ifndef NOTTF
 
276
  // Initialisation de TTF
 
277
  TTF_Init();
 
278
  #endif
 
279
  
 
280
  // Initialisation des fontes
 
281
  font_list_start = NULL;
 
282
  Nb_fonts=0;
 
283
  // Parcours du r�pertoire "fonts"
 
284
  strcpy(directory_name, Data_directory);
 
285
  strcat(directory_name, "fonts");
 
286
  For_each_file(directory_name, Add_font);
 
287
  
 
288
  #if defined(__WIN32__)
 
289
    // Parcours du r�pertoire systeme windows "fonts"
 
290
    #ifndef NOTTF
 
291
    {
 
292
      char * WindowsPath=getenv("windir");
 
293
      if (WindowsPath)
 
294
      {
 
295
        sprintf(directory_name, "%s\\FONTS", WindowsPath);
 
296
        For_each_file(directory_name, Add_font);
 
297
      }
 
298
    }
 
299
    #endif
 
300
  #elif defined(__macosx__)
 
301
    // R�cup�ration de la liste des fonts avec fontconfig
 
302
    #ifndef NOTTF
 
303
 
 
304
 
 
305
      int i,number;
 
306
      char home_dir[MAXPATHLEN];
 
307
      char *font_path_list[3] = {
 
308
         "/System/Library/Fonts",
 
309
         "/Library/Fonts"
 
310
      };
 
311
      number = 3;
 
312
      // Make sure we also search into the user's fonts directory
 
313
      CFURLRef url = (CFURLRef) CFCopyHomeDirectoryURLForUser(NULL);
 
314
      CFURLGetFileSystemRepresentation(url, true, (UInt8 *) home_dir, MAXPATHLEN);
 
315
      strcat(home_dir, "/Library/Fonts");
 
316
      font_path_list[2] = home_dir;
 
317
 
 
318
      for(i=0;i<number;i++)
 
319
         For_each_file(*(font_path_list+i),Add_font);
 
320
 
 
321
      CFRelease(url);
 
322
    #endif
 
323
 
 
324
  #elif defined(__linux__)
 
325
    #ifndef NOTTF
 
326
       #define USE_XLIB
 
327
    
 
328
       #ifdef USE_XLIB
 
329
       {
 
330
        int i,number;
 
331
        Display* dpy = XOpenDisplay(NULL);
 
332
        char** font_path_list = XGetFontPath(dpy,&number);
 
333
        XCloseDisplay(dpy);
 
334
 
 
335
        for(i=0;i<number;i++)
 
336
            For_each_file(*(font_path_list+i),Add_font);
 
337
 
 
338
        XFreeFontPath(font_path_list);
 
339
       }
 
340
       #endif
 
341
    #endif
 
342
  #elif defined(__amigaos4__) || defined(__amigaos__)
 
343
    #ifndef NOTTF
 
344
      For_each_file( "FONTS:_TrueType", Add_font );
 
345
    #endif
 
346
  #elif defined(__BEOS__) || defined(__HAIKU__)
 
347
    #ifndef NOTTF
 
348
      For_each_file("/etc/fonts/ttfonts", Add_font);
 
349
    #endif
 
350
 
 
351
  #elif defined(__SKYOS__)
 
352
    #ifndef NOTTF
 
353
      For_each_file("/boot/system/fonts", Add_font);
 
354
    #endif
 
355
 
 
356
  #endif
 
357
}
 
358
 
 
359
// Informe si texte.c a �t� compil� avec l'option de support TrueType ou pas.
 
360
int TrueType_is_supported()
 
361
{
 
362
  #ifdef NOTTF
 
363
  return 0;
 
364
  #else
 
365
  return 1;
 
366
  #endif
 
367
}
 
368
 
 
369
  
 
370
#ifndef NOTTF
 
371
byte *Render_text_TTF(const char *str, int font_number, int size, int antialias, int bold, int italic, int *width, int *height)
 
372
{
 
373
 TTF_Font *font;
 
374
  SDL_Surface * TexteColore;
 
375
  SDL_Surface * Texte8Bit;
 
376
  byte * new_brush;
 
377
  int index;
 
378
  int style;
 
379
  
 
380
  SDL_Color Couleur_Avant;
 
381
  SDL_Color Couleur_Arriere;
 
382
 
 
383
  // Chargement de la fonte
 
384
  font=TTF_OpenFont(Font_name(font_number), size);
 
385
  if (!font)
 
386
  {
 
387
    return NULL;
 
388
  }
 
389
  // Style
 
390
  style=0;
 
391
  if (italic)
 
392
    style|=TTF_STYLE_ITALIC;
 
393
  if (bold)
 
394
    style|=TTF_STYLE_BOLD;
 
395
  TTF_SetFontStyle(font, style);
 
396
  // Couleurs
 
397
  if (antialias)
 
398
  {
 
399
    Couleur_Avant = Color_to_SDL_color(Fore_color);
 
400
    Couleur_Arriere = Color_to_SDL_color(Back_color);
 
401
  }
 
402
  else
 
403
  {
 
404
    Couleur_Avant = Color_to_SDL_color(MC_White);
 
405
    Couleur_Arriere = Color_to_SDL_color(MC_Black);
 
406
  }
 
407
 
 
408
  
 
409
  // Rendu du texte: cr�e une surface SDL RGB 24bits
 
410
  if (antialias)
 
411
    TexteColore=TTF_RenderText_Shaded(font, str, Couleur_Avant, Couleur_Arriere );
 
412
  else
 
413
    TexteColore=TTF_RenderText_Solid(font, str, Couleur_Avant);
 
414
  if (!TexteColore)
 
415
  {
 
416
    TTF_CloseFont(font);
 
417
    return NULL;
 
418
  }
 
419
  
 
420
  Texte8Bit=SDL_DisplayFormat(TexteColore);
 
421
 
 
422
  SDL_FreeSurface(TexteColore);
 
423
    
 
424
  new_brush=Surface_to_bytefield(Texte8Bit, NULL);
 
425
  if (!new_brush)
 
426
  {
 
427
    SDL_FreeSurface(TexteColore);
 
428
    SDL_FreeSurface(Texte8Bit);
 
429
    TTF_CloseFont(font);
 
430
    return NULL;
 
431
  }
 
432
  if (!antialias)
 
433
  {
 
434
    // Mappage des couleurs
 
435
    for (index=0; index < Texte8Bit->w * Texte8Bit->h; index++)
 
436
    {
 
437
      if (*(new_brush+index) == MC_Black)
 
438
      *(new_brush+index)=Back_color;
 
439
      else if (*(new_brush+index) == MC_White)
 
440
      *(new_brush+index)=Fore_color;
 
441
    }
 
442
  }
 
443
  *width=Texte8Bit->w;
 
444
  *height=Texte8Bit->h;
 
445
  SDL_FreeSurface(Texte8Bit);
 
446
  TTF_CloseFont(font);
 
447
  return new_brush;
 
448
}
 
449
#endif
 
450
 
 
451
 
 
452
byte *Render_text_SFont(const char *str, int font_number, int *width, int *height)
 
453
{
 
454
  SFont_Font *font;
 
455
  SDL_Surface * TexteColore;
 
456
  SDL_Surface * Texte8Bit;
 
457
  SDL_Surface *Surface_fonte;
 
458
  byte * new_brush;
 
459
  SDL_Rect rectangle;
 
460
 
 
461
  // Chargement de la fonte
 
462
  Surface_fonte=IMG_Load(Font_name(font_number));
 
463
  if (!Surface_fonte)
 
464
  {
 
465
    DEBUG("Font loading failed",0);
 
466
    return NULL;
 
467
  }
 
468
  font=SFont_InitFont(Surface_fonte);
 
469
  if (!font)
 
470
  {
 
471
    DEBUG("Font init failed",1);
 
472
    return NULL;
 
473
  }
 
474
  
 
475
  // Calcul des dimensions
 
476
  *height=SFont_TextHeight(font);
 
477
  *width=SFont_TextWidth(font, str);
 
478
  // Allocation d'une surface SDL
 
479
  TexteColore=SDL_CreateRGBSurface(SDL_SWSURFACE, *width, *height, 24, 0, 0, 0, 0);
 
480
  // Fill with backcolor
 
481
  rectangle.x=0;
 
482
  rectangle.y=0;
 
483
  rectangle.w=*width;
 
484
  rectangle.h=*height;
 
485
  SDL_FillRect(TexteColore, &rectangle, SDL_MapRGB(
 
486
    TexteColore->format, 
 
487
    Main_palette[Back_color].R, 
 
488
    Main_palette[Back_color].G, 
 
489
    Main_palette[Back_color].B
 
490
    ));
 
491
  // Rendu du texte
 
492
  SFont_Write(TexteColore, font, 0, 0, str);
 
493
  if (!TexteColore)
 
494
  {
 
495
    DEBUG("Rendering failed",2);
 
496
    SFont_FreeFont(font);
 
497
    return NULL;
 
498
  }
 
499
  
 
500
  Texte8Bit=SDL_DisplayFormat(TexteColore);
 
501
  SDL_FreeSurface(TexteColore);
 
502
    
 
503
  new_brush=Surface_to_bytefield(Texte8Bit, NULL);
 
504
  if (!new_brush)
 
505
  {
 
506
    DEBUG("Converting failed",3);
 
507
    SDL_FreeSurface(TexteColore);
 
508
    SDL_FreeSurface(Texte8Bit);
 
509
    SFont_FreeFont(font);
 
510
    return NULL;
 
511
  }
 
512
  SDL_FreeSurface(Texte8Bit);
 
513
  SFont_FreeFont(font);
 
514
 
 
515
  return new_brush;
 
516
}
 
517
 
 
518
#ifdef NOTTF
 
519
  #define TTFONLY __attribute__((unused))
 
520
#else
 
521
  #define TTFONLY
 
522
#endif
 
523
 
 
524
// Cr�e une brosse � partir des param�tres de texte demand�s.
 
525
// Si cela r�ussit, la fonction place les dimensions dans width et height, 
 
526
// et retourne l'adresse du bloc d'octets.
 
527
byte *Render_text(const char *str, int font_number, TTFONLY int size, int TTFONLY antialias, TTFONLY int bold, TTFONLY int italic, int *width, int *height)
 
528
{
 
529
  T_Font *font = font_list_start;
 
530
  int index=font_number;
 
531
  
 
532
  // Verification type de la fonte
 
533
  if (font_number<0 ||font_number>=Nb_fonts)
 
534
    return NULL;
 
535
    
 
536
  while (index--)
 
537
    font = font->Next;
 
538
  if (font->Is_truetype)
 
539
  {
 
540
  #ifndef NOTTF 
 
541
    return Render_text_TTF(str, font_number, size, antialias, bold, italic, width, height);
 
542
  #else
 
543
    return NULL;
 
544
  #endif
 
545
  }
 
546
  else
 
547
  {
 
548
    return Render_text_SFont(str, font_number, width, height);
 
549
  }
 
550
}
 
551
 
 
552