View | Details | Raw Unified | Return to issue 60594
Collapse All | Expand All

(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/inc/scriptinfo.hxx (-4 / +19 lines)
Lines 107-112 private: Link Here
107
    SvXub_StrLens aDirChg;
107
    SvXub_StrLens aDirChg;
108
    SvBytes aDirType;
108
    SvBytes aDirType;
109
    SvXub_StrLens aKashida;
109
    SvXub_StrLens aKashida;
110
	SvXub_StrLens aKashidaInvalid;
110
    SvXub_StrLens aCompChg;
111
    SvXub_StrLens aCompChg;
111
    SvXub_StrLens aCompLen;
112
    SvXub_StrLens aCompLen;
112
    SvXub_StrLens aHiddenChg;
113
    SvXub_StrLens aHiddenChg;
Lines 116-121 private: Link Here
116
117
117
    void UpdateBidiInfo( const String& rTxt );
118
    void UpdateBidiInfo( const String& rTxt );
118
119
120
	sal_Bool IsKashidaValid ( xub_StrLen nKashPos ) const;
121
	void MarkKashidaInvalid ( xub_StrLen nKashPos );
122
	void ClearKashidaInvalid ( xub_StrLen nKashPos );
123
119
public:
124
public:
120
    enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE };
125
    enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE };
121
126
Lines 255-261 public: Link Here
255
                The printers kerning array. Optional.
260
                The printers kerning array. Optional.
256
    @param  pScrArray
261
    @param  pScrArray
257
                The screen kerning array. Optional.
262
                The screen kerning array. Optional.
258
    @param  nIdx
263
    @param  nStt
259
                Start referring to the paragraph.
264
                Start referring to the paragraph.
260
    @param  nLen
265
    @param  nLen
261
                The number of characters to be considered.
266
                The number of characters to be considered.
Lines 263-271 public: Link Here
263
                The value which has to be added to a kashida opportunity.
268
                The value which has to be added to a kashida opportunity.
264
    @return The number of kashida opportunities in the given range
269
    @return The number of kashida opportunities in the given range
265
*/
270
*/
266
    USHORT KashidaJustify( sal_Int32* pKernArray ,sal_Int32* pScrArray,
271
    USHORT KashidaJustify( sal_Int32* pKernArray, sal_Int32* pScrArray, 
267
                           xub_StrLen nIdx, xub_StrLen nLen,
272
	                       xub_StrLen nStt, xub_StrLen nLen, 
268
                           long nSpaceAdd = 0 ) const;
273
                           long nSpaceAdd = 0) const;
274
275
/** Marks a kashida as invalid for the given text range.
276
	returns true if a kashida was marked invalid
277
*/
278
	bool MarkKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen );
279
	
280
/** Clears array of kashidas marked as invalid
281
*/
282
	void ClearKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen );
283
269
284
270
/** Checks if language is one of the 16 Arabic languages
285
/** Checks if language is one of the 16 Arabic languages
271
286
(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/text/frmform.cxx (-1 / +1 lines)
Lines 2208-2214 sal_Bool SwTxtFrm::FormatQuick( bool bFo Link Here
2208
    {
2208
    {
2209
        //DBG_LOOP; shadows declaration above.
2209
        //DBG_LOOP; shadows declaration above.
2210
		//resolved into:
2210
		//resolved into:
2211
#if OSL_DEBUG_LEVEL > 1
2211
#ifndef PRODUCT
2212
		DbgLoop aDbgLoop2( (const void*) this );
2212
		DbgLoop aDbgLoop2( (const void*) this );
2213
#endif
2213
#endif
2214
		nStart = aLine.FormatLine( nStart );
2214
		nStart = aLine.FormatLine( nStart );
(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/text/frmpaint.cxx (-1 / +1 lines)
Lines 789-795 void SwTxtFrm::Paint( const SwRect &rRec Link Here
789
			{
789
			{
790
				//DBG_LOOP; shadows declaration above.
790
				//DBG_LOOP; shadows declaration above.
791
				//resolved into:
791
				//resolved into:
792
#if  OSL_DEBUG_LEVEL > 1
792
#ifndef PRODUCT
793
				DbgLoop aDbgLoop2( (const void*) this );
793
				DbgLoop aDbgLoop2( (const void*) this );
794
#endif
794
#endif
795
				aLine.DrawTextLine( rRect, aClip, IsUndersized() );
795
				aLine.DrawTextLine( rRect, aClip, IsUndersized() );
(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/text/itradj.cxx (-2 / +65 lines)
Lines 54-59 Link Here
54
#include <portab.hxx>
54
#include <portab.hxx>
55
#endif
55
#endif
56
56
57
#include <vcl/outdev.hxx>
58
57
#define MIN_TAB_WIDTH 60
59
#define MIN_TAB_WIDTH 60
58
60
59
/*************************************************************************
61
/*************************************************************************
Lines 154-159 void SwTxtAdjuster::CalcNewBlock( SwLine Link Here
154
	xub_StrLen nCharCnt = 0;
156
	xub_StrLen nCharCnt = 0;
155
	MSHORT nSpaceIdx = 0;
157
	MSHORT nSpaceIdx = 0;
156
158
159
	SwScriptInfo& rSI = GetInfo().GetParaPortion()->GetScriptInfo();
160
	SwTxtSizeInfo aInf ( GetTxtFrm() );
161
	SwTxtIter aItr ( GetTxtFrm(), &aInf );
162
163
	if ( rSI.CountKashida() )
164
	{
165
		while (aItr.GetCurr() != pCurrent && aItr.GetNext())
166
			aItr.Next();
167
		rSI.ClearKashidaInvalid ( aItr.GetStart(), aItr.GetLength() );
168
	}
169
157
	// Nicht vergessen:
170
	// Nicht vergessen:
158
    // CalcRightMargin() setzt pCurrent->Width() auf die Zeilenbreite !
171
    // CalcRightMargin() setzt pCurrent->Width() auf die Zeilenbreite !
159
    CalcRightMargin( pCurrent, nReal );
172
    CalcRightMargin( pCurrent, nReal );
Lines 195-201 void SwTxtAdjuster::CalcNewBlock( SwLine Link Here
195
			else if( pMulti->IsDouble() )
208
			else if( pMulti->IsDouble() )
196
				nGluePortion = nGluePortion + ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt();
209
				nGluePortion = nGluePortion + ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt();
197
            else if ( pMulti->IsBidi() )
210
            else if ( pMulti->IsBidi() )
198
                nGluePortion = nGluePortion + ((SwBidiPortion*)pMulti)->GetSpaceCnt();
211
                nGluePortion = nGluePortion + ((SwBidiPortion*)pMulti)->GetSpaceCnt( GetInfo() );
199
        }
212
        }
200
213
201
		if( pPos->InGlueGrp() )
214
		if( pPos->InGlueGrp() )
Lines 210-216 void SwTxtAdjuster::CalcNewBlock( SwLine Link Here
210
223
211
				if( nGluePortion )
224
				if( nGluePortion )
212
				{
225
				{
213
                    const long nSpaceAdd = nGluePortionWidth / nGluePortion;
226
                    long nSpaceAdd = nGluePortionWidth / nGluePortion;
227
					
228
					// validate or recalculate for Kashida justification
229
					if ( rSI.CountKashida() )
230
					{	
231
						xub_StrLen nIdx = aItr.GetStart();
232
						xub_StrLen nEnd = aItr.GetEnd();
233
						
234
235
						// Note on calling KashidaJustify():
236
						// Kashida positions may be marked as invalid. Therefore KashidaJustify may return the clean
237
						// total number of kashida positions, or the number of kashida positions after some positions
238
						// have been dropped.
239
						// Here we want the clean total, which is OK: We have called ClearKashidaInvalid() before.
240
						xub_StrLen nKashidas = rSI.KashidaJustify ( 0, 0, aItr.GetStart(), aItr.GetLength(), 0 );
241
242
						bool bAddSpaceChanged;
243
						while ( nKashidas ) 
244
						{
245
							bAddSpaceChanged = false;
246
							nIdx = aItr.GetStart();
247
							aItr.SeekAndChgAttrIter( nIdx, aInf.GetOut() );
248
249
							while ( nIdx < nEnd )
250
							{
251
								long nFontMinKashida = aInf.GetOut()->GetMinKashida();
252
								if ( nFontMinKashida )
253
								{
254
									while ( nKashidas && nGluePortion > 1 && 
255
											nSpaceAdd / SPACING_PRECISION_FACTOR < nFontMinKashida )
256
									{
257
										if ( rSI.MarkKashidaInvalid(aItr.GetStart(), aItr.GetLength()) )
258
										{
259
											--nGluePortion;
260
											--nKashidas;
261
											nSpaceAdd = nGluePortionWidth / nGluePortion;
262
										    bAddSpaceChanged = true;
263
										}
264
									}
265
								}
266
								if ( bAddSpaceChanged ) 
267
									break; // start all over again
268
								nIdx = aItr.GetNextAttr();
269
								if ( nIdx != STRING_LEN )
270
										aItr.SeekAndChgAttrIter( nIdx, aInf.GetOut() );
271
							}
272
							if ( !bAddSpaceChanged ) 
273
								break; // everything was OK
274
						}
275
					}
276
214
                    pCurrent->SetLLSpaceAdd( nSpaceAdd , nSpaceIdx );
277
                    pCurrent->SetLLSpaceAdd( nSpaceAdd , nSpaceIdx );
215
                    pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() );
278
                    pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() );
216
				}
279
				}
(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/text/porlay.cxx (-118 / +415 lines)
Lines 113-118 using namespace i18n::ScriptType; Link Here
113
//#ifdef BIDI
113
//#ifdef BIDI
114
#include <unicode/ubidi.h>
114
#include <unicode/ubidi.h>
115
115
116
sal_Bool isAlefChar ( xub_Unicode cCh )
117
{
118
	return ( cCh == 0x622 || cCh == 0x623 || cCh == 0x625 || cCh == 0x627 || 
119
			cCh == 0x622 || cCh == 0x671 || cCh == 0x672 || cCh == 0x673 || cCh == 0x675 );
120
}
121
122
sal_Bool isWawChar ( xub_Unicode cCh )
123
{
124
	return ( cCh == 0x624 || cCh == 0x648 || cCh == 0x676 || cCh == 0x677 || 
125
			( cCh >= 0x6C4 &&  cCh <= 0x6CB ) || cCh == 0x6CF );
126
}
127
128
sal_Bool isDalChar ( xub_Unicode cCh )
129
{
130
	return ( cCh == 0x62F || cCh == 0x630 || cCh == 0x688 || cCh == 0x689 || cCh == 0x690 );
131
}
132
133
sal_Bool isRehChar ( xub_Unicode cCh )
134
{
135
	return ( cCh == 0x631 || cCh == 0x632 || ( cCh >= 0x691 && cCh <= 0x699 ));
136
}
137
138
sal_Bool isTehMarbutaChar ( xub_Unicode cCh )
139
{
140
	return ( cCh == 0x629 || cCh == 0x6C0 );
141
}
142
143
sal_Bool isBaaChar ( xub_Unicode cCh )
144
{
145
	return ( cCh == 0x628 || cCh == 0x62A || cCh == 0x62B || cCh == 0x679 || cCh == 0x680 );
146
}
147
148
sal_Bool isYehChar ( xub_Unicode cCh )
149
{
150
	return ( cCh == 0x626 || cCh == 0x649 || cCh == 0x64A || cCh == 0x678 || cCh == 0x6CC || 
151
		cCh == 0x6CE || cCh == 0x6D0 || cCh == 0x6D1 );
152
}
153
154
sal_Bool isSeenOrSadChar ( xub_Unicode cCh )
155
{
156
	return ( ( cCh >= 0x633 && cCh <= 0x636 ) || ( cCh >= 0x69A && cCh <= 0x69E ) 
157
			|| cCh == 0x6FA || cCh == 0x6FB );
158
}
159
160
sal_Bool isHahChar ( xub_Unicode cCh )
161
{
162
	return ( ( cCh >= 0x62C && cCh <= 0x62E ) || ( cCh >= 0x681 && cCh <= 0x687 ) 
163
			|| cCh == 0x6BF );
164
}
165
166
sal_Bool isTahChar ( xub_Unicode cCh )
167
{
168
	return ( cCh == 0x637 || cCh == 0x638 || cCh == 0x69F );
169
}
170
171
sal_Bool isAinChar ( xub_Unicode cCh )
172
{
173
	return ( cCh == 0x639 || cCh == 0x63A || cCh == 0x6A0 || cCh == 0x6FC );
174
}
175
176
sal_Bool isKafChar ( xub_Unicode cCh )
177
{
178
	return ( cCh == 0x643 || ( cCh >= 0x6AC && cCh <= 0x6AE ) );
179
}
180
181
sal_Bool isLamChar ( xub_Unicode cCh )
182
{
183
	return ( cCh == 0x644 || ( cCh >= 0x6B5 && cCh <= 0x6B8 ) );
184
}
185
186
sal_Bool isGafChar ( xub_Unicode cCh )
187
{
188
	return ( cCh == 0x6A9 || cCh == 0x6AB ||( cCh >= 0x6AF && cCh <= 0x6B4 ) );
189
}
190
191
sal_Bool isQafChar ( xub_Unicode cCh )
192
{
193
	return ( cCh == 0x642 || cCh == 0x6A7 || cCh == 0x6A8  );
194
}
195
196
sal_Bool isFeChar ( xub_Unicode cCh )
197
{
198
	return ( cCh == 0x641 || ( cCh >= 0x6A1 && cCh <= 0x6A6 ) );
199
}
200
201
sal_Bool isTransparentChar ( xub_Unicode cCh )
202
{
203
	return ( ( cCh >= 0x610 && cCh <= 0x61A ) ||
204
			 ( cCh >= 0x64B && cCh <= 0x65E ) ||
205
			 ( cCh == 0x670 ) ||
206
			 ( cCh >= 0x6D6 && cCh <= 0x6DC ) ||
207
			 ( cCh >= 0x6DF && cCh <= 0x6E4 ) ||
208
			 ( cCh >= 0x6E7 && cCh <= 0x6E8 ) ||
209
			 ( cCh >= 0x6EA && cCh <= 0x6ED ));
210
211
			
212
}
213
116
/*************************************************************************
214
/*************************************************************************
117
 *                 lcl_IsLigature
215
 *                 lcl_IsLigature
118
 *
216
 *
Lines 127-132 sal_Bool lcl_IsLigature( xub_Unicode cCh Link Here
127
           ( 0x628 == cCh && 0x631 == cNextCh );
225
           ( 0x628 == cCh && 0x631 == cNextCh );
128
}
226
}
129
227
228
229
130
/*************************************************************************
230
/*************************************************************************
131
 *                 lcl_ConnectToPrev
231
 *                 lcl_ConnectToPrev
132
 *
232
 *
Lines 142-154 sal_Bool lcl_ConnectToPrev( xub_Unicode Link Here
142
    sal_Bool bRet = 0x628 == cPrevCh ||
242
    sal_Bool bRet = 0x628 == cPrevCh ||
143
                    ( 0x62A <= cPrevCh && cPrevCh <= 0x62E ) ||
243
                    ( 0x62A <= cPrevCh && cPrevCh <= 0x62E ) ||
144
                    ( 0x633 <= cPrevCh && cPrevCh <= 0x643 ) ||
244
                    ( 0x633 <= cPrevCh && cPrevCh <= 0x643 ) ||
245
					0x644 == cPrevCh || // Lam does connect !!!
145
                    ( 0x645 <= cPrevCh && cPrevCh <= 0x647 ) ||
246
                    ( 0x645 <= cPrevCh && cPrevCh <= 0x647 ) ||
247
					0x649 == cPrevCh || // Alef Maksura does connect !!!
146
                    0x64A == cPrevCh ||
248
                    0x64A == cPrevCh ||
147
                    ( 0x678 <= cPrevCh && cPrevCh <= 0x687 ) ||
249
                    ( 0x678 <= cPrevCh && cPrevCh <= 0x687 ) ||
148
                    ( 0x69A <= cPrevCh && cPrevCh <= 0x6B4 ) ||
250
                    ( 0x69A <= cPrevCh && cPrevCh <= 0x6B4 ) ||
149
                    ( 0x6B9 <= cPrevCh && cPrevCh <= 0x6C0 ) ||
251
                    ( 0x6B9 <= cPrevCh && cPrevCh <= 0x6C0 ) ||
150
                    ( 0x6C3 <= cPrevCh && cPrevCh <= 0x6D3 );
252
                    ( 0x6C3 <= cPrevCh && cPrevCh <= 0x6D3 );
151
253
254
152
    // check for ligatures cPrevChar + cChar
255
    // check for ligatures cPrevChar + cChar
153
    if ( bRet )
256
    if ( bRet )
154
        bRet = ! lcl_IsLigature( cPrevCh, cCh );
257
        bRet = ! lcl_IsLigature( cPrevCh, cCh );
Lines 713-718 BYTE SwScriptInfo::WhichFont( xub_StrLen Link Here
713
    return SW_LATIN;
816
    return SW_LATIN;
714
}
817
}
715
818
819
716
/*************************************************************************
820
/*************************************************************************
717
 *						SwScriptInfo::InitScriptInfo()
821
 *						SwScriptInfo::InitScriptInfo()
718
 *
822
 *
Lines 881-887 void SwScriptInfo::InitScriptInfo( const Link Here
881
985
882
    // remove invalid entries from kashida array
986
    // remove invalid entries from kashida array
883
    aKashida.Remove( nCntKash, aKashida.Count() - nCntKash );
987
    aKashida.Remove( nCntKash, aKashida.Count() - nCntKash );
884
988
	
885
    //
989
    //
886
    // TAKE CARE OF WEAK CHARACTERS: WE MUST FIND AN APPROPRIATE
990
    // TAKE CARE OF WEAK CHARACTERS: WE MUST FIND AN APPROPRIATE
887
    // SCRIPT FOR WEAK CHARACTERS AT THE BEGINNING OF A PARAGRAPH
991
    // SCRIPT FOR WEAK CHARACTERS AT THE BEGINNING OF A PARAGRAPH
Lines 1025-1117 void SwScriptInfo::InitScriptInfo( const Link Here
1025
                xub_StrLen nKashidaPos = STRING_LEN;
1129
                xub_StrLen nKashidaPos = STRING_LEN;
1026
                xub_Unicode cCh;
1130
                xub_Unicode cCh;
1027
                xub_Unicode cPrevCh = 0;
1131
                xub_Unicode cPrevCh = 0;
1028
1132
				USHORT nPriorityLevel = 7; // 0..6 = level found
1029
                while ( nIdx < rWord.Len() )
1133
										   // 7 not found	
1030
                {
1134
				while (nIdx < rWord.Len())
1031
                    cCh = rWord.GetChar( nIdx );
1135
				{
1032
1136
					cCh = rWord.GetChar( nIdx );
1033
                    // 1. Priority:
1137
					// 1. Priority:
1034
                    // after user inserted kashida
1138
					// after user inserted kashida
1035
                    if ( 0x640 == cCh )
1139
                    if ( 0x640 == cCh )
1036
                    {
1140
					{
1037
                        nKashidaPos = aScanner.GetBegin() + nIdx;
1141
						nKashidaPos = aScanner.GetBegin() + nIdx;
1038
                        break;
1142
						nPriorityLevel = 0;
1039
                    }
1143
					}
1040
1144
				
1041
                    // 2. Priority:
1145
					// 2. Priority:
1042
                    // after a Seen or Sad
1146
					// after a Seen or Sad
1043
                    if ( nIdx + 1 < rWord.Len() &&
1147
					if (nPriorityLevel >= 1 && nIdx < rWord.Len() - 1)
1044
                         ( 0x633 == cCh || 0x635 == cCh ) )
1148
					{
1045
                    {
1149
						if ( isSeenOrSadChar ( cCh ) )
1046
                        nKashidaPos = aScanner.GetBegin() + nIdx;
1150
						{
1047
                        break;
1151
							nKashidaPos  = aScanner.GetBegin() + nIdx;
1048
                    }
1152
							nPriorityLevel = 1;
1049
1153
						}
1050
                    // 3. Priority:
1154
					}
1051
                    // before final form of Teh Marbuta, Hah, Dal
1155
					// 3. Priority:
1052
                    // 4. Priority:
1156
					// before final form of Teh Marbuta, Hah, Dal
1053
                    // before final form of Alef, Lam or Kaf
1157
					if ( nPriorityLevel >= 2 && nIdx > 0 )
1054
                    if ( nIdx && nIdx + 1 == rWord.Len() &&
1158
					{
1055
                         ( 0x629 == cCh || 0x62D == cCh || 0x62F == cCh ||
1159
						if ( isTehMarbutaChar ( cCh ) || // Teh Marbuta (right joining)
1056
                           0x627 == cCh || 0x644 == cCh || 0x643 == cCh ) )
1160
							 isDalChar ( cCh ) ||		 // Dal	(right joining) final form may appear in the middle of word
1057
                    {
1161
							 ( isHahChar ( cCh ) && nIdx == rWord.Len() - 1))  // Hah (dual joining) only at end of word
1058
                        ASSERT( 0 != cPrevCh, "No previous character" )
1162
						{
1059
1163
							
1060
                        // check if character is connectable to previous character,
1164
							ASSERT( 0 != cPrevCh, "No previous character" )
1061
                        if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1165
							// check if character is connectable to previous character,
1062
                        {
1166
							if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1063
                            nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1167
							{
1064
                            break;
1168
								nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1065
                        }
1169
								nPriorityLevel = 2;
1066
                    }
1170
							}
1067
1171
						}
1068
                    // 5. Priority:
1172
					}
1069
                    // before media Bah
1070
                    if ( nIdx && nIdx + 1 < rWord.Len() && 0x628 == cCh )
1071
                    {
1072
                        ASSERT( 0 != cPrevCh, "No previous character" )
1073
1074
                        // check if next character is Reh, Yeh or Alef Maksura
1075
                        xub_Unicode cNextCh = rWord.GetChar( nIdx + 1 );
1076
1173
1077
                        if ( 0x631 == cNextCh || 0x64A == cNextCh ||
1174
					// 4. Priority:
1078
                             0x649 == cNextCh )
1175
					// before final form of Alef, Lam or Kaf
1079
                        {
1176
					if ( nPriorityLevel >= 3 && nIdx > 0 )
1080
                            // check if character is connectable to previous character,
1177
					{
1081
                            if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1178
						if ( isAlefChar ( cCh ) ||   // Alef (right joining) final form may appear in the middle of word
1082
                                nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1179
							 (( isLamChar ( cCh ) || // Lam	
1083
                        }
1180
							  isKafChar ( cCh )   || // Kaf (both dual joining)
1181
							  isGafChar ( cCh ) )
1182
							  && nIdx == rWord.Len() - 1))  // only at end of word
1183
						{
1184
							ASSERT( 0 != cPrevCh, "No previous character" )
1185
							// check if character is connectable to previous character,
1186
							if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1187
							{
1188
								nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1189
								nPriorityLevel = 3;
1190
							}
1191
						}
1192
					}
1193
                    
1194
					// 5. Priority:
1195
					// before media Bah
1196
				
1197
					if ( nPriorityLevel >= 4 && nIdx > 0 && nIdx < rWord.Len() - 1 )
1198
					{
1199
						if ( isBaaChar ( cCh )) // Bah
1200
						{
1201
							// check if next character is Reh, Yeh or Alef Maksura
1202
							xub_Unicode cNextCh = rWord.GetChar( nIdx + 1 );
1203
							if ( isRehChar ( cNextCh ) || isYehChar ( cNextCh ))
1204
							{
1205
								ASSERT( 0 != cPrevCh, "No previous character" )
1206
								// check if character is connectable to previous character,
1207
								if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1208
								{
1209
									nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1210
									nPriorityLevel = 4;
1211
								}
1212
							}
1213
						}
1084
                    }
1214
                    }
1085
1215
1086
                    // 6. Priority:
1216
					// 6. Priority:
1087
                    // other connecting possibilities
1217
					// before the final form of Waw, Ain, Qaf and Fa
1088
                    if ( nIdx && nIdx + 1 == rWord.Len() &&
1218
				
1089
                         0x60C <= cCh && 0x6FE >= cCh )
1219
					if ( nPriorityLevel >= 5 && nIdx > 0 )
1090
                    {
1220
					{
1091
                        ASSERT( 0 != cPrevCh, "No previous character" )
1221
						if ( isWawChar ( cCh )   ||	// Wav (right joining) 
1092
1222
													// final form may appear in the middle of word
1093
                        // check if character is connectable to previous character,
1223
							 (( isAinChar ( cCh ) ||  // Ain (dual joining)	
1094
                        if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1224
							    isQafChar ( cCh ) ||  // Qaf (dual joining)
1095
                        {
1225
							    isFeChar  ( cCh ) )   // Feh (dual joining)
1096
                            // only choose this position if we did not find
1226
							    && nIdx == rWord.Len() - 1))  // only at end of word
1097
                            // a better one:
1227
						{
1098
                            if ( STRING_LEN == nKashidaPos )
1228
							ASSERT( 0 != cPrevCh, "No previous character" )
1099
                                nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1229
							// check if character is connectable to previous character,
1100
                            break;
1230
							if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1101
                        }
1231
							{
1102
                    }
1232
								nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1233
								nPriorityLevel = 5;
1234
							}
1235
						}
1236
					}
1237
				
1238
					// other connecting possibilities
1239
					if ( nPriorityLevel >= 6 && nIdx > 0 )
1240
					{
1241
						// remaining right joiners
1242
						// Reh, Zain, Thal, 
1243
						if ( isRehChar ( cCh ) ||	// Reh Zain (right joining)
1244
													// final form may appear in the middle of word
1245
							 ( 0x60C <= cCh && 0x6FE >= cCh // all others
1246
							  && nIdx == rWord.Len() - 1))   // only at end of word
1247
						{
1248
							ASSERT( 0 != cPrevCh, "No previous character" )
1249
							// check if character is connectable to previous character,
1250
							if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
1251
							{
1252
								nKashidaPos = aScanner.GetBegin() + nIdx - 1;
1253
								nPriorityLevel = 6;
1254
							}
1255
						}
1256
					}
1103
1257
1104
                    // Do not consider Fathatan, Dammatan, Kasratan, Fatha,
1258
					// Do not consider Fathatan, Dammatan, Kasratan, Fatha,
1105
                    // Damma, Kasra, Shadda and Sukun when checking if
1259
                    // Damma, Kasra, Shadda and Sukun when checking if
1106
                    // a character can be connected to previous character.
1260
                    // a character can be connected to previous character.
1107
                    if ( cCh < 0x64B || cCh > 0x652 )
1261
                    if ( !isTransparentChar ( cCh) )
1108
                        cPrevCh = cCh;
1262
                        cPrevCh = cCh;
1109
1263
1110
                    ++nIdx;
1264
					++nIdx;
1111
                } // end of current word
1265
				} // end of current word
1112
1266
1113
                if ( STRING_LEN != nKashidaPos )
1267
                if ( STRING_LEN != nKashidaPos )
1114
                    aKashida.Insert( nKashidaPos, nCntKash++ );
1268
				{
1269
                    aKashida.Insert( nKashidaPos, nCntKash++ ); 
1270
				}
1115
            } // end of kashida search
1271
            } // end of kashida search
1116
        }
1272
        }
1117
1273
Lines 1702-1714 long SwScriptInfo::Compress( sal_Int32* Link Here
1702
 *                      SwScriptInfo::KashidaJustify()
1858
 *                      SwScriptInfo::KashidaJustify()
1703
 *************************************************************************/
