[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ft] Problem rendering Arabic Text.
From: |
Blaine1666 |
Subject: |
[ft] Problem rendering Arabic Text. |
Date: |
Wed, 25 Apr 2012 01:07:06 -0700 (PDT) |
I've an application that uses SDL, SGE and Freetype libraries to render text
on Screen. Latin text works fine, but Arabic text appears from left to
right. This is a complex language, is RTL and the glyphs are different
depending on the possition, and my application doesn't care.
Is there a solution to Load and render each character but deppending if text
is RTL/LTR and drawing the correct character deppending if is Arabic etc..?
I don't know how can I solve this. Here is the source code that render a
unicode texts and draw them on screen with SGE and SDL libraries:
//==================================================================================
// TT Render (unicode)
// Returns an 8bit or 32bit(8/8/8/8-alpha) surface with TT text
//==================================================================================
SDL_Surface *sge_TTF_RenderUNICODE(sge_TTFont *font,const Uint16 *text,
SDL_Color fg, SDL_Color bg)
{
int xstart, width;
int w, h;
SDL_Surface *textbuf;
SDL_Palette *palette;
int index;
int rdiff, gdiff, bdiff;
const Uint16 *ch;
Uint8 *src, *dst;
Uint32 *dst32;
int row, col;
TT_Error error;
sge_TTF_FitToBox_UNI( font, text );
/* Get the dimensions of the text surface */
SDL_Rect ret=sge_TTF_TextSize_UNI(font, text);
w=ret.w; h=ret.h;
if ( !w ) {
SDL_SetError("SGE - Text has zero width");
return(NULL);
}
/* Create the target surface */
width = w;
w = (w+6)&~3;
if(_sge_TTF_AA!=2) /* Allocate an 8-bit pixmap */
textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
else /* Allocate an 32-bit alpha pixmap */
textbuf = sge_CreateAlphaSurface(SDL_SWSURFACE,w,h);
if ( textbuf == NULL ) {
SDL_SetError("SGE - Out of memory");
return(NULL);
}
/* Setup our colors */
Uint32 ctab[8]={0,0,0,0,0,0,0,0};
switch(_sge_TTF_AA){
case 0:{ /* No fancy antialiasing or alpha component */
palette = textbuf->format->palette;
palette->colors[0].r = bg.r;
palette->colors[0].g = bg.g;
palette->colors[0].b = bg.b;
palette->colors[1].r = fg.r;
palette->colors[1].g = fg.g;
palette->colors[1].b = fg.b;
}
break;
case 1:{ /* Fill the palette with 5 levels of shading from bg
to fg */
palette = textbuf->format->palette;
rdiff = fg.r - bg.r;
gdiff = fg.g - bg.g;
bdiff = fg.b - bg.b;
for ( index=0; index<5; ++index ) {
palette->colors[index].r = bg.r +
(index*rdiff)/4;
palette->colors[index].g = bg.g +
(index*gdiff)/4;
palette->colors[index].b = bg.b +
(index*bdiff)/4;
}
/* The other 3 levels are used as overflow when ORing
pixels */
for ( ; index<8; ++index ) {
palette->colors[index] = palette->colors[4];
}
}
break;
case 2:{ /* Alpha component magic */
ctab[0]=sge_MapAlpha(bg.r,bg.g,bg.b,SDL_ALPHA_TRANSPARENT); //The
background (transparent color)
ctab[4]=sge_MapAlpha(fg.r,fg.g,fg.b,SDL_ALPHA_OPAQUE);
//The color of
the font
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION,
SDL_MINOR_VERSION, SDL_PATCHLEVEL)
>= \
SDL_VERSIONNUM(1, 1, 5)
sge_AlphaFader(fg.r,fg.g,fg.b,10, fg.r,fg.g,fg.b,190,
ctab,1,3); //Alpha
fading
#else
sge_AlphaFader(fg.r,fg.g,fg.b,190, fg.r,fg.g,fg.b,10,
ctab,1,3); //Alpha
fading
#endif
sge_ClearSurface(textbuf,
sge_MapAlpha(bg.r,bg.g,bg.b,SDL_ALPHA_TRANSPARENT));
ctab[5]=ctab[6]=ctab[7];
}
break;
}
/* Load and render each character */
//xstart = 3;
// start drawing in the left-most pixel!
// otherwise text width calculated to fit the box will be overriden!
xstart = 0;
for ( ch=text; *ch; ++ch ) {
error = Find_Glyph(font, *ch);
if ( ! error ) {
w = font->current->pixmap.width;
src = (Uint8 *)font->current->pixmap.bitmap;
for ( row = 0; row < h; ++row ) {
dst = (Uint8 *)textbuf->pixels + row *
textbuf->pitch + xstart +
font->current->minx;
switch(_sge_TTF_AA){
case 0:{ /* Normal */
for ( col=w; col>0; col -= 4 ) {
*dst++ |= (*src++<3)?
0:1;
*dst++ |= (*src++<3)?
0:1;
*dst++ |= (*src++<3)?
0:1;
*dst++ |= (*src++<3)?
0:1;
}
}
break;
case 1:{ /* Antialiasing */
for ( col=w; col>0; col -= 4 ) {
*dst++ |= *src++;
*dst++ |= *src++;
*dst++ |= *src++;
*dst++ |= *src++;
}
}
break;
case 2:{ /* Alpha */
dst32 = (Uint32
*)textbuf->pixels + row * textbuf->pitch/4 + xstart +
font->current->minx;
for ( col=w; col>0; col -= 4 ) {
*dst32++ |=
ctab[*src++];
*dst32++ |=
ctab[*src++];
*dst32++ |=
ctab[*src++];
*dst32++ |=
ctab[*src++];
}
}
break;
}
}
xstart += font->current->advance;
if ( font->style & SGE_TTF_BOLD ) {
xstart += font->glyph_overhang;
}
}
}
/* Handle the underline style */
if ( font->style & SGE_TTF_UNDERLINE ) {
int row_offset;
row_offset = round(font->ascent) + 1;
if ( row_offset > font->height ) {
row_offset = font->height-1;
}
if(_sge_TTF_AA==0){
memset((Uint8
*)textbuf->pixels+row_offset*textbuf->pitch, 1, width);
}else if(_sge_TTF_AA==1){
memset((Uint8
*)textbuf->pixels+row_offset*textbuf->pitch, 4, width);
}else{
dst32 = (Uint32
*)textbuf->pixels+row_offset*textbuf->pitch/4;
for ( col=width; col > 0; --col ) {
*dst32++ = ctab[4];
}
}
}
return(textbuf);
}
//==================================================================================
// Find glyph
//==================================================================================
TT_Error Find_Glyph(sge_TTFont *font, Uint16 ch)
{
int retval;
retval = 0;
if ( ch < 256 ) {
font->current = &font->cache[ch];
} else {
if ( font->scratch.cached != ch ) {
Flush_Glyph(&font->scratch);
}
font->current = &font->scratch;
}
if ( ! font->current->cached ) {
retval = Load_Glyph(font, ch, font->current);
}
return retval;
}
--
View this message in context:
http://old.nabble.com/Problem-rendering-Arabic-Text.-tp33744959p33744959.html
Sent from the Freetype - User mailing list archive at Nabble.com.
- [ft] Problem rendering Arabic Text.,
Blaine1666 <=