CWS-TOOLING: integrate CWS ooo31gsl2_DEV300

2009-02-18 16:57:37 +0100 hdu  r268244 : #i99367# force logical-width of diacritic glyphs to zero
2009-02-18 14:51:18 +0100 pl  r268224 : #i98525# correct popup menu position on right side in RTL UI
2009-02-18 13:17:20 +0100 pl  r268213 : #i99299# check for NULL ptr
2009-02-18 10:51:48 +0100 pl  r268204 : #i99167# revert change from issue 93173
2009-02-17 16:56:47 +0100 hdu  r268181 : #i99295# src-=debug
2009-02-17 16:43:40 +0100 hdu  r268180 : #i99295# retarget unresolved pLogCluster[n] to a glyph inside the cluster
2009-02-17 16:15:45 +0100 sj  r268178 : #i94831# fixed performance of table import, no longer looping
2009-02-17 13:19:00 +0100 hdu  r268165 : #i97304# reapplied SJ's fix for OOo31
2009-02-17 12:04:53 +0100 hdu  r267989 : #i99241# revert upstream change from icu-trac issue 6249
2009-02-16 18:35:07 +0100 pl  r267832 : #i99166# convolute the already convoluted RTL positioning code some more
2009-02-16 17:25:24 +0100 hdu  r267828 : #i99227# do not export the glyph-flags for the i97326-workaround
2009-02-13 16:26:10 +0100 pl  r267729 : #i98525# remove unused typeinfo header
2009-02-13 16:25:02 +0100 pl  r267728 : #i98525# fix scrolling and native menu issues in RTL UI
2009-02-13 11:18:37 +0100 pl  r267705 : #i98525# merge from CWS vcl99
This commit is contained in:
Oliver Bolte
2009-03-05 11:59:11 +00:00
parent 75875aa445
commit fa1f37753d
9 changed files with 148 additions and 99 deletions

View File

@@ -346,7 +346,6 @@ bool AquaSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rR
// set offsets for positioning
const float offset = 9.0;
const float lineHeight = 17.0;
// get the pointers
AquaSalFrame * pParentAquaSalFrame = (AquaSalFrame *) pWin->ImplGetWindowImpl()->mpRealParent->ImplGetFrame();
@@ -360,21 +359,19 @@ bool AquaSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rR
NSMenu* pCopyMenu = [mpMenu copy];
// filter disabled elements
sal_Int32 drawnItems = removeUnusedItemsRunner( pCopyMenu );
removeUnusedItemsRunner( pCopyMenu );
// create frame rect
NSRect displayPopupFrame = NSMakeRect( rRect.nLeft+(offset-1), rRect.nTop+(offset+1), popupFrame.size.width, 0 );
pParentAquaSalFrame->VCLToCocoa(displayPopupFrame, false);
// adjust frame rect when necessary
// do the same strange semantics as vcl popup windows to arrive at a frame geometry
// in mirrored UI case; best done by actually executing the same code
USHORT nArrangeIndex;
Point position = pWin->ImplCalcPos( pWin, rRect, nFlags, nArrangeIndex );
if( position.Y() < rRect.nTop ) {
displayPopupFrame.origin.y += ( lineHeight*drawnItems );
}
if( position.X() < rRect.nLeft ) {
displayPopupFrame.origin.x -= popupFrame.size.width;
}
pWin->SetPosPixel( pWin->ImplCalcPos( pWin, rRect, nFlags, nArrangeIndex ) );
displayPopupFrame.origin.x = pWin->ImplGetFrame()->maGeometry.nX - pParentAquaSalFrame->maGeometry.nX + offset;
displayPopupFrame.origin.y = pWin->ImplGetFrame()->maGeometry.nY - pParentAquaSalFrame->maGeometry.nY + offset;
pParentAquaSalFrame->VCLToCocoa(displayPopupFrame, false);
// open popup menu
NSPopUpButtonCell * pPopUpButtonCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO];

View File