1859
 *************************************************************************/
1704
1860
1705
USHORT SwScriptInfo::KashidaJustify( sal_Int32* pKernArray, sal_Int32* pScrArray,
1861
// Note on calling KashidaJustify():
1706
                                     xub_StrLen nStt, xub_StrLen nLen,
1862
// Kashida positions may be marked as invalid. Therefore KashidaJustify may return the clean
1707
                                     long nSpaceAdd ) const
1863
// total number of kashida positions, or the number of kashida positions after some positions
1864
// have been dropped, depending on the state of the aKashidaInvalid array.
1865
1866
USHORT SwScriptInfo::KashidaJustify( sal_Int32* pKernArray,
1867
                               sal_Int32* pScrArray, 
1868
							   xub_StrLen nStt,
1869
                               xub_StrLen nLen, 
1870
                               long nSpaceAdd ) const
1708
{
1871
{
1709
    ASSERT( nLen, "Kashida justification without text?!" )
1872
    ASSERT( nLen, "Kashida justification without text?!" )
1710
1873
1711
    // evaluate kashida informatin in collected in SwScriptInfo
1874
    // evaluate kashida information in collected in SwScriptInfo
1712
1875
1713
    USHORT nCntKash = 0;
1876
    USHORT nCntKash = 0;
1714
    while( nCntKash < CountKashida() )
1877
    while( nCntKash < CountKashida() )
Lines 1721-1770 USHORT SwScriptInfo::KashidaJustify( sal Link Here
1721
1884
1722
    const xub_StrLen nEnd = nStt + nLen;
1885
    const xub_StrLen nEnd = nStt + nLen;
1723
1886
1724
    if ( ! pKernArray )
1887
    
1888
    USHORT nCntKashEnd = nCntKash;
1889
    while ( nCntKashEnd < CountKashida() )
1725
    {
1890
    {
1726
        USHORT nCntKashEnd = nCntKash;
1891
		if ( nEnd <= GetKashida( nCntKashEnd ) )
1727
        while ( nCntKashEnd < CountKashida() )
1892
            break;
1728
        {
1893
        else
1729
            if ( nEnd <= GetKashida( nCntKashEnd ) )
1894
            nCntKashEnd++;
1730
                break;
1731
            else
1732
                nCntKashEnd++;
1733
        }
1734
1735
        return nCntKashEnd - nCntKash;
1736
    }
1895
    }
1896
	
1897
	USHORT nActualKashCount = nCntKashEnd - nCntKash;
1898
	for ( USHORT i = nCntKash; i < nCntKashEnd; ++i )
1899
	{
1900
		if ( nActualKashCount && !IsKashidaValid ( i ) )
1901
			--nActualKashCount;
1902
		
1903
	}
1737
1904
1738
    // do nothing if there is no more kashida
1905
	if ( !pKernArray )
1739
    if ( nCntKash < CountKashida() )
1906
        return nActualKashCount;
1740
    {
1741
        xub_StrLen nKashidaPos = GetKashida( nCntKash );
1742
        xub_StrLen nIdx = nKashidaPos;
1743
        long nKashAdd = nSpaceAdd;
1744
1745
        while ( nIdx < nEnd )
1746
        {
1747
            USHORT nArrayPos = nIdx - nStt;
1748
1749
            // next kashida position
1750
            nIdx = ++nCntKash  < CountKashida() ? GetKashida( nCntKash ) : nEnd;
1751
            if ( nIdx > nEnd )
1752
                nIdx = nEnd;
1753
1907
1754
            const USHORT nArrayEnd = nIdx - nStt;
1908
	// do nothing if there is no more kashida
1909
	if ( nCntKash < CountKashida() )
1910
	{
1911
		while ( ! IsKashidaValid ( nCntKash ) && nCntKash < nCntKashEnd )
1912
			++nCntKash;
1913
		xub_StrLen nKashidaPos = GetKashida( nCntKash );
1914
		xub_StrLen nIdx = nKashidaPos;
1915
		long nKashAdd = nSpaceAdd;
1916
		
1917
		while ( nIdx < nEnd )
1918
		{
1919
			USHORT nArrayPos = nIdx - nStt;
1755
1920
1756
            while ( nArrayPos < nArrayEnd )
1921
			// next kashida position
1757
            {
1922
			++nCntKash;
1758
                pKernArray[ nArrayPos ] += nKashAdd;
1923
			while ( ! IsKashidaValid ( nCntKash ) && nCntKash < nCntKashEnd )
1759
                if ( pScrArray )
1924
				++nCntKash;
1760
                   pScrArray[ nArrayPos ] += nKashAdd;
1925
			nIdx = nCntKash < CountKashida() && IsKashidaValid ( nCntKash ) ? GetKashida( nCntKash ) : nEnd;
1761
                ++nArrayPos;
1926
			if ( nIdx > nEnd )
1762
            }
1927
				nIdx = nEnd;
1763
1928
1764
            nKashAdd += nSpaceAdd;
1929
			const USHORT nArrayEnd = nIdx - nStt;
1765
        }
1766
    }
1767
1930
1931
			while ( nArrayPos < nArrayEnd )
1932
			{
1933
				pKernArray[ nArrayPos ] += nKashAdd;
1934
				if ( pScrArray )
1935
				   pScrArray[ nArrayPos ] += nKashAdd;
1936
				++nArrayPos;
1937
			}
1938
			nKashAdd += nSpaceAdd;
1939
		}
1940
	}
1768
    return 0;
1941
    return 0;
1769
}
1942
}
1770
1943
Lines 1786-1791 sal_Bool SwScriptInfo::IsArabicLanguage( Link Here
1786
}
1959
}
1787
1960
1788
/*************************************************************************
1961
/*************************************************************************
1962
 *                      SwScriptInfo::IsKashidaValid()
1963
 *************************************************************************/
