QT 2.2.4 (patched) Arabic fixes

Some improvements were made to QT 2.2.4, solving some arabic text rendering issues.
The issues being addressed:
1 - Tashkeel disconnects connectable letters.
2 - Maddah disconnects connectable letters
3 - Lam-Alef is not rendered correctly when it comes between two connecting letters.
I've sent the patch to be incorporated, and it will hopefully, appear in QT 2.3 ( On which KDE 2.1 can still run ).
Arabic pages on Konqueror, look now better than ever.
The arabic rendering is left with one issue, though, QT 2.x doesn't render non-marking spaces (like Tashkeel) correctly in terms of positioning and spacing. Fortuenitly, QT 3.0 promises to solve that in addition to lots of other goodies of Arabic language and BiDi support.
Enjoy,
Kefah T. Issa < [email protected] >

Screenshots

Konqueror with arabic fixes


A sample application before the fix


A sample application after the fix


Sourcecode

[Update : May-05-2001] The hosting site doesn't allow .tar.gz files to be accessed!. Please note that the fix is already implmented in QT 2.3. I'm including the code below, however: The patch is done to qstring.cpp



// This function is used by format()
// This function caters for Non-spacing marks by looking for
// the next non non-spacing mark character and check its connectivity.
static inline bool check_left(QString & str, int index) {
    if  (index < str.length()) {
        if( str[index].category() != QChar::Mark_NonSpacing ) {
	    // the QChar::Center is used to fix for the Maddah:
	    // Where it should be considered as Dual.
            return  ( (str[index].joining() == QChar::Dual)  ||
                    (str[index].joining() == QChar::Right)   ||
                    (str[index].joining() == QChar::Center)  );
        } else {
            if ( (index + 1) < str.length() ) {
                return check_left(str, index+1);
            }
        }
    }

    return FALSE;
}


// This function is used by format()
// This function caters for Non-spacing marks by looking for
// the previous non non-spacing mark character and check its connectivity.
static inline bool check_right(QString & str, int index) {
    if (index > 0) {
        index--;
        if(  str[index].category() != QChar::Mark_NonSpacing  ) {
	    // the QChar::Center is used to fix for the Maddah:
	    // Where it should be considered as Dual.
            return (str[index].joining() == QChar::Dual) || (str[index].joining() == QChar::Center);
        } else {
            if(index > 0 ) {
                return check_right(str, index);
            }
        }
    }

    return FALSE;
}





// this function is just used in QString::compose()
static inline bool format(QChar::Decomposition tag, QString & str,
			  int index, int len)
{
    bool left = FALSE, right = FALSE;

    // our ligature is connectable from left :
    // If its last character is joinable from left
    // And the character left to it it joinable from right
    left = ( str[(int)(index+len-1)].joining() == QChar::Dual ) && check_left(str, index+len) ;

    // our ligature is connectable from right :
    // If its first character is joinable from right
    // And the character right to it it joinable from left
    right = ( str[index].joining() == QChar::Dual || str[index].joining() == QChar::Right ) && check_right(str, index);


// Old code commented
//    left = ((l < str.length()) &&
//	    ((str[(int)l].joining() == QChar::Dual) ||
//	     (str[(int)l].joining() == QChar::Right)));
//    if (r > 0) {
//	r--;
//	//printf("joining(right) = %d\n", str[(int)r].joining());
//	right = (str[(int)r].joining() == QChar::Dual);
//    }


    switch (tag) {
    case QChar::Medial:
	return (left & right);
    case QChar::Initial:
	return (left && !right);
    case QChar::Final:
	return (right);// && !left);
    case QChar::Isolated:
    default:
	return (!right && !left);
    }
} // format()