Palette sort (on brightness) now uses a better formula, provided by DawnBringer. Text tool no longer crashes with some fonts. Added support for bitmap fonts from 'Bitmap Font Writer', such as those from http://www.zone38.net/font/bmpfont.html or http://www.matriaxweb.com/others.htm or http://www.genvid.com/moonstruck/downloads/fonts.html
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1530 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
e6ced5f6a0
commit
d5ecba7b6c
55
src/SFont.c
55
src/SFont.c
@ -69,7 +69,7 @@ static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
|
|||||||
|
|
||||||
SFont_Font* SFont_InitFont(SDL_Surface* Surface)
|
SFont_Font* SFont_InitFont(SDL_Surface* Surface)
|
||||||
{
|
{
|
||||||
int x = 0, i = 0;
|
int x = 0, i = 33;
|
||||||
Uint32 pixel;
|
Uint32 pixel;
|
||||||
SFont_Font* Font;
|
SFont_Font* Font;
|
||||||
Uint32 pink;
|
Uint32 pink;
|
||||||
@ -78,21 +78,42 @@ SFont_Font* SFont_InitFont(SDL_Surface* Surface)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Font = (SFont_Font *) malloc(sizeof(SFont_Font));
|
Font = (SFont_Font *) malloc(sizeof(SFont_Font));
|
||||||
|
memset(Font, 0, sizeof(SFont_Font));
|
||||||
|
|
||||||
Font->Surface = Surface;
|
Font->Surface = Surface;
|
||||||
|
|
||||||
SDL_LockSurface(Surface);
|
SDL_LockSurface(Surface);
|
||||||
|
|
||||||
pink = SDL_MapRGB(Surface->format, 255, 0, 255);
|
pink = GetPixel(Surface, 0, 0);
|
||||||
while (x < Surface->w) {
|
while (x < Surface->w) {
|
||||||
if (GetPixel(Surface, x, 0) == pink) {
|
if (GetPixel(Surface, x, 0) != pink) {
|
||||||
Font->CharPos[i++]=x;
|
Font->CharBegin[i]=x;
|
||||||
while((x < Surface->w) && (GetPixel(Surface, x, 0)== pink))
|
while((x < Surface->w) && (GetPixel(Surface, x, 0)!= pink))
|
||||||
x++;
|
x++;
|
||||||
Font->CharPos[i++]=x;
|
Font->CharWidth[i]=x-Font->CharBegin[i];
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
Font->MaxPos = x-1;
|
|
||||||
|
// Create lowercase characters, if not present
|
||||||
|
for (i=0; i <26; i++)
|
||||||
|
{
|
||||||
|
if (Font->CharWidth['a'+i]==0)
|
||||||
|
{
|
||||||
|
Font->CharBegin['a'+i]=Font->CharBegin['A'+i];
|
||||||
|
Font->CharWidth['a'+i]=Font->CharWidth['A'+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine space width.
|
||||||
|
// This strange format doesn't allow font designer to write explicit
|
||||||
|
// space as a character.
|
||||||
|
// Rule: A space should be as large as the character " if available,
|
||||||
|
// or 'a' if it's not.
|
||||||
|
Font->Space = Font->CharWidth[(int)'"'];
|
||||||
|
if (Font->Space<2)
|
||||||
|
Font->Space = Font->CharWidth[(int)'a'];
|
||||||
|
|
||||||
pixel = GetPixel(Surface, 0, Surface->h-1);
|
pixel = GetPixel(Surface, 0, Surface->h-1);
|
||||||
SDL_UnlockSurface(Surface);
|
SDL_UnlockSurface(Surface);
|
||||||
@ -111,7 +132,6 @@ void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font,
|
|||||||
int x, int y, const char *text)
|
int x, int y, const char *text)
|
||||||
{
|
{
|
||||||
const char* c;
|
const char* c;
|
||||||
int charoffset;
|
|
||||||
SDL_Rect srcrect, dstrect;
|
SDL_Rect srcrect, dstrect;
|
||||||
|
|
||||||
if(text == NULL)
|
if(text == NULL)
|
||||||
@ -123,42 +143,39 @@ void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font,
|
|||||||
srcrect.h = dstrect.h = Font->Surface->h - 1;
|
srcrect.h = dstrect.h = Font->Surface->h - 1;
|
||||||
|
|
||||||
for(c = text; *c != '\0' && x <= Surface->w ; c++) {
|
for(c = text; *c != '\0' && x <= Surface->w ; c++) {
|
||||||
charoffset = ((int) (*c - 33)) * 2 + 1;
|
|
||||||
// skip spaces and nonprintable characters
|
// skip spaces and nonprintable characters
|
||||||
if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) {
|
if (*c == ' ' || Font->CharWidth[(int)*c]==0) {
|
||||||
x += Font->CharPos[2]-Font->CharPos[1];
|
x += Font->Space;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
srcrect.w = Font->CharPos[charoffset+2] - Font->CharPos[charoffset];
|
srcrect.w = Font->CharWidth[(int)*c];
|
||||||
dstrect.w = srcrect.w;
|
dstrect.w = srcrect.w;
|
||||||
srcrect.x = Font->CharPos[charoffset];
|
srcrect.x = Font->CharBegin[(int)*c];
|
||||||
dstrect.x = x;
|
dstrect.x = x;
|
||||||
|
|
||||||
SDL_BlitSurface(Font->Surface, &srcrect, Surface, &dstrect);
|
SDL_BlitSurface(Font->Surface, &srcrect, Surface, &dstrect);
|
||||||
|
|
||||||
x += Font->CharPos[charoffset+1] - Font->CharPos[charoffset];
|
x += Font->CharWidth[(int)*c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SFont_TextWidth(const SFont_Font *Font, const char *text)
|
int SFont_TextWidth(const SFont_Font *Font, const char *text)
|
||||||
{
|
{
|
||||||
const char* c;
|
const char* c;
|
||||||
int charoffset=0;
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
|
||||||
if(text == NULL)
|
if(text == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for(c = text; *c != '\0'; c++) {
|
for(c = text; *c != '\0'; c++) {
|
||||||
charoffset = ((int) *c - 33) * 2 + 1;
|
|
||||||
// skip spaces and nonprintable characters
|
// skip spaces and nonprintable characters
|
||||||
if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) {
|
if (*c == ' ' || Font->CharWidth[(int)*c]==0) {
|
||||||
width += Font->CharPos[2]-Font->CharPos[1];
|
width += Font->Space;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
width += Font->CharPos[charoffset+1] - Font->CharPos[charoffset];
|
width += Font->CharWidth[(int)*c];
|
||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
|
|||||||
@ -56,8 +56,9 @@ extern "C" {
|
|||||||
/// and call InitFont( YourFont );
|
/// and call InitFont( YourFont );
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SDL_Surface *Surface;
|
SDL_Surface *Surface;
|
||||||
int CharPos[512];
|
int CharBegin[256];
|
||||||
int MaxPos;
|
int CharWidth[256];
|
||||||
|
int Space;
|
||||||
} SFont_Font;
|
} SFont_Font;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
10
src/op_c.c
10
src/op_c.c
@ -165,6 +165,16 @@ void HSL_to_RGB(byte h,byte s,byte l, byte* r, byte* g, byte* b)
|
|||||||
*b = bf * (255);
|
*b = bf * (255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns a value that is high when color is near white,
|
||||||
|
/// and low when it's darker. Used for sorting.
|
||||||
|
long Perceptual_lightness(T_Components *color)
|
||||||
|
{
|
||||||
|
return 26*color->R*26*color->R +
|
||||||
|
55*color->G*55*color->G +
|
||||||
|
19*color->B*19*color->B;
|
||||||
|
}
|
||||||
|
|
||||||
// Conversion table handlers
|
// Conversion table handlers
|
||||||
// The conversion table is built after a run of the median cut algorithm and is
|
// The conversion table is built after a run of the median cut algorithm and is
|
||||||
// used to find the best color index for a given (RGB) color. GIMP avoids
|
// used to find the best color index for a given (RGB) color. GIMP avoids
|
||||||
|
|||||||
@ -160,6 +160,7 @@ void CT_set(T_Conversion_table * t,int r,int g,int b,byte i);
|
|||||||
void RGB_to_HSL(int r, int g,int b, byte* h, byte*s, byte* l);
|
void RGB_to_HSL(int r, int g,int b, byte* h, byte*s, byte* l);
|
||||||
void HSL_to_RGB(byte h, byte s, byte l, byte* r, byte* g, byte* b);
|
void HSL_to_RGB(byte h, byte s, byte l, byte* r, byte* g, byte* b);
|
||||||
|
|
||||||
|
long Perceptual_lightness(T_Components *color);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////// Méthodes de gestion des tables d'occurence //
|
/////////////////////////////// Méthodes de gestion des tables d'occurence //
|
||||||
|
|||||||
@ -1641,10 +1641,10 @@ void Button_Palette(void)
|
|||||||
= Requester_window("Enter the max. number of colors",
|
= Requester_window("Enter the max. number of colors",
|
||||||
reduce_colors_number);
|
reduce_colors_number);
|
||||||
if (reduce_colors_number < 2 || reduce_colors_number >= 256)
|
if (reduce_colors_number < 2 || reduce_colors_number >= 256)
|
||||||
reduce_colors_number = -1;
|
reduce_colors_number = 256;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (reduce_colors_number > 0)
|
if (reduce_colors_number != 256)
|
||||||
{
|
{
|
||||||
if (!image_is_backed_up)
|
if (!image_is_backed_up)
|
||||||
{
|
{
|
||||||
@ -2089,6 +2089,9 @@ void Button_Palette(void)
|
|||||||
byte remap_table[256];
|
byte remap_table[256];
|
||||||
byte inverted_table[256];
|
byte inverted_table[256];
|
||||||
byte begin, end;
|
byte begin, end;
|
||||||
|
long lightness;
|
||||||
|
long old_lightness;
|
||||||
|
|
||||||
|
|
||||||
if(block_start==block_end)
|
if(block_start==block_end)
|
||||||
{
|
{
|
||||||
@ -2112,7 +2115,7 @@ void Button_Palette(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Window_attribute1==LEFT_SIDE)
|
if(Window_attribute1==LEFT_SIDE)
|
||||||
// Laft click on button: Sort by Hue (H) and Lightness (L)
|
// Left click on button: Sort by Hue (H) and Lightness (L)
|
||||||
while(swap==1)
|
while(swap==1)
|
||||||
{
|
{
|
||||||
swap=0;
|
swap=0;
|
||||||
@ -2143,19 +2146,17 @@ void Button_Palette(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else // Right click > Sort only on L
|
else // Right click > Sort only on perceived lightness
|
||||||
while(swap==1)
|
while(swap==1)
|
||||||
{
|
{
|
||||||
swap=0;
|
swap=0;
|
||||||
l=255;
|
lightness=Perceptual_lightness(working_palette+begin);
|
||||||
for(temp_color=begin;temp_color<=end;temp_color++)
|
for(temp_color=begin+1;temp_color<=end;temp_color++)
|
||||||
{
|
{
|
||||||
ol=l;
|
old_lightness=lightness;
|
||||||
RGB_to_HSL(working_palette[temp_color].R,
|
lightness=Perceptual_lightness(working_palette+temp_color);
|
||||||
working_palette[temp_color].G,
|
|
||||||
working_palette[temp_color].B,&h,&s,&l);
|
|
||||||
|
|
||||||
if(l>ol)
|
if(lightness>old_lightness)
|
||||||
{
|
{
|
||||||
// Swap color with the previous one
|
// Swap color with the previous one
|
||||||
SWAP_BYTES(working_palette[temp_color].R, working_palette[temp_color-1].R)
|
SWAP_BYTES(working_palette[temp_color].R, working_palette[temp_color-1].R)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user