1964
1965
sal_Bool SwScriptInfo::IsKashidaValid ( xub_StrLen nKashPos ) const
1966
{
1967
	for ( xub_StrLen i = 0; i < aKashidaInvalid.Count(); ++i )
1968
	{
1969
		if ( aKashidaInvalid [ i ] == nKashPos )
1970
			return false;
1971
	}
1972
	return true;
1973
}
1974
1975
/*************************************************************************
1976
 *                      SwScriptInfo::ClearKashidaInvalid()
1977
 *************************************************************************/
1978
1979
void SwScriptInfo::ClearKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen )
1980
{
1981
	if ( !aKashidaInvalid.Count() ) 
1982
		return;
1983
	USHORT nCntKash = 0;
1984
    while( nCntKash < CountKashida() )
1985
    {
1986
        if ( nStt <= GetKashida( nCntKash ) )
1987
            break;
1988
        else
1989
            nCntKash++;
1990
    }
1991
1992
    const xub_StrLen nEnd = nStt + nLen;
1993
    
1994
    while ( nCntKash < CountKashida() )
1995
    {
1996
		if ( nEnd <= GetKashida( nCntKash ) )
1997
            break;
1998
        else
1999
		{
2000
			ClearKashidaInvalid ( nCntKash );
2001
            nCntKash++;
2002
		}
2003
    }
2004
}
2005
2006
2007
void SwScriptInfo::ClearKashidaInvalid (  xub_StrLen nKashPos )
2008
{
2009
	for ( xub_StrLen i = 0; i < aKashidaInvalid.Count(); ++i )
2010
	{
2011
		if ( aKashidaInvalid [ i ] == nKashPos )
2012
		{
2013
			aKashidaInvalid.Remove (i, 1);
2014
			return;
2015
		}
2016
	}
2017
}
2018
2019
/*************************************************************************
2020
 *                      SwScriptInfo::MarkKashidaInvalid()
2021
 * 
2022
 *************************************************************************/
