freetype
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]