/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#include "font/anti_prop.hh"
#include "image/image.hh"
#include "palette/pal.hh"
#include "image/context.hh"
/* Printable english characters
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | }
"
*/
static inline int i4_is_black(w32 c)
{
if ((c&0xff000000)==0)
return 1;
else return 0;
}
static inline int i4_scanline_empty(i4_image_class *im, int y)
{
for (int x=0; xwidth(); x++)
if (!i4_is_black(im->get_pixel(x,y)))
return 0;
return 1;
}
static inline int i4_colum_empty(i4_image_class *im, int x)
{
for (int y=0; yheight(); y++)
if (!i4_is_black(im->get_pixel(x,y)))
return 0;
return 1;
}
static inline int i4_image_has_alpha(i4_image_class *im)
{
for (int y=0; yheight(); y++)
for (int x=0; xwidth(); x++)
{
w32 cl=im->get_pixel(x,y);
if (cl>>24)
i4_warning("alpha %d", cl>>24);
}
return 1;
}
class i4_anti_image_class : public i4_image_class
{
public:
w32 current_color;
virtual i4_image_class *copy()
{
i4_anti_image_class *i=new i4_anti_image_class(w,h);
memcpy(i->data, data, w*h);
return i;
}
virtual w16 width() { return w; }
virtual w16 height() { return h; }
void set_color(w32 c) { current_color=c; }
virtual void put_pixel(i4_coord x, i4_coord y, w32 color)
{
*((w8 *)data+x+y*w)=color>>24;
}
virtual w32 get_pixel(i4_coord x, i4_coord y)
{
return ((*((w8 *)data+x+y*w))<<24) | current_color;
}
i4_anti_image_class(w16 _w, w16 _h)
{
w=_w;
h=_h;
bpl=w;
i4_pixel_format fmt;
fmt.default_format();
pal=i4_pal_man.register_pal(&fmt);
data=i4_malloc(w*h,"");
current_color=0xffffff;
}
~i4_anti_image_class()
{
i4_free(data);
}
};
void i4_anti_proportional_font_class::put_string(i4_image_class *screen,
sw16 x, sw16 y,
const i4_const_str &string,
i4_draw_context_class &context)
{
if (!string.null())
{
for (i4_const_str::iterator p=string.begin(); p!=string.end(); ++p)
{
char ch=p.get().ascii_value();
if (offsets[ch])
{
aim->put_part(screen, x,y, offsets[ch], 0, offsets[ch]+widths[ch]-1, aim->height()-1,
context);
x+=widths[ch];
}
else x+=4;
}
}
}
void i4_anti_proportional_font_class::put_character(i4_image_class *screen,
sw16 x, sw16 y,
const i4_char &c,
i4_draw_context_class &context)
{
int ch=c.ascii_value();
int xo=offsets[ch];
if (xo)
aim->put_part(screen, x,y, xo,0,xo+widths[ch]-1,aim->height(), context);
}
i4_anti_proportional_font_class::i4_anti_proportional_font_class(i4_image_class *im,
int start_ch)
{
memset(offsets, 0, sizeof(offsets));
longest_w=2;
// i4_image_has_alpha(im);
int y_top=0, y_bottom=im->height()-1, x1=0,x2,i;
for (i=0; i<256; i++)
widths[i]=4;
while (y_top<=y_bottom && i4_scanline_empty(im, y_top))
y_top++;
if (y_top==y_bottom-1)
i4_error("image is empty");
while (i4_scanline_empty(im, y_bottom))
y_bottom--;
int char_on=start_ch;
int x=1;
do
{
while (x1!=im->width() && i4_colum_empty(im, x1)) x1++;
if (x1width())
{
x2=x1+1;
while (x2!=im->width() &&
!(i4_colum_empty(im, x2) && i4_colum_empty(im, x2+1))) x2++;
widths[char_on]=x2-x1+1;
if (widths[char_on]>longest_w)
longest_w=widths[char_on];
offsets[char_on]=x;
x+=x2-x1+1;
x1=x2+2;
}
char_on++;
} while (x1width());
h=y_bottom-y_top+1;
aim=new i4_anti_image_class(x, h);
x1=0; x=1;
i4_draw_context_class context(0,0, aim->width()-1, aim->height()-1);
char_on=start_ch;
do
{
while (x1!=im->width() && i4_colum_empty(im, x1)) x1++;
if (x1width())
{
x2=x1+1;
while (x2!=im->width() &&
!(i4_colum_empty(im, x2) && i4_colum_empty(im, x2+1))) x2++;
im->i4_image_class::put_part(aim, x, 0, x1, y_top, x2, y_bottom, context);
x+=x2-x1+1;
x1=x2+2;
}
char_on++;
} while (x1width());
}
void i4_anti_proportional_font_class::set_color(i4_color color)
{
aim->set_color(color);
}
i4_anti_proportional_font_class::~i4_anti_proportional_font_class()
{
delete aim;
}