diff --git a/src/SFont.c b/src/SFont.c index 0e9a8c95..fef5b17f 100644 --- a/src/SFont.c +++ b/src/SFont.c @@ -69,7 +69,7 @@ static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y) SFont_Font* SFont_InitFont(SDL_Surface* Surface) { - int x = 0, i = 0; + int x = 0, i = 33; Uint32 pixel; SFont_Font* Font; Uint32 pink; @@ -78,21 +78,42 @@ SFont_Font* SFont_InitFont(SDL_Surface* Surface) return NULL; Font = (SFont_Font *) malloc(sizeof(SFont_Font)); + memset(Font, 0, sizeof(SFont_Font)); + Font->Surface = Surface; SDL_LockSurface(Surface); - pink = SDL_MapRGB(Surface->format, 255, 0, 255); + pink = GetPixel(Surface, 0, 0); while (x < Surface->w) { - if (GetPixel(Surface, x, 0) == pink) { - Font->CharPos[i++]=x; - while((x < Surface->w) && (GetPixel(Surface, x, 0)== pink)) + if (GetPixel(Surface, x, 0) != pink) { + Font->CharBegin[i]=x; + while((x < Surface->w) && (GetPixel(Surface, x, 0)!= pink)) x++; - Font->CharPos[i++]=x; + Font->CharWidth[i]=x-Font->CharBegin[i]; + i++; } 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); SDL_UnlockSurface(Surface); @@ -111,7 +132,6 @@ void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font, int x, int y, const char *text) { const char* c; - int charoffset; SDL_Rect srcrect, dstrect; 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; for(c = text; *c != '\0' && x <= Surface->w ; c++) { - charoffset = ((int) (*c - 33)) * 2 + 1; // skip spaces and nonprintable characters - if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) { - x += Font->CharPos[2]-Font->CharPos[1]; + if (*c == ' ' || Font->CharWidth[(int)*c]==0) { + x += Font->Space; continue; } - srcrect.w = Font->CharPos[charoffset+2] - Font->CharPos[charoffset]; + srcrect.w = Font->CharWidth[(int)*c]; dstrect.w = srcrect.w; - srcrect.x = Font->CharPos[charoffset]; + srcrect.x = Font->CharBegin[(int)*c]; dstrect.x = x; 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) { const char* c; - int charoffset=0; int width = 0; if(text == NULL) return 0; for(c = text; *c != '\0'; c++) { - charoffset = ((int) *c - 33) * 2 + 1; // skip spaces and nonprintable characters - if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) { - width += Font->CharPos[2]-Font->CharPos[1]; + if (*c == ' ' || Font->CharWidth[(int)*c]==0) { + width += Font->Space; continue; } - width += Font->CharPos[charoffset+1] - Font->CharPos[charoffset]; + width += Font->CharWidth[(int)*c]; } return width; diff --git a/src/SFont.h b/src/SFont.h index bca5fae2..27a54937 100644 --- a/src/SFont.h +++ b/src/SFont.h @@ -56,8 +56,9 @@ extern "C" { /// and call InitFont( YourFont ); typedef struct { SDL_Surface *Surface; - int CharPos[512]; - int MaxPos; + int CharBegin[256]; + int CharWidth[256]; + int Space; } SFont_Font; /// diff --git a/src/op_c.c b/src/op_c.c index 8bcc065a..8544b7cc 100644 --- a/src/op_c.c +++ b/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); } +/// +/// 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 // 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 diff --git a/src/op_c.h b/src/op_c.h index ead494db..76b544a2 100644 --- a/src/op_c.h +++ b/src/op_c.h @@ -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 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 // diff --git a/src/palette.c b/src/palette.c index 082cc118..94b34417 100644 --- a/src/palette.c +++ b/src/palette.c @@ -1641,10 +1641,10 @@ void Button_Palette(void) = Requester_window("Enter the max. number of colors", reduce_colors_number); if (reduce_colors_number < 2 || reduce_colors_number >= 256) - reduce_colors_number = -1; + reduce_colors_number = 256; break; } - if (reduce_colors_number > 0) + if (reduce_colors_number != 256) { if (!image_is_backed_up) { @@ -2089,6 +2089,9 @@ void Button_Palette(void) byte remap_table[256]; byte inverted_table[256]; byte begin, end; + long lightness; + long old_lightness; + if(block_start==block_end) { @@ -2112,7 +2115,7 @@ void Button_Palette(void) } 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) { 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) { swap=0; - l=255; - for(temp_color=begin;temp_color<=end;temp_color++) + lightness=Perceptual_lightness(working_palette+begin); + for(temp_color=begin+1;temp_color<=end;temp_color++) { - ol=l; - RGB_to_HSL(working_palette[temp_color].R, - working_palette[temp_color].G, - working_palette[temp_color].B,&h,&s,&l); + old_lightness=lightness; + lightness=Perceptual_lightness(working_palette+temp_color); - if(l>ol) + if(lightness>old_lightness) { // Swap color with the previous one SWAP_BYTES(working_palette[temp_color].R, working_palette[temp_color-1].R)