@@ -145,6 +145,7 @@ protected:
};
// helper functions often used with ImplLayoutArgs
bool IsDiacritic( sal_UCS4 );
int GetVerticalFlags( sal_UCS4 );
sal_UCS4 GetVerticalChar( sal_UCS4 );
// #i80090# GetMirroredChar also needed outside vcl, moved to svapp.hxx
@@ -329,11 +330,11 @@ public:
mnGlyphIndex(nGlyphIndex), maLinearPos(rLinearPos)
{}
enum{ FALLBACK_MASK=0xFF, IS_IN_CLUSTER=0x100, IS_RTL_GLYPH=0x200 };
enum{ FALLBACK_MASK=0xFF, IS_IN_CLUSTER=0x100, IS_RTL_GLYPH=0x200, IS_DIACRITIC=0x400 };
bool IsClusterStart() const { return !(mnFlags & IS_IN_CLUSTER); }
bool IsRTLGlyph() const { return ((mnFlags & IS_RTL_GLYPH) != 0); }
bool IsDiacritic() const { return (mnOrigWidth <= 0); } // TODO: better heuristic
bool IsClusterStart() const { return ((mnFlags & IS_IN_CLUSTER) == 0); }
bool IsRTLGlyph() const { return ((mnFlags & IS_RTL_GLYPH) != 0); }
bool IsDiacritic() const { return ((mnFlags & IS_DIACRITIC) != 0); }
};
// ---------------

View File

@@ -65,6 +65,43 @@
// =======================================================================
// TODO: ask the glyph directly, for now we need this method because of #i99367#
// true if a codepoint doesn't influence the logical text width
bool IsDiacritic( sal_UCS4 nChar )
{
// shortcut abvious non-diacritics
if( nChar < 0x0300 )
return false;
if( nChar >= 0x2100 )
return false;
struct DiaRange { sal_UCS4 mnMin, mnEnd;};
static const DiaRange aRanges[] = {
{0x0300, 0x0370},
{0x0590, 0x05C0}, {0x05C1, 0x05C3}, {0x05C3, 0x05C6}, {0x05C7, 0x05C8},
{0x0610, 0x061B}, {0x064B, 0x0660}, {0x0670, 0x0671}, {0x06D6, 0x06DC}, {0x06DF, 0x06EE},
{0x0730, 0x074D}, {0x07A6, 0x07B1}, {0x07EB, 0x07F4},
#if 0 // all known fonts have zero-width diacritics already, so no need to query it
{0x0900, 0x0904}, {0x093C, 0x093D}, {0x0941, 0x0948}, {0x094D, 0x0950}, {0x0951, 0x0958},
{0x0980, 0x0985}, {0x09BC, 0x09BD}, {0x09C1, 0x09C7}, {0x09CD, 0x09CE}, {0x09E2, 0x09E6},
{0x0A00, 0x0A05}, {0x0A3C, 0x0A59}, //...
#endif
{0x1DC0, 0x1E00},
{0x205F, 0x2070}, {0x20D0, 0x2100}
};
// TODO: almost anything is faster than an O(n) search
static const int nCount = sizeof(aRanges) / sizeof(*aRanges);
const DiaRange* pRange = &aRanges[0];
for( int i = nCount; --i >= 0; ++pRange )
if( (pRange->mnMin <= nChar) && (nChar < pRange->mnEnd) )
return true;
return false;
}
// =======================================================================
int GetVerticalFlags( sal_UCS4 nChar )
{
if( (nChar >= 0x1100 && nChar <= 0x11f9) // Hangul Jamo
@@ -1077,7 +1114,7 @@ void GenericSalLayout::ApplyDXArray( ImplLayoutArgs& rArgs )
return;
// determine cluster boundaries and x base offset
int nCharCount = rArgs.mnEndCharPos - rArgs.mnMinCharPos;
const int nCharCount = rArgs.mnEndCharPos - rArgs.mnMinCharPos;
int* pLogCluster = (int*)alloca( nCharCount * sizeof(int) );
int i, n;
long nBasePointX = -1;
@@ -1096,6 +1133,20 @@ void GenericSalLayout::ApplyDXArray( ImplLayoutArgs& rArgs )
if( nBasePointX < 0 )
nBasePointX = pG->maLinearPos.X();
}
// retarget unresolved pLogCluster[n] to a glyph inside the cluster
// TODO: better do it while the deleted-glyph markers are still there
for( n = 0; n < nCharCount; ++n )
if( (i = pLogCluster[0]) >= 0 )
break;
if( n >= nCharCount )
return;
for( n = 0; n < nCharCount; ++n )
{
if( pLogCluster[ n ] < 0 )
pLogCluster[ n ] = i;
else
i = pLogCluster[ n ];
}
// calculate adjusted cluster widths
sal_Int32* pNewGlyphWidths = (sal_Int32*)alloca( mnGlyphCount * sizeof(long) );
@@ -1106,15 +1157,11 @@ void GenericSalLayout::ApplyDXArray( ImplLayoutArgs& rArgs )
for( int nCharPos = i = -1; rArgs.GetNextPos( &nCharPos, &bRTL ); )
{
n = nCharPos - rArgs.mnMinCharPos;
if( pLogCluster[ n ] >= 0 )
i = pLogCluster[ n ];
if( i >= 0 )
{
long nDelta = rArgs.mpDXArray[ n ] ;
if( n > 0 )
nDelta -= rArgs.mpDXArray[ n-1 ];
pNewGlyphWidths[ i ] += nDelta * mnUnitsPerPixel;
}
i = pLogCluster[ n ];
long nDelta = rArgs.mpDXArray[ n ] ;
if( n > 0 )
nDelta -= rArgs.mpDXArray[ n-1 ];
pNewGlyphWidths[ i ] += nDelta * mnUnitsPerPixel;
}
// move cluster positions using the adjusted widths
@@ -1133,10 +1180,11 @@ void GenericSalLayout::ApplyDXArray( ImplLayoutArgs& rArgs )
{
if( pClusterG->IsClusterStart() )
break;
nOldClusterWidth += pClusterG->mnNewWidth;
if( !pClusterG->IsDiacritic() ) // #i99367# ignore diacritics
nOldClusterWidth += pClusterG->mnNewWidth;
nNewClusterWidth += pNewGlyphWidths[j];
}
int nDiff = nNewClusterWidth - nOldClusterWidth;
const int nDiff = nNewClusterWidth - nOldClusterWidth;
// adjust cluster glyph widths and positions
nDelta = nBasePointX + (nNewPos - pG->maLinearPos.X());
@@ -1179,13 +1227,13 @@ void GenericSalLayout::Justify( long nNewWidth )
{
if( !pG->IsDiacritic() )
++nStretchable;
if( nMaxGlyphWidth < pG->mnOrigWidth)
nMaxGlyphWidth = pG->mnOrigWidth;
if( nMaxGlyphWidth < pG->mnOrigWidth )
nMaxGlyphWidth = pG->mnOrigWidth;
}
// move rightmost glyph to requested position
nOldWidth -= pGRight->mnOrigWidth;
if( nOldWidth <= 0)
if( nOldWidth <= 0 )
return;
if( nNewWidth < nMaxGlyphWidth)
nNewWidth = nMaxGlyphWidth;

View File

@@ -181,7 +181,7 @@ public:
virtual int GetFontFaceNum() const { return mpFontInfo->GetFaceNum(); }
virtual bool TestFont() const;
virtual void* GetFtFace() const;
virtual int GetLoadFlags() const { return mnLoadFlags; }
virtual int GetLoadFlags() const { return (mnLoadFlags & ~FT_LOAD_IGNORE_TRANSFORM); }
virtual bool NeedsArtificialBold() const { return mbArtBold; }
virtual bool NeedsArtificialItalic() const { return mbArtItalic; }

View File

@@ -519,7 +519,9 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
continue;
}
// apply vertical flags, etc.
bool bDiacritic = false;
if( nCharPos >= 0 )
{
sal_UCS4 aChar = rArgs.mpStr[ nCharPos ];
@@ -535,12 +537,22 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
}
#endif
nGlyphIndex = rFont.FixupGlyphIndex( nGlyphIndex, aChar );
// #i99367# HACK: try to detect all diacritics
if( aChar>=0x0300 && aChar<0x2100 )
bDiacritic = IsDiacritic( aChar );
}
// get glyph position and its metrics
aNewPos = Point( (int)(pPos->fX+0.5), (int)(pPos->fY+0.5) );
const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex );
int nGlyphWidth = rGM.GetCharWidth();
if( nGlyphWidth <= 0 )
bDiacritic |= true;
// #i99367# force all diacritics to zero width
// TODO: we need mnOrigWidth/mnLogicWidth/mnNewWidth
else if( bDiacritic )
nGlyphWidth = 0;
// heuristic to detect glyph clusters
bool bInCluster = true;
@@ -556,7 +568,7 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
nClusterMinPos = nCharPos; // extend cluster
else if( nCharPos <= nClusterMaxPos )
/*NOTHING*/; // inside cluster
else if( nGlyphWidth <= 0 )
else if( bDiacritic )
nClusterMaxPos = nCharPos; // add diacritic to cluster
else {
nClusterMinPos = nClusterMaxPos = nCharPos; // new cluster
@@ -570,7 +582,7 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
nClusterMaxPos = nCharPos; // extend cluster
else if( nCharPos >= nClusterMinPos )
/*NOTHING*/; // inside cluster
else if( nGlyphWidth <= 0 )
else if( bDiacritic )
{
nClusterMinPos = nCharPos; // ICU often has [diacritic* baseglyph*]
if( bClusterStart ) {
@@ -590,6 +602,8 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
if( bRightToLeft )
nGlyphFlags |= GlyphItem::IS_RTL_GLYPH;
if( bDiacritic )
nGlyphFlags |= GlyphItem::IS_DIACRITIC;
// add resulting glyph item to layout
const GlyphItem aGI( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth );

View File

@@ -370,7 +370,7 @@ static Window* ImplFindAccelWindow( Window* pParent, USHORT& rIndex, xub_Unicode
pWindow = ImplGetNextWindow( pParent, i, i, TRUE );
else
pWindow = ImplGetChildWindow( pParent, nFormStart, i, TRUE );
while ( bSearch )
while( bSearch && pWindow )
{
const XubString aStr = pWindow->GetText();
USHORT nPos = aStr.Search( '~' );
@@ -415,7 +415,11 @@ static Window* ImplFindAccelWindow( Window* pParent, USHORT& rIndex, xub_Unicode
break;
if ( i < nFormEnd )
{
pWindow = ImplGetNextWindow( pParent, i, i, bCheckEnable );
if( ! pWindow )
pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
}
else
pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
}

View File

@@ -424,6 +424,11 @@ Point FloatingWindow::ImplCalcPos( Window* pWindow,
{
if( devRectRTL.Right()-aSize.Width()+1 < aScreenRect.Left() )
aPos.X() -= aScreenRect.Left() - devRectRTL.Right() + aSize.Width() - 1;
else if( aPos.X() + aSize.Width() > aScreenRect.Right() )
{
aPos.X() -= aSize.Width()-2; // popup to left instead
aPos.Y() -= 2;
}
}
else if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
{

View File

@@ -31,42 +31,36 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#ifndef _SV_SVSYS_HXX
#include <svsys.h>
#endif
#include <vcl/salinst.hxx>
#include <tools/list.hxx>
#include <tools/debug.hxx>
#include <vcl/svdata.hxx>
#include <vcl/svapp.hxx>
#include <vcl/mnemonic.hxx>
#include <vcl/image.hxx>
#include <vcl/event.hxx>
#include <vcl/help.hxx>
#ifndef _SV_SVIDS_HRC
#include <vcl/svids.hrc>
#endif
#include <vcl/floatwin.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/timer.hxx>
#include <vcl/sound.hxx>
#include <vcl/decoview.hxx>
#include <vcl/bitmap.hxx>
#ifndef _SV_RC_H
#include <tools/rc.h>
#endif
#include <vcl/menu.hxx>
#include <vcl/button.hxx>
#include <vcl/gradient.hxx>
#include <vcl/i18nhelp.hxx>
#include <vcl/taskpanelist.hxx>
#include <vcl/window.h>
#include <vcl/controllayout.hxx>
#include <vcl/toolbox.hxx>
#include <tools/stream.hxx>
#include <vcl/salmenu.hxx>
#include <vcl/salframe.hxx>
#include <vcl/dockingarea.hxx>
#include "svsys.h"
#include "vcl/salinst.hxx"
#include "tools/list.hxx"
#include "tools/debug.hxx"
#include "vcl/svdata.hxx"
#include "vcl/svapp.hxx"
#include "vcl/mnemonic.hxx"
#include "vcl/image.hxx"
#include "vcl/event.hxx"
#include "vcl/help.hxx"
#include "vcl/svids.hrc"
#include "vcl/floatwin.hxx"
#include "vcl/wrkwin.hxx"
#include "vcl/timer.hxx"
#include "vcl/sound.hxx"
#include "vcl/decoview.hxx"
#include "vcl/bitmap.hxx"
#include "tools/rc.h"
#include "vcl/menu.hxx"
#include "vcl/button.hxx"
#include "vcl/gradient.hxx"
#include "vcl/i18nhelp.hxx"
#include "vcl/taskpanelist.hxx"
#include "vcl/window.h"
#include "vcl/controllayout.hxx"
#include "vcl/toolbox.hxx"
#include "tools/stream.hxx"
#include "vcl/salmenu.hxx"
#include "vcl/salframe.hxx"
#include "vcl/dockingarea.hxx"
#include <com/sun/star/uno/Reference.h>
@@ -3572,7 +3566,7 @@ USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupM
pWin->SetFocusId( nFocusId );
pWin->SetOutputSizePixel( aSz );
// #102158# menues must never grab the focus, otherwise
// #102158# menus must never grab the focus, otherwise
// they will be closed immediately
// from now on focus grabbing is only prohibited automatically if
// FLOATWIN_POPUPMODE_GRABFOCUS was set (which is done below), because some
@@ -3581,15 +3575,7 @@ USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupM
if ( GetItemCount() )
{
SalMenu* pMenu = ImplGetSalMenu();
Rectangle aNativeRect( aRect );
if( pW->IsRTLEnabled() && Application::GetSettings().GetLayoutRTL() )
{
Point aPt( aRect.TopLeft() );
aPt.X() += aSz.Width();
pW->ImplMirrorFramePos( aPt );
aNativeRect = Rectangle( aPt, aNativeRect.GetSize() );
}
if( pMenu && pMenu->ShowNativePopupMenu( pWin, aNativeRect, nPopupModeFlags | FLOATWIN_POPUPMODE_GRABFOCUS ) )
if( pMenu && pMenu->ShowNativePopupMenu( pWin, aRect, nPopupModeFlags | FLOATWIN_POPUPMODE_GRABFOCUS ) )
{
pWin->StopExecute(0);
pWin->doShutdown();

View File

@@ -3015,25 +3015,9 @@ void Window::ImplScroll( const Rectangle& rRect,
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
pWindow->mpWindowImpl->mnX += nHorzScroll;
pWindow->mpWindowImpl->maPos.X() += nHorzScroll;
pWindow->mpWindowImpl->mnY += nVertScroll;
pWindow->mpWindowImpl->maPos.Y() += nVertScroll;
if ( pWindow->ImplUpdatePos() )
pWindow->ImplUpdateSysObjPos();
if ( pWindow->IsReallyVisible() )
pWindow->ImplSetClipFlag();
if ( pWindow->mpWindowImpl->mpClientWindow )
pWindow->mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = pWindow->mpWindowImpl->maPos;
if ( pWindow->IsVisible() )
{
pWindow->ImplCallMove();
}
else
{
pWindow->mpWindowImpl->mbCallMove = TRUE;
}
Point aPos = pWindow->GetPosPixel();
aPos += Point( nHorzScroll, nVertScroll );
pWindow->SetPosPixel( aPos );
pWindow = pWindow->mpWindowImpl->mpNext;
}
@@ -3261,7 +3245,6 @@ void Window::ImplPosSizeWindow( long nX, long nY,
if ( nFlags & WINDOW_POSSIZE_X )
{
long nOrgX = nX;
//if ( nX != mnX )
// --- RTL --- (compare the screen coordinates)
Point aPtDev( Point( nX+mnOutOffX, 0 ) );
if( ImplHasMirroredGraphics() )
@@ -3276,6 +3259,17 @@ void Window::ImplPosSizeWindow( long nX, long nY,
// --- RTL --- (re-mirror at parent window)
nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
}
/* #i99166# An LTR window in RTL UI that gets sized only would be
expected to not moved its upper left point
*/
if( bnXRecycled )
{
if( ImplIsAntiparallel() )
{
aPtDev.X() = mpWindowImpl->mnAbsScreenX;
nOrgX = mpWindowImpl->maPos.X();
}
}
}
else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
{