2023
2024
bool SwScriptInfo::MarkKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen )
2025
{
2026
    USHORT nCntKash = 0;
2027
    while( nCntKash < CountKashida() )
2028
    {
2029
        if ( nStt <= GetKashida( nCntKash ) )
2030
            break;
2031
        else
2032
            nCntKash++;
2033
    }
2034
2035
    const xub_StrLen nEnd = nStt + nLen;
2036
    
2037
    while ( nCntKash < CountKashida() )
2038
    {
2039
		if ( nEnd <= GetKashida( nCntKash ) )
2040
            break;
2041
        else
2042
		{
2043
			if ( IsKashidaValid ( nCntKash ) )
2044
			{
2045
				MarkKashidaInvalid ( nCntKash );
2046
				return true;
2047
			}
2048
            nCntKash++;
2049
		}
2050
    }
2051
	return false;
2052
}
2053
	
2054
void SwScriptInfo::MarkKashidaInvalid ( xub_StrLen nKashPos )
2055
{
2056
	aKashidaInvalid.Insert( nKashPos, aKashidaInvalid.Count() );
2057
}
2058
2059
/*
2060
USHORT SwScriptInfo::CountKashidaInRange ( xub_StrLen nStt, xub_StrLen nLen )
2061
{
2062
	USHORT nCntKash = 0;
2063
    while( nCntKash < CountKashida() )
2064
    {
2065
        if ( nStt <= GetKashida( nCntKash ) )
2066
            break;
2067
        else
2068
            nCntKash++;
2069
    }
2070
2071
    const xub_StrLen nEnd = nStt + nLen;
2072
    
2073
    USHORT nCntKashEnd = nCntKash;
2074
    while ( nCntKashEnd < CountKashida() )
2075
    {
2076
		if ( nEnd <= GetKashida( nCntKashEnd ) )
2077
            break;
2078
        else
2079
            nCntKashEnd++;
2080
    }
2081
	return nCntKashEnd - nCntKash;
2082
}
2083
*/
2084
2085
/*************************************************************************
1789
 *                      SwScriptInfo::ThaiJustify()
2086
 *                      SwScriptInfo::ThaiJustify()
1790
 *************************************************************************/
2087
 *************************************************************************/
1791
2088
(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/text/pormulti.cxx (-21 / +25 lines)
Lines 294-302 SwBidiPortion::SwBidiPortion( xub_StrLen Link Here
294
}
294
}
295
295
296
296
297
long SwBidiPortion::CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo & ) const
297
long SwBidiPortion::CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const
298
{
298
{
299
    return HasTabulator() ? 0 : GetSpaceCnt() * nSpaceAdd / SPACING_PRECISION_FACTOR;
299
    return HasTabulator() ? 0 : GetSpaceCnt( rInf ) * nSpaceAdd / SPACING_PRECISION_FACTOR;
300
}
300
}
301
301
302
sal_Bool SwBidiPortion::ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const
302
sal_Bool SwBidiPortion::ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const
Lines 312-317 sal_Bool SwBidiPortion::ChgSpaceAdd( SwL Link Here
312
    return bRet;
312
    return bRet;
313
}
313
}
314
314
315
xub_StrLen SwBidiPortion::GetSpaceCnt( const SwTxtSizeInfo &rInf ) const
316
{
317
	// Calculate number of blanks for justified alignment
318
    SwLinePortion* pPor = GetRoot().GetFirstPortion();
319
    xub_StrLen nTmpStart = rInf.GetIdx();
320
    xub_StrLen nNull = 0;
321
    xub_StrLen nBlanks;
322
323
    for( nBlanks = 0; pPor; pPor = pPor->GetPortion() )
324
    {
325
        if( pPor->InTxtGrp() )
326
            nBlanks = nBlanks + ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nNull );
327
        else if ( pPor->IsMultiPortion() &&
328
                 ((SwMultiPortion*)pPor)->IsBidi() )
329
            nBlanks = nBlanks + ((SwBidiPortion*)pPor)->GetSpaceCnt( rInf );
330
331
        ((SwTxtSizeInfo &)rInf).SetIdx( rInf.GetIdx() + pPor->GetLen() );
332
    }
333
    ((SwTxtSizeInfo &)rInf).SetIdx( nTmpStart );
334
	return nBlanks;
335
}
336
315
/*-----------------01.11.00 14:22-------------------
337
/*-----------------01.11.00 14:22-------------------
316
 * SwDoubleLinePortion::SwDoubleLinePortion(..)
338
 * SwDoubleLinePortion::SwDoubleLinePortion(..)
317
 * This constructor is for the continuation of a doubleline portion
339
 * This constructor is for the continuation of a doubleline portion
Lines 2128-2151 BOOL SwTxtFormatter::BuildMultiPortion( Link Here
2128
	}
2150
	}
2129
    else if ( rMulti.IsBidi() )
2151
    else if ( rMulti.IsBidi() )
2130
    {
2152
    {
2131
        // Calculate number of blanks for justified alignment
2132
        SwLinePortion* pPor = rMulti.GetRoot().GetFirstPortion();
2133
        xub_StrLen nTmpStart = rInf.GetIdx();
2134
        xub_StrLen nNull = 0;
2135
        xub_StrLen nBlanks;
2136
2137
        for( nBlanks = 0; pPor; pPor = pPor->GetPortion() )
2138
        {
2139
            if( pPor->InTxtGrp() )
2140
                nBlanks = nBlanks + ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nNull );
2141
            else if ( pPor->IsMultiPortion() &&
2142
                     ((SwMultiPortion*)pPor)->IsBidi() )
2143
                nBlanks = nBlanks + ((SwBidiPortion*)pPor)->GetSpaceCnt();
2144
2145
            rInf.SetIdx( rInf.GetIdx() + pPor->GetLen() );
2146
        }
2147
        rInf.SetIdx( nTmpStart );
2148
        ((SwBidiPortion&)rMulti).SetSpaceCnt( nBlanks );
2149
2153
2150
        bRet = rMulti.GetLen() < nMultiLen || pNextFirst;
2154
        bRet = rMulti.GetLen() < nMultiLen || pNextFirst;
2151
    }
2155
    }
Lines 2453-2459 SwTxtCursorSave::SwTxtCursorSave( SwTxtC Link Here
2453
            nSpaceCnt = ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt();
2457
            nSpaceCnt = ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt();
2454
        }
2458
        }
2455
        else
2459
        else
2456
            nSpaceCnt = ((SwBidiPortion*)pMulti)->GetSpaceCnt();
2460
            nSpaceCnt = ((SwBidiPortion*)pMulti)->GetSpaceCnt( pTxtCursor->GetInfo() );
2457
2461
2458
		if( nSpaceAdd > 0 && !pMulti->HasTabulator() )
2462
		if( nSpaceAdd > 0 && !pMulti->HasTabulator() )
2459
            pTxtCursor->pCurr->Width( static_cast<USHORT>(nWidth + nSpaceAdd * nSpaceCnt / SPACING_PRECISION_FACTOR ) );
2463
            pTxtCursor->pCurr->Width( static_cast<USHORT>(nWidth + nSpaceAdd * nSpaceCnt / SPACING_PRECISION_FACTOR ) );
(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/text/pormulti.hxx (-4 / +2 lines)
Lines 231-245 public: Link Here
231
class SwBidiPortion : public SwMultiPortion
231
class SwBidiPortion : public SwMultiPortion
232
{
232
{
233
    BYTE nLevel;
233
    BYTE nLevel;
234
    xub_StrLen nBlanks;     // Number of blanks
235
234
236
public:
235
public:
237
    SwBidiPortion( xub_StrLen nEnd, BYTE nLv );
236
    SwBidiPortion( xub_StrLen nEnd, BYTE nLv );
238
237
239
    inline BYTE GetLevel() const { return nLevel; }
238
    inline BYTE GetLevel() const { return nLevel; }
240
    // Set/Get number of blanks for justified alignment
239
    // Get number of blanks for justified alignment
241
    inline void SetSpaceCnt( xub_StrLen nNew ) { nBlanks = nNew; }
240
    xub_StrLen GetSpaceCnt( const SwTxtSizeInfo &rInf ) const; 
242
    inline xub_StrLen GetSpaceCnt() const { return nBlanks; }
243
    // Calculates extra spacing based on number of blanks
241
    // Calculates extra spacing based on number of blanks
244
    virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
242
    virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
245
    // Manipulate the spacing array at pCurr
243
    // Manipulate the spacing array at pCurr
(-)/cygdrive/C/Users/Henner/Downloads/OOSource/OOH680_m12/sw/source/core/txtnode/fntcache.cxx (-2 / +18 lines)
Lines 887-892 static sal_Bool lcl_IsMonoSpaceFont( con Link Here
887
    return nWidth1 == nWidth2;
887
    return nWidth1 == nWidth2;
888
}
888
}
889
889
890
sal_Bool isCharArabic ( xub_Unicode cChar )
891
{
892
	return ( cChar >= 0x0600 && cChar <= 0x06FF );
893
}
894
890
// ER 09.07.95 20:34
895
// ER 09.07.95 20:34
891
// mit -Ox Optimierung stuerzt's unter win95 ab
896
// mit -Ox Optimierung stuerzt's unter win95 ab
892
// JP 12.07.95: unter WNT auch (i386);       Alpha ??
897
// JP 12.07.95: unter WNT auch (i386);       Alpha ??
Lines 1270-1276 void SwFntObj::DrawText( SwDrawTextInfo Link Here
1270
                        if ( pSI && pSI->CountKashida() )
1275
                        if ( pSI && pSI->CountKashida() )
1271
                            pSI->KashidaJustify( pKernArray, 0, rInf.GetIdx(),
1276
                            pSI->KashidaJustify( pKernArray, 0, rInf.GetIdx(),
1272
                                                rInf.GetLen(), nSpaceAdd );
1277
                                                rInf.GetLen(), nSpaceAdd );
1273
1274
                        bSpecialJust = sal_True;
1278
                        bSpecialJust = sal_True;
1275
                        nSpaceAdd = 0;
1279
                        nSpaceAdd = 0;
1276
                    }
1280
                    }
Lines 1426-1437 void SwFntObj::DrawText( SwDrawTextInfo Link Here
1426
        // Modify Printer and ScreenArrays for special justifications
1430
        // Modify Printer and ScreenArrays for special justifications
1427
        //
1431
        //
1428
        long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR;
1432
        long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR;
1433
		bool bNoHalfSpace = false;
1429
1434
1430
        if ( rInf.GetFont() && rInf.GetLen() )
1435
        if ( rInf.GetFont() && rInf.GetLen() )
1431
        {
1436
        {
1432
            const BYTE nActual = rInf.GetFont()->GetActual();
1437
            const BYTE nActual = rInf.GetFont()->GetActual();
1433
            const SwScriptInfo* pSI = rInf.GetScriptInfo();
1438
            const SwScriptInfo* pSI = rInf.GetScriptInfo();
1434
1439
1440
1435
            // Kana Compression
1441
            // Kana Compression
1436
            if ( SW_CJK == nActual && rInf.GetKanaComp() &&
1442
            if ( SW_CJK == nActual && rInf.GetKanaComp() &&
1437
                 pSI && pSI->CountCompChg() &&
1443
                 pSI && pSI->CountCompChg() &&
Lines 1486-1491 void SwFntObj::DrawText( SwDrawTextInfo Link Here
1486
            // Kashida Justification
1492
            // Kashida Justification
1487
            if ( SW_CTL == nActual && nSpaceAdd )
1493
            if ( SW_CTL == nActual && nSpaceAdd )
1488
            {
1494
            {
1495
				// Precaution: This prevents the bad effects of issue 28203, if Arabic characters are used
1496
				// without an Arabic language attribute. 
1497
				// The half spacing makes it impossible to use regular justification of blanks with Arabic characters.
1498
				// But there might be situations, where we would want to support this.
1499
				for ( xub_StrLen i = 0; i < rInf.GetLen(); ++i )
1500
				{
1501
					bNoHalfSpace = isCharArabic ( rInf.GetText().GetChar ( rInf.GetIdx() + i ));
1502
					if ( bNoHalfSpace )
1503
						break;
1504
				}
1489
                if ( SwScriptInfo::IsArabicLanguage( rInf.GetFont()->
1505
                if ( SwScriptInfo::IsArabicLanguage( rInf.GetFont()->
1490
                                                        GetLanguage( SW_CTL ) ) )
1506
                                                        GetLanguage( SW_CTL ) ) )
1491
                {
1507
                {
Lines 1571-1577 void SwFntObj::DrawText( SwDrawTextInfo Link Here
1571
            // vor bzw. hinter den kompletten Zwischenraum gesetzt werden,
1587
            // vor bzw. hinter den kompletten Zwischenraum gesetzt werden,
1572
            // sonst wuerde das Durch-/Unterstreichen Luecken aufweisen.
1588
            // sonst wuerde das Durch-/Unterstreichen Luecken aufweisen.
1573
            long nSpaceSum = 0;
1589
            long nSpaceSum = 0;
1574
            long nHalfSpace = pPrtFont->IsWordLineMode() ? 0 : nSpaceAdd / 2;
1590
            long nHalfSpace = pPrtFont->IsWordLineMode() || bNoHalfSpace ? 0 : nSpaceAdd / 2;
1575
            long nOtherHalf = nSpaceAdd - nHalfSpace;
1591
            long nOtherHalf = nSpaceAdd - nHalfSpace;
1576
            if ( nSpaceAdd && ( cChPrev == CH_BLANK ) )
1592
            if ( nSpaceAdd && ( cChPrev == CH_BLANK ) )
1577
                nSpaceSum = nHalfSpace;
1593
                nSpaceSum = nHalfSpace;

Return to issue 60594