Index: firmware/bidi.c =================================================================== --- firmware/bidi.c (revision 25039) +++ firmware/bidi.c (working copy) @@ -30,6 +30,7 @@ #include "arabjoin.h" #include "scroll_engine.h" #include "bidi.h" +#include "diacritic.h" /* #define _HEB_BUFFER_LENGTH (MAX_PATH + LCD_WIDTH/2 + 3 + 2 + 2) * 2 */ #define _HEB_BLOCK_TYPE_ENG 1 @@ -61,30 +62,43 @@ { bool connected = false; unsigned short * writeprt = stringprt; - + short is_diac = 0; + unsigned short * diac_ptr = 0; const arab_t * prev = 0; const arab_t * cur; const arab_t * ligature = 0; short uchar; - int i; + int i,j; for (i = 0; i <= length; i++) { cur = arab_lookup(uchar = *stringprt++); - /* Skip non-arabic chars */ + /* Skip non-arabic chars */ /* (actually this skips diacritics too as they are commented in arabjoin.c) */ if (cur == 0) { - if (prev) { + if (is_diacritic(uchar, NULL)) { /* skip diacritics without affecting the shaping algorithm (apply joining as if there is no diacritics) */ + if(!is_diac) + diac_ptr = stringprt - 1; + is_diac++; + } + else if (prev) /* non-arabic characters */ + { /* Finish the last char */ if (connected) { *writeprt++ = prev->final; connected = false; - } else + } + else *writeprt++ = prev->isolated; prev = 0; + if (is_diac) { /* write the skipped diacritics */ + for (j = 0; j < is_diac; j++) + *writeprt++ = *diac_ptr++; + is_diac = 0; + } *writeprt++ = uchar; - } else { + } + else *writeprt++ = uchar; - } continue; } @@ -129,6 +143,11 @@ } else *writeprt++ = prev->isolated; } + if (is_diac) { /* write the skipped diacritics */ + for (j = 0; j < is_diac; j++) + *writeprt++ = *diac_ptr++; + is_diac = 0; + } prev = cur; } } Index: firmware/drivers/lcd-bitmap-common.c =================================================================== --- firmware/drivers/lcd-bitmap-common.c (revision 25309) +++ firmware/drivers/lcd-bitmap-common.c (working copy) @@ -84,10 +84,14 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) { unsigned short *ucs; + unsigned char bits_tmp[400]; + int k; struct font* pf = font_get(current_vp->font); int vp_flags = current_vp->flags; int rtl_next_non_diac_width, last_non_diacritic_width; + for(k = 0; k < 400; k++) + bits_tmp[k] = 0; if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0) { int w; @@ -115,7 +119,7 @@ { bool is_rtl, is_diac; const unsigned char *bits; - int width, base_width, drawmode = 0, base_ofs = 0; + int width, base_width, base_ofs = 0; const unsigned short next_ch = ucs[1]; if (x >= current_vp->width) @@ -165,35 +169,15 @@ if (is_diac) { - /* XXX: Suggested by amiconn: - * This will produce completely wrong results if the original - * drawmode is DRMODE_COMPLEMENT. We need to pre-render the current - * character with all its diacritics at least (in mono) and then - * finally draw that. And we'll need an extra buffer that can hold - * one char's bitmap. Basically we can't just change the draw mode - * to something else irrespective of the original mode and expect - * the result to look as intended and with DRMODE_COMPLEMENT (which - * means XORing pixels), overdrawing this way will cause odd results - * if the diacritics and the base char both have common pixels set. - * So we need to combine the char and its diacritics in a temp - * buffer using OR, and then draw the final bitmap instead of the - * chars, without touching the drawmode - **/ - drawmode = current_vp->drawmode; - current_vp->drawmode = DRMODE_FG; - base_ofs = (base_width - width) / 2; } bits = font_get_bits(pf, *ucs); - LCDFN(mono_bitmap_part)(bits, ofs, 0, width, x + base_ofs, y, + for(k = 0; k < 400; k++) + bits_tmp[k] = bits_tmp[k] | *bits++; + LCDFN(mono_bitmap_part)(bits_tmp, ofs, 0, width, x + base_ofs, y, width - ofs, pf->height); - if (is_diac) - { - current_vp->drawmode = drawmode; - } - if (next_ch) { bool next_is_rtl; @@ -207,6 +191,8 @@ { x += base_width - ofs; ofs = 0; + for(k = 0; k < 400; k++) + bits_tmp[k] = 0; } } }