--- winlayout.1.108.206.2.cxx 2008-03-05 13:57:13.567000000 +0000 +++ winlayout.cxx 2008-04-01 09:37:02.036000000 +0000 @@ -1120,6 +1120,9 @@ private: GOFFSET* mpGlyphOffsets; // glyph offsets to the "naive" layout SCRIPT_VISATTR* mpVisualAttrs; // glyph visual attributes mutable int* mpGlyphs2Chars; // map from absolute_glyph_pos to absolute_char_pos + + // font specific info + int mnMinKashidaWidth; // minimal Kashida width allowed by font }; // ----------------------------------------------------------------------- @@ -1685,11 +1688,23 @@ bool UniscribeLayout::LayoutText( ImplLa } } + //ScriptGetFontProperties + + SCRIPT_FONTPROPERTIES aFontProperties; + aFontProperties.cBytes = sizeof (aFontProperties); + mnMinKashidaWidth = 0; + HRESULT nRC = (*pScriptGetFontProperties)( mhDC, &rScriptCache, &aFontProperties ); + if( !nRC ) + { + mnMinKashidaWidth = aFontProperties.iKashidaWidth; + } + + // scale layout metrics if needed if( mfFontScale != 1.0 ) { mnBaseAdv = (int)((double)mnBaseAdv*mfFontScale); - + mnMinKashidaWidth = (int)((double)mnMinKashidaWidth*mfFontScale); for( i = 0; i < mnItemCount; ++i ) mpVisualItems[i].mnXOffset = (int)((double)mpVisualItems[i].mnXOffset*mfFontScale); @@ -2354,7 +2369,7 @@ void UniscribeLayout::ApplyDXArray( cons if( rVisualItem.mpScriptItem->a.fRTL ) { for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i ) - if ( (1U << mpVisualAttrs[i].uJustification) & 0x7F89 ) // any Arabic justification ? + if ( (1U << mpVisualAttrs[i].uJustification) & 0xFF89 ) // any Arabic justification ? { // yes bHasKashida = true; @@ -2363,7 +2378,8 @@ void UniscribeLayout::ApplyDXArray( cons if ( bHasKashida ) for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i ) { - if ( mpVisualAttrs[i].uJustification == SCRIPT_JUSTIFY_NONE ) + // check if we still need this hack after correkction of kashida placing + if ( mpVisualAttrs[i].uJustification == SCRIPT_JUSTIFY_NONE ) // usp decided that justification can't be applied here // but maybe our Kashida algorithm thinks differently. // To avoid trouble (gaps within words, last character of @@ -2397,6 +2413,15 @@ void UniscribeLayout::ApplyDXArray( cons break; } + // to prepare for the next visual item + // update nXOffset to the next items position + // before the mpJustifications[] array gets modified + int nMinGlyphPos, nEndGlyphPos; + if( GetItemSubrange( rVisualItem, nMinGlyphPos, nEndGlyphPos ) ) + { + for( i = nMinGlyphPos; i < nEndGlyphPos; ++i ) + nXOffset += mpJustifications[ i ]; + // TODO: for kashida justification // check the widths which are added to mpJustification // if added width is smaller than iKashidaWidth returned by @@ -2405,13 +2430,37 @@ void UniscribeLayout::ApplyDXArray( cons // Need to think of a way to compensate the change in overall // width. - // to prepare for the next visual item - // update nXOffset to the next items position - // before the mpJustifications[] array gets modified - int nMinGlyphPos, nEndGlyphPos; - if( GetItemSubrange( rVisualItem, nMinGlyphPos, nEndGlyphPos ) ) - for( i = nMinGlyphPos; i < nEndGlyphPos; ++i ) - nXOffset += mpJustifications[ i ]; + if ( bHasKashida && mnMinKashidaWidth ) + { + int nSpaceAdded; + for ( i = nMinGlyphPos; i < nEndGlyphPos; ++i ) + { + nSpaceAdded = mpJustifications[ i ] - mpGlyphAdvances[ i ]; + if ( nSpaceAdded && nSpaceAdded < mnMinKashidaWidth + && ((1U << mpVisualAttrs[i].uJustification) & 0xFF89) ) + { + mpJustifications[ i ] = mpGlyphAdvances[ i ]; // overriding; + for ( int j = i; j >= nMinGlyphPos; --j ) + { + if ( mpVisualAttrs[ j ].uJustification == SCRIPT_JUSTIFY_ARABIC_BLANK ) + { + mpJustifications [ j ] += nSpaceAdded; // padding a blank instead + nSpaceAdded = 0; + break; + } + } + if ( nSpaceAdded ) + { + // no blank found + // right aligning seems more reasonable + rVisualItem.mnXOffset += nSpaceAdded; + } + } + } + } + } + + // right align the justification-adjusted glyphs in their cells for RTL-items if( bManualCellAlign && rVisualItem.mpScriptItem->a.fRTL && !bHasKashida ) @@ -2466,6 +2515,7 @@ void UniscribeLayout::Justify( long nNew nItemWidth = (int)((fStretch - 1.0) * nItemWidth + 0.5); SCRIPT_FONTPROPERTIES aFontProperties; + aFontProperties.cBytes = sizeof (aFontProperties); int nMinKashida = 1; HRESULT nRC = (*pScriptGetFontProperties)( mhDC, &rScriptCache, &aFontProperties ); if( !nRC )