summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2008-04-03 16:08:21 +0000
committerKurt Zenker <kz@openoffice.org>2008-04-03 16:08:21 +0000
commitb87191aaf0c4e45cead0ceafad6b1b0992774a86 (patch)
tree098ddddc6c07aa235823127226069cc9b886d857 /vcl
parent01dfa203f5613c89304fe3a8570f0e8911c26ad9 (diff)
INTEGRATION: CWS vcl87 (1.108.206); FILE MERGED
2008/03/05 12:08:55 hdu 1.108.206.2: #i77976# adjust glyph positions for PDF-export on newer USP versions 2008/02/18 14:39:12 hdu 1.108.206.1: #i77976# fix BiDi glyph positioning on Vista (thank you Henner Drewes!)
Diffstat (limited to 'vcl')
-rwxr-xr-xvcl/win/source/gdi/winlayout.cxx122
1 files changed, 98 insertions, 24 deletions
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 954f967880fc..e13800cc30cb 100755
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: winlayout.cxx,v $
*
- * $Revision: 1.109 $
+ * $Revision: 1.110 $
*
- * last change: $Author: kz $ $Date: 2008-03-31 13:36:25 $
+ * last change: $Author: kz $ $Date: 2008-04-03 17:08:21 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -42,6 +42,7 @@
#include <rtl/ustring.hxx>
#include <osl/module.h>
+#include <osl/file.h>
#ifndef _SV_SALGDI_H
#include <salgdi.h>
@@ -70,6 +71,8 @@
#ifdef USE_UNISCRIBE
#include <Usp10.h>
+#include <ShLwApi.h>
+#include <winver.h>
#endif // USE_UNISCRIBE
#include <hash_map>
@@ -1144,6 +1147,8 @@ static HRESULT ((WINAPI *pScriptTextOut)( const HDC, SCRIPT_CACHE*,
static HRESULT ((WINAPI *pScriptGetFontProperties)( HDC, SCRIPT_CACHE*, SCRIPT_FONTPROPERTIES* ));
static HRESULT ((WINAPI *pScriptFreeCache)( SCRIPT_CACHE* ));
+static bool bManualCellAlign = true;
+
// -----------------------------------------------------------------------
static bool InitUSP()
@@ -1217,6 +1222,36 @@ static bool InitUSP()
aUspModule = NULL;
}
+ // get the DLL version info
+ int nUspVersion = 0;
+ // TODO: there must be a simpler way to get the friggin version info from OSL?
+ rtl_uString* pModuleURL = NULL;
+ osl_getModuleURLFromAddress( (void*)pScriptIsComplex, &pModuleURL );
+ rtl_uString* pModuleFileName = NULL;
+ if( pModuleURL )
+ osl_getSystemPathFromFileURL( pModuleURL, &pModuleFileName );
+ const sal_Unicode* pModuleFileCStr = NULL;
+ if( pModuleFileName )
+ pModuleFileCStr = rtl_uString_getStr( pModuleFileName );
+ if( pModuleFileCStr )
+ {
+ DWORD nHandle;
+ DWORD nBufSize = ::GetFileVersionInfoSizeW( pModuleFileCStr, &nHandle );
+ char* pBuffer = (char*)alloca( nBufSize );
+ WIN_BOOL bRC = ::GetFileVersionInfoW( pModuleFileCStr, nHandle, nBufSize, pBuffer );
+ VS_FIXEDFILEINFO* pFixedFileInfo = NULL;
+ UINT nFixedFileSize = 0;
+ if( bRC )
+ ::VerQueryValueW( pBuffer, L"\\", (void**)&pFixedFileInfo, &nFixedFileSize );
+ if( pFixedFileInfo && pFixedFileInfo->dwSignature == 0xFEEF04BD )
+ nUspVersion = HIWORD(pFixedFileInfo->dwProductVersionMS) * 10000
+ + LOWORD(pFixedFileInfo->dwProductVersionMS);
+ }
+
+ // #i77976# USP>=1.0600 changed the need to manually align glyphs in their cells
+ if( nUspVersion >= 10600 )
+ bManualCellAlign = false;
+
return bUspEnabled;
}
@@ -1745,12 +1780,12 @@ int UniscribeLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos,
return 0;
// find the visual item for the nStart glyph position
- int nItem;
+ int nItem = 0;
const VisualItem* pVI = mpVisualItems;
- if( nStart == 0 ) // nStart==0 for first visible glyph
+ if( nStart <= 0 ) // nStart<=0 requests the first visible glyph
{
// find first visible item
- for( nItem = 0; nItem < mnItemCount; ++nItem, ++pVI )
+ for(; nItem < mnItemCount; ++nItem, ++pVI )
if( !pVI->IsEmpty() )
break;
// it is possible that there are glyphs but no valid visual item
@@ -1763,7 +1798,7 @@ int UniscribeLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos,
--nStart;
// find matching item
- for( nItem = 0; nItem < mnItemCount; ++nItem, ++pVI )
+ for(; nItem < mnItemCount; ++nItem, ++pVI )
if( (nStart >= pVI->mnMinGlyphPos)
&& (nStart < pVI->mnEndGlyphPos) )
break;
@@ -1822,6 +1857,10 @@ int UniscribeLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos,
while( (--c >= pVI->mnMinCharPos)
&& (nTmpIndex == mpLogClusters[c]) )
nXOffset += mpCharWidths[c];
+
+ // adjust the xoffset if justified glyphs are not positioned at their justified positions yet
+ if( mpJustifications && !bManualCellAlign )
+ nXOffset += mpJustifications[ nStart ] - mpGlyphAdvances[ nStart ];
}
// create mpGlyphs2Chars[] if it is needed later
@@ -1875,6 +1914,11 @@ int UniscribeLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos,
break;
}
+ // RTL-justified glyph positioning is not easy
+ // simplify the code by just returning only one glyph at a time
+ if( mpJustifications && !bManualCellAlign && pVI->mpScriptItem->a.fRTL )
+ break;
+
// stop when the x-position of the next glyph is unexpected
if( !pGlyphAdvances )
if( (mpGlyphOffsets && (mpGlyphOffsets[nStart].du != aGOffset.du) )
@@ -2306,15 +2350,34 @@ void UniscribeLayout::ApplyDXArray( const ImplLayoutArgs& rArgs )
|| (rVisualItem.mnEndCharPos <= mnMinCharPos) )
continue;
+ bool bHasKashida = false;
if( rVisualItem.mpScriptItem->a.fRTL )
{
- // HACK: make sure kashida justification is used when possible
- // TODO: make sure this works on all usp versions
for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
- if( (1U << mpVisualAttrs[i].uJustification) & 0x7F89 )
- mpVisualAttrs[i].uJustification = SCRIPT_JUSTIFY_ARABIC_KASHIDA;
+ if ( (1U << mpVisualAttrs[i].uJustification) & 0x7F89 ) // any Arabic justification ?
+ {
+ // yes
+ bHasKashida = true;
+ break;
+ }
+ if ( bHasKashida )
+ for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
+ {
+ 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
+ // a word gets a Kashida appended) override this.
+
+ // I chose SCRIPT_JUSTIFY_ARABIC_KASHIDA to replace SCRIPT_JUSTIFY_NONE
+ // just because this previous hack (which I haven't understand, sorry) used
+ // the same value to replace. Don't know if this is really the best
+ // thing to do, but it seems to fix things
+ mpVisualAttrs[i].uJustification = SCRIPT_JUSTIFY_ARABIC_KASHIDA;
+ }
}
+
// convert virtual charwidths to glyph justification values
HRESULT nRC = (*pScriptApplyLogicalWidth)(
mpCharWidths + rVisualItem.mnMinCharPos,
@@ -2334,23 +2397,34 @@ void UniscribeLayout::ApplyDXArray( const ImplLayoutArgs& rArgs )
break;
}
- // update nXOffset to the position of the next visual item
- int nEndGlyphPos;
- if( GetItemSubrange( rVisualItem, i, nEndGlyphPos ) )
- for(; i < nEndGlyphPos; ++i )
+ // TODO: for kashida justification
+ // check the widths which are added to mpJustification
+ // if added width is smaller than iKashidaWidth returned by
+ // ScriptGetFontProperties, do something (either enlarge to
+ // iKashidaWidth, or reduce to original width).
+ // 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( rVisualItem.mpScriptItem->a.fRTL )
+ // right align the justification-adjusted glyphs in their cells for RTL-items
+ if( bManualCellAlign && rVisualItem.mpScriptItem->a.fRTL && !bHasKashida )
{
- // right align adjusted glyph positions for RTL item
- // exception: kashida aligned glyphs
- // TODO: make sure this works on all usp versions
- for( i = rVisualItem.mnMinGlyphPos+1; i < rVisualItem.mnEndGlyphPos; ++i )
- if( mpVisualAttrs[i].uJustification != SCRIPT_JUSTIFY_ARABIC_KASHIDA )
- {
- mpJustifications[i-1] += mpJustifications[ i ] - mpGlyphAdvances[ i ];
- mpJustifications[ i ] = mpGlyphAdvances[ i ];
- }
+ for( i = nMinGlyphPos; i < nEndGlyphPos; ++i )
+ {
+ const int nXOffsetAdjust = mpJustifications[i] - mpGlyphAdvances[i];
+ if( i == nMinGlyphPos )
+ rVisualItem.mnXOffset += nXOffsetAdjust;
+ else
+ mpJustifications[i-1] += nXOffsetAdjust;
+ mpJustifications[i] -= nXOffsetAdjust;
+ }
}
}
}