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

(-)vcl_old/inc/vcl/outdev.hxx (+3 lines)
Lines 1017-1022 public: Link Here
1017
1017
1018
    xub_StrLen          HasGlyphs( const Font& rFont, const String& rStr,
1018
    xub_StrLen          HasGlyphs( const Font& rFont, const String& rStr,
1019
                            xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN ) const;
1019
                            xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN ) const;
1020
	
1021
	long				GetMinKashida() const;
1022
	long				GetMinKashida( const Font& rFont ) const;
1020
1023
1021
    USHORT              GetBitCount() const;
1024
    USHORT              GetBitCount() const;
1022
1025
(-)vcl_old/inc/vcl/outfont.hxx (+2 lines)
Lines 315-320 public: // TODO: hide members behind acc Link Here
315
    long                mnDStrikeoutSize;           // Hoehe von doppelter Durchstreichung
315
    long                mnDStrikeoutSize;           // Hoehe von doppelter Durchstreichung
316
    long                mnDStrikeoutOffset1;        // Offset von doppelter Durchstreichung zur Baseline
316
    long                mnDStrikeoutOffset1;        // Offset von doppelter Durchstreichung zur Baseline
317
    long                mnDStrikeoutOffset2;        // Offset von doppelter Durchstreichung zur Baseline
317
    long                mnDStrikeoutOffset2;        // Offset von doppelter Durchstreichung zur Baseline
318
	long				mnMinKashida;				// Minimal width of kashida (Arabic)
319
318
};
320
};
319
321
320
// -----------------
322
// -----------------
(-)vcl_old/source/gdi/outdev3.cxx (+27 lines)
Lines 114-119 using namespace ::vcl; Link Here
114
114
115
// =======================================================================
115
// =======================================================================
116
116
117
118
119
117
//#ifdef USE_NEW_RTL_IMPLEMENTATION
120
//#ifdef USE_NEW_RTL_IMPLEMENTATION
118
121
119
122
Lines 3771-3776 ImplFontMetricData::ImplFontMetricData( Link Here
3771
    mnDStrikeoutSize           = 0;
3774
    mnDStrikeoutSize           = 0;
3772
    mnDStrikeoutOffset1        = 0;
3775
    mnDStrikeoutOffset1        = 0;
3773
    mnDStrikeoutOffset2        = 0;
3776
    mnDStrikeoutOffset2        = 0;
3777
	mnMinKashida			   = 0;	
3774
}
3778
}
3775
3779
3776
// -----------------------------------------------------------------------
3780
// -----------------------------------------------------------------------
Lines 7401-7406 FontMetric OutputDevice::GetFontMetric( Link Here
7401
7405
7402
// -----------------------------------------------------------------------
7406
// -----------------------------------------------------------------------
7403
7407
7408
long OutputDevice::GetMinKashida() const
7409
{
7410
    DBG_TRACE( "OutputDevice::GetMinKashida()" );
7411
    DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
7412
    if( mbNewFont && !ImplNewFont() )
7413
        return 0;
7414
7415
	ImplFontEntry*      pEntry = mpFontEntry;
7416
    ImplFontMetricData* pMetric = &(pEntry->maMetric);
7417
 	return ImplDevicePixelToLogicWidth( pMetric->mnMinKashida );
7418
}
7419
// -----------------------------------------------------------------------
7420
7421
long OutputDevice::GetMinKashida( const Font& rFont ) const
7422
{
7423
	// select font, query Kashida, select original font again
7424
    Font aOldFont = GetFont();
7425
    const_cast<OutputDevice*>(this)->SetFont( rFont );
7426
    long aKashida = GetMinKashida();
7427
    const_cast<OutputDevice*>(this)->SetFont( aOldFont );
7428
    return aKashida;
7429
}
7430
7404
// TODO: best is to get rid of this method completely
7431
// TODO: best is to get rid of this method completely
7405
ULONG OutputDevice::GetKerningPairCount() const
7432
ULONG OutputDevice::GetKerningPairCount() const
7406
{
7433
{
(-)vcl_old/win/inc/salgdi.h (+2 lines)
Lines 78-83 public: Link Here
78
    bool                    IsGlyphApiDisabled() const  { return mbDisableGlyphApi; }
78
    bool                    IsGlyphApiDisabled() const  { return mbDisableGlyphApi; }
79
    bool                    SupportsKorean() const      { return mbHasKoreanRange; }
79
    bool                    SupportsKorean() const      { return mbHasKoreanRange; }
80
    bool                    SupportsCJK() const         { return mbHasCJKSupport; }
80
    bool                    SupportsCJK() const         { return mbHasCJKSupport; }
81
	bool					SupportsArabic() const		{ return mbHasArabicSupport; }
81
    bool                    AliasSymbolsHigh() const    { return mbAliasSymbolsHigh; }
82
    bool                    AliasSymbolsHigh() const    { return mbAliasSymbolsHigh; }
82
    bool                    AliasSymbolsLow() const     { return mbAliasSymbolsLow; }
83
    bool                    AliasSymbolsLow() const     { return mbAliasSymbolsLow; }
83
84
Lines 96-101 private: Link Here
96
    mutable bool                    mbDisableGlyphApi;
97
    mutable bool                    mbDisableGlyphApi;
97
    mutable bool                    mbHasKoreanRange;
98
    mutable bool                    mbHasKoreanRange;
98
    mutable bool                    mbHasCJKSupport;
99
    mutable bool                    mbHasCJKSupport;
100
	mutable bool                    mbHasArabicSupport;
99
    mutable ImplFontCharMap*        mpUnicodeMap;
101
    mutable ImplFontCharMap*        mpUnicodeMap;
100
    mutable const Ucs2SIntMap*      mpEncodingVector;
102
    mutable const Ucs2SIntMap*      mpEncodingVector;
101
103
(-)vcl_old/win/source/gdi/salgdi3.cxx (+64 lines)
Lines 36-41 Link Here
36
#include <tools/svwin.h>
36
#include <tools/svwin.h>
37
#include <rtl/logfile.hxx>
37
#include <rtl/logfile.hxx>
38
#include <rtl/tencinfo.h>
38
#include <rtl/tencinfo.h>
39
#include <osl/module.h>
39
#ifndef _OSL_FILE_HXX
40
#ifndef _OSL_FILE_HXX
40
#include <osl/file.hxx>
41
#include <osl/file.hxx>
41
#endif
42
#endif
Lines 65-70 Link Here
65
#endif
66
#endif
66
#include <rtl/textcvt.h>
67
#include <rtl/textcvt.h>
67
68
69
#include <Usp10.h>
70
68
#ifdef GCP_KERN_HACK
71
#ifdef GCP_KERN_HACK
69
#include <algorithm>
72
#include <algorithm>
70
#endif
73
#endif
Lines 111-116 static bool bImplSalCourierNew = false; Link Here
111
114
112
// =======================================================================
115
// =======================================================================
113
116
117
// -----------------------------------------------------------------------
118
// dynamic loading of usp library
119
// copied from winlayout.cxx
120
121
static oslModule aUspModule = NULL;
122
static bool bUspEnabled = true;
123
124
static HRESULT ((WINAPI *pScriptGetFontProperties)( HDC, SCRIPT_CACHE*, SCRIPT_FONTPROPERTIES* ));
125
static HRESULT ((WINAPI *pScriptFreeCache)( SCRIPT_CACHE* ));
126
127
static bool InitUSP()
128
{
129
	rtl::OUString aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "usp10" ) );
130
    aUspModule = osl_loadModule( aLibraryName.pData, SAL_LOADMODULE_DEFAULT );
131
    if( !aUspModule )
132
        return (bUspEnabled = false);
133
134
135
	rtl::OUString queryFuncName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptGetFontProperties" ) );
136
    pScriptGetFontProperties = (HRESULT (WINAPI*)( HDC,SCRIPT_CACHE*,SCRIPT_FONTPROPERTIES*))
137
        osl_getSymbol( aUspModule, queryFuncName.pData );
138
    bUspEnabled &= (NULL != pScriptGetFontProperties);
139
140
	queryFuncName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptFreeCache" ) );
141
    pScriptFreeCache = (HRESULT (WINAPI*)(SCRIPT_CACHE*))
142
        osl_getSymbol( aUspModule, queryFuncName.pData );
143
    bUspEnabled &= (NULL != pScriptFreeCache);
144
145
    if( !bUspEnabled )
146
    {
147
        osl_unloadModule( aUspModule );
148
        aUspModule = NULL;
149
    }
150
    return bUspEnabled;
151
}
152
153
154
155
156
157
114
// TODO: also support temporary TTC font files
158
// TODO: also support temporary TTC font files
115
typedef std::map< String, ImplDevFontAttributes > FontAttrMap;
159
typedef std::map< String, ImplDevFontAttributes > FontAttrMap;
116
160
Lines 740-745 ImplWinFontData::ImplWinFontData( const Link Here
740
    mbDisableGlyphApi( false ),
784
    mbDisableGlyphApi( false ),
741
    mbHasKoreanRange( false ),
785
    mbHasKoreanRange( false ),
742
    mbHasCJKSupport( false ),
786
    mbHasCJKSupport( false ),
787
	mbHasArabicSupport ( false ),
743
    mbAliasSymbolsLow( false ),
788
    mbAliasSymbolsLow( false ),
744
    mbAliasSymbolsHigh( false ),
789
    mbAliasSymbolsHigh( false ),
745
    mnId( 0 ),
790
    mnId( 0 ),
Lines 870-875 void ImplWinFontData::ReadOs2Table( HDC Link Here
870
        mbHasCJKSupport = (ulUnicodeRange2 & 0x2DF00000);
915
        mbHasCJKSupport = (ulUnicodeRange2 & 0x2DF00000);
871
        mbHasKoreanRange= (ulUnicodeRange1 & 0x10000000)
916
        mbHasKoreanRange= (ulUnicodeRange1 & 0x10000000)
872
                        | (ulUnicodeRange2 & 0x01100000);
917
                        | (ulUnicodeRange2 & 0x01100000);
918
		mbHasArabicSupport = (ulUnicodeRange1 & 0x00002000);
873
    }
919
    }
874
}
920
}
875
921
Lines 1467-1472 void WinSalGraphics::GetFontMetric( Impl Link Here
1467
            if( mpWinFontData[0]->SupportsKorean() )
1513
            if( mpWinFontData[0]->SupportsKorean() )
1468
                pMetric->mnDescent += pMetric->mnExtLeading;
1514
                pMetric->mnDescent += pMetric->mnExtLeading;
1469
    }
1515
    }
1516
1517
	 if( mpWinFontData[0] && mpWinFontData[0]->SupportsArabic() )
1518
	 {
1519
		 if (aUspModule || (bUspEnabled && InitUSP()) )  
1520
		 {
1521
			//ScriptGetFontProperties 
1522
			SCRIPT_FONTPROPERTIES aFontProperties;
1523
			SCRIPT_CACHE aScriptCache = NULL; // should use ScriptCache from ImplWinFontEntry
1524
											  // but how do I get there	
1525
			aFontProperties.cBytes = sizeof (aFontProperties);
1526
			HRESULT nRC = (*pScriptGetFontProperties)( mhDC, &aScriptCache, &aFontProperties );
1527
			if( !nRC )
1528
			{
1529
				pMetric->mnMinKashida = static_cast<int>( mfFontScale * aFontProperties.iKashidaWidth);
1530
			}
1531
			(*pScriptFreeCache)( &aScriptCache );
1532
		 }
1533
	 }
1470
}
1534
}
1471
1535
1472
// -----------------------------------------------------------------------
1536
// -----------------------------------------------------------------------
(-)vcl_old/win/source/gdi/winlayout.cxx (-12 / +86 lines)
Lines 1105-1110 private: Link Here
1105
    GOFFSET*        mpGlyphOffsets;     // glyph offsets to the "naive" layout
1105
    GOFFSET*        mpGlyphOffsets;     // glyph offsets to the "naive" layout
1106
    SCRIPT_VISATTR* mpVisualAttrs;      // glyph visual attributes
1106
    SCRIPT_VISATTR* mpVisualAttrs;      // glyph visual attributes
1107
    mutable int*    mpGlyphs2Chars;     // map from absolute_glyph_pos to absolute_char_pos
1107
    mutable int*    mpGlyphs2Chars;     // map from absolute_glyph_pos to absolute_char_pos
1108
1109
	// font specific info
1110
	int				mnMinKashidaWidth;  // minimal Kashida width allowed by font
1108
};
1111
};
1109
1112
1110
// -----------------------------------------------------------------------
1113
// -----------------------------------------------------------------------
Lines 1670-1680 bool UniscribeLayout::LayoutText( ImplLa Link Here
1670
        }
1673
        }
1671
    }
1674
    }
1672
1675
1676
	//ScriptGetFontProperties 
1677
1678
	SCRIPT_FONTPROPERTIES aFontProperties;
1679
	aFontProperties.cBytes = sizeof (aFontProperties); // don't forget to initialize
1680
    mnMinKashidaWidth = 0;
1681
    HRESULT nRC = (*pScriptGetFontProperties)( mhDC, &rScriptCache, &aFontProperties );
1682
    if( !nRC )
1683
	{
1684
       mnMinKashidaWidth = aFontProperties.iKashidaWidth;
1685
	}
1686
1687
1673
    // scale layout metrics if needed
1688
    // scale layout metrics if needed
1674
    if( mfFontScale != 1.0 )
1689
    if( mfFontScale != 1.0 )
1675
    {
1690
    {
1676
        mnBaseAdv = (int)((double)mnBaseAdv*mfFontScale);
1691
        mnBaseAdv = (int)((double)mnBaseAdv*mfFontScale);
1677
1692
		mnMinKashidaWidth = (int)((double)mnMinKashidaWidth*mfFontScale);
1678
        for( i = 0; i < mnItemCount; ++i )
1693
        for( i = 0; i < mnItemCount; ++i )
1679
            mpVisualItems[i].mnXOffset = (int)((double)mpVisualItems[i].mnXOffset*mfFontScale);
1694
            mpVisualItems[i].mnXOffset = (int)((double)mpVisualItems[i].mnXOffset*mfFontScale);
1680
1695
Lines 2342-2357 void UniscribeLayout::ApplyDXArray( cons Link Here
2342
		if( rVisualItem.mpScriptItem->a.fRTL )
2357
		if( rVisualItem.mpScriptItem->a.fRTL )
2343
        {
2358
        {
2344
			for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
2359
			for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
2345
				if ( (1U << mpVisualAttrs[i].uJustification) & 0x7F89 )  //  any Arabic justification ?
2360
				if ( (1U << mpVisualAttrs[i].uJustification) & 0xFF89 )  //  any Arabic justification ?
2346
				{
2361
				{														 //  the last SCRIPT_JUSTIFY_xxx	
2347
					// yes
2362
					// yes												 //  == 15 (usp 1.6)
2348
					bHasKashida = true;
2363
					bHasKashida = true;
2349
					break;
2364
					break;
2350
				}
2365
				}
2351
			if ( bHasKashida )
2366
			if ( bHasKashida )
2352
				for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
2367
				for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
2353
				{
2368
				{
2354
					if ( mpVisualAttrs[i].uJustification == SCRIPT_JUSTIFY_NONE )
2369
					// check if we still need this hack after correction of kashida placing? 
2370
					// (i87688): apparently yes, we still need it!
2371
				    if ( mpVisualAttrs[i].uJustification == SCRIPT_JUSTIFY_NONE )
2355
						// usp decided that justification can't be applied here
2372
						// usp decided that justification can't be applied here
2356
						// but maybe our Kashida algorithm thinks differently.
2373
						// but maybe our Kashida algorithm thinks differently.
2357
						// To avoid trouble (gaps within words, last character of 
2374
						// To avoid trouble (gaps within words, last character of 
Lines 2385-2390 void UniscribeLayout::ApplyDXArray( cons Link Here
2385
            break;
2402
            break;
2386
        }
2403
        }
2387
2404
2405
        // to prepare for the next visual item
2406
        // update nXOffset to the next items position
2407
        // before the mpJustifications[] array gets modified
2408
        int nMinGlyphPos, nEndGlyphPos;
2409
        if( GetItemSubrange( rVisualItem, nMinGlyphPos, nEndGlyphPos ) )
2410
		{
2411
            for( i = nMinGlyphPos; i < nEndGlyphPos; ++i )
2412
                nXOffset += mpJustifications[ i ];
2413
2388
		// TODO: for kashida justification
2414
		// TODO: for kashida justification
2389
		// check the widths which are added to mpJustification
2415
		// check the widths which are added to mpJustification
2390
		// if added width is smaller than iKashidaWidth returned by 
2416
		// if added width is smaller than iKashidaWidth returned by 
Lines 2393-2405 void UniscribeLayout::ApplyDXArray( cons Link Here
2393
		// Need to think of a way to compensate the change in overall 
2419
		// Need to think of a way to compensate the change in overall 
2394
		// width.
2420
		// width.
2395
2421
2396
        // to prepare for the next visual item
2422
			if ( bHasKashida && mnMinKashidaWidth ) 
2397
        // update nXOffset to the next items position
2423
			{
2398
        // before the mpJustifications[] array gets modified
2424
				int nSpaceAdded;
2399
        int nMinGlyphPos, nEndGlyphPos;
2425
				for ( i = nMinGlyphPos; i < nEndGlyphPos; ++i )
2400
        if( GetItemSubrange( rVisualItem, nMinGlyphPos, nEndGlyphPos ) )
2426
				{
2401
            for( i = nMinGlyphPos; i < nEndGlyphPos; ++i )
2427
					nSpaceAdded =  mpJustifications[ i ] - mpGlyphAdvances[ i ];
2402
                nXOffset += mpJustifications[ i ];
2428
					if ( nSpaceAdded && ((1U << mpVisualAttrs[i].uJustification) & 0xFF89 ))
2429
					{
2430
						if ( i > nMinGlyphPos && ! mpGlyphAdvances [ i - 1 ] && nSpaceAdded >= mnMinKashidaWidth)
2431
						{
2432
							// vowel, we do it like ScriptJustify does
2433
							// this works great !!!
2434
							mpJustifications [ i ] = mpGlyphAdvances [ i ];
2435
							mpJustifications [ i - 1 ] += nSpaceAdded;
2436
						}
2437
2438
						if ( nSpaceAdded < mnMinKashidaWidth )
2439
						{
2440
							mpJustifications[ i ] = mpGlyphAdvances[ i ]; // overriding;
2441
							/*for ( int j = i; j >= nMinGlyphPos; --j )
2442
							{
2443
								if ( mpVisualAttrs[ j ].uJustification == SCRIPT_JUSTIFY_ARABIC_BLANK )
2444
								{
2445
									mpJustifications [ j ] += nSpaceAdded; // padding a blank instead
2446
									nSpaceAdded = 0;
2447
									break;
2448
								}
2449
							}*/
2450
							
2451
							// no blank found
2452
							// try the other side
2453
							for ( int j = i; j < nEndGlyphPos; ++j )
2454
							{
2455
								if ( mpVisualAttrs[ j ].uJustification == SCRIPT_JUSTIFY_ARABIC_BLANK )
2456
								{
2457
									mpJustifications [ j ] += nSpaceAdded; // padding a blank instead
2458
									nSpaceAdded = 0;
2459
									break;
2460
								}
2461
							}
2462
						
2463
							if ( nSpaceAdded ) 
2464
							{
2465
								// no blank found
2466
								// right align
2467
								// rVisualItem.mnXOffset += nSpaceAdded;
2468
							}
2469
						}
2470
					}
2471
				} 
2472
			}	
2473
		}
2474
2475
2403
2476
2404
        // right align the justification-adjusted glyphs in their cells for RTL-items
2477
        // right align the justification-adjusted glyphs in their cells for RTL-items
2405
        if( bManualCellAlign && rVisualItem.mpScriptItem->a.fRTL && !bHasKashida ) 
2478
        if( bManualCellAlign && rVisualItem.mpScriptItem->a.fRTL && !bHasKashida ) 
Lines 2454-2459 void UniscribeLayout::Justify( long nNew Link Here
2454
            nItemWidth = (int)((fStretch - 1.0) * nItemWidth + 0.5);
2527
            nItemWidth = (int)((fStretch - 1.0) * nItemWidth + 0.5);
2455
2528
2456
            SCRIPT_FONTPROPERTIES aFontProperties;
2529
            SCRIPT_FONTPROPERTIES aFontProperties;
2530
			aFontProperties.cBytes = sizeof (aFontProperties); // don't forget to initialize
2457
            int nMinKashida = 1;
2531
            int nMinKashida = 1;
2458
            HRESULT nRC = (*pScriptGetFontProperties)( mhDC, &rScriptCache, &aFontProperties );
2532
            HRESULT nRC = (*pScriptGetFontProperties)( mhDC, &rScriptCache, &aFontProperties );
2459
            if( !nRC )
2533
            if( !nRC )

Return to issue 60594