freetype
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft] Problem rendering Arabic Text.


From: suzuki toshiya
Subject: Re: [ft] Problem rendering Arabic Text.
Date: Wed, 25 Apr 2012 19:32:38 +0900
User-agent: Mozilla-Thunderbird 2.0.0.12 (X11/20080406)

Hi,

Blaine1666 wrote:
> 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..? 

Do you mean as: the glyph shapes of Arabic script should be appropriately 
changed
for their positions, like, head-of-word, middle-in-word, tail-of-word (and
separated), but at present you cannot realize it by FreeType2?

If so, please consider to use complex text layout libraries, like, Pango, 
HarfBuzz,
ICU, m17n etc. FreeType2 itself does not support complex text layout feature.

Regards,
mpsuzuki

> 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;
> }
> 
> 
> 
> 
> 
> 
> 
>  




reply via email to

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