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.


_______________________________________________
Freetype mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/freetype

Reply via email to