Commits

Anonymous committed fe6408c

CWS-TOOLING: integrate CWS ooo301gsl1_DEV300

  • Participants
  • Parent commits b306b40

Comments (0)

Files changed (6)

File scp2/source/ooo/file_library_ooo.scp

 File gid_File_Lib_Go
     Name = LIBNAME(go);
     TXT_FILE_BODY;
-    Styles = (PACKED,UNO_COMPONENT);
+    Styles = (PACKED,UNO_COMPONENT,PATCH);
     Dir = gid_Dir_Program;
     RegistryID = gid_Starregistry_Services_Rdb;
 End

File vcl/aqua/inc/salgdi.h

     void                ImplDrawPixel( long nX, long nY, const RGBAColor& ); // helper to draw single pixels
     
     bool                CheckContext();
-    void                UpdateWindow( NSRect& rRect ); // delivered in NSView coordinates
+    void                UpdateWindow( NSRect& ); // delivered in NSView coordinates
 	void				RefreshRect( const CGRect& );
-	void				RefreshRect( const NSRect& rRect );
+	void				RefreshRect( const NSRect& );
 	void				RefreshRect(float lX, float lY, float lWidth, float lHeight);
 
     void                SetState();
 	RefreshRect( rRect.origin.x, rRect.origin.y, rRect.size.width, rRect.size.height );
 }
 
+inline void AquaSalGraphics::RefreshRect( const NSRect& rRect )
+{
+	RefreshRect( rRect.origin.x, rRect.origin.y, rRect.size.width, rRect.size.height );
+}
+
 inline RGBAColor::RGBAColor( SalColor nSalColor )
 :	mfRed( SALCOLOR_RED(nSalColor) * (1.0/255))
 ,	mfGreen( SALCOLOR_GREEN(nSalColor) * (1.0/255))

File vcl/aqua/source/gdi/salatslayout.cxx

 	float      		mfFontScale;
 
 private:
-	bool	InitGIA() const;
+	bool	InitGIA( ImplLayoutArgs* pArgs = NULL ) const;
 	bool	GetIdealX() const;
 	bool	GetDeltaY() const;
 
     mutable Fixed*			mpGlyphOrigAdvs;	// contains glyph widths for the unjustified layout
     mutable Fixed*			mpDeltaY;			// vertical offset from the baseline
 
+	struct SubPortion { int mnMinCharPos, mnEndCharPos; Fixed mnXOffset; };
+	typedef std::vector<SubPortion> SubPortionVector;
+	mutable SubPortionVector	maSubPortions;		// Writer&ATSUI layouts can differ quite a bit... 
+
     // storing details about fonts used in glyph-fallback for this layout
     mutable class FallbackInfo*	mpFallbackInfo;
 
 	OSStatus eStatus = ATSUSetLayoutControls( maATSULayout, 3, nTags, nBytes, nVals );
 	if( eStatus != noErr )
 		return;
+
+	// check result of the justied layout
+	if( rArgs.mpDXArray )
+		InitGIA( &rArgs );
 }
 
 // -----------------------------------------------------------------------
 	DBG_ASSERT( (theErr==noErr), "ATSLayout::DrawText ATSUSetLayoutControls failed!\n" );
 
 	// Draw the text
-	DBG_ASSERT( mnBaseAdv==0, "ATSLayout::DrawText() not yet implemented for glyph fallback layouts" );
 	const Point aPos = GetDrawPosition( Point(mnBaseAdv,0) );
 	const Fixed nFixedX = Vcl2Fixed( +aPos.X() );
     const Fixed nFixedY = Vcl2Fixed( -aPos.Y() ); // adjusted for y-mirroring
-	theErr = ATSUDrawText( maATSULayout, mnMinCharPos, mnCharCount, nFixedX, nFixedY );
-	DBG_ASSERT( (theErr==noErr), "ATSLayout::DrawText ATSUDrawText failed!\n" );
+	if( maSubPortions.empty() )
+		ATSUDrawText( maATSULayout, mnMinCharPos, mnCharCount, nFixedX, nFixedY );
+	else
+	{
+		// draw the sub-portions and apply individual adjustments
+		SubPortionVector::const_iterator it = maSubPortions.begin();
+		for(; it != maSubPortions.end(); ++it )
+		{
+			const SubPortion& rSubPortion = *it;
+			ATSUDrawText( maATSULayout,
+				rSubPortion.mnMinCharPos, rSubPortion.mnEndCharPos - rSubPortion.mnMinCharPos,
+				nFixedX + rSubPortion.mnXOffset, nFixedY );
+		}
+	}
 
 	// request an update of the changed window area
 	if( rAquaGraphics.IsWindowGraphics() )
     Fixed nXOffset = mnBaseAdv;
     for( int i = 0; i < nStart; ++i )
         nXOffset += mpGlyphAdvances[ i ];
+    // if sub-portion offsets are involved there is an additional x-offset
+    if( !maSubPortions.empty() )
+    {
+    	// prepare to find the sub-portion
+        int nCharPos = nStart + mnMinCharPos;
+        if( mpGlyphs2Chars )
+            nCharPos = mpGlyphs2Chars[nStart];
+
+    	// find the matching subportion
+    	// TODO: is a non-linear search worth it?
+    	SubPortionVector::const_iterator it = maSubPortions.begin();
+        for(; it != maSubPortions.end(); ++it) {
+            const SubPortion& r = *it;
+            if( nCharPos < r.mnMinCharPos )
+                continue;
+            if( nCharPos >= r.mnEndCharPos )
+                continue;
+            // apply the sub-portion xoffset
+            nXOffset += r.mnXOffset;
+            break;
+    	}
+    }
 
 	Fixed nYOffset = 0;
 	if( mpDeltaY )
 
        	// check if glyph fallback is needed for this glyph
         // TODO: use ATSUDirectGetLayoutDataArrayPtrFromTextLayout(kATSUDirectDataStyleIndex) API instead?
-	const int nCharPos = mpGlyphs2Chars ? mpGlyphs2Chars[nStart] : nStart + mnMinCharPos;
+        const int nCharPos = mpGlyphs2Chars ? mpGlyphs2Chars[nStart] : nStart + mnMinCharPos;
         ATSUFontID nFallbackFontID = kATSUInvalidFontID;
         UniCharArrayOffset nChangedOffset = 0;
         UniCharCount nChangedLength = 0;
             break;
 
         // stop when next the x-position is unexpected
+        if( !maSubPortions.empty() )
+            break;	 // TODO: finish the complete sub-portion
         if( !pGlyphAdvances && mpGlyphOrigAdvs )
             if( mpGlyphAdvances[nStart-1] != mpGlyphOrigAdvs[nStart-1] )
                 break;
 **/
 int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const
 {
+	// get a quick overview on what could fit
     const long nPixelWidth = (nMaxWidth - (nCharExtra * mnCharCount)) / nFactor;
 
 	UniCharArrayOffset nBreakPos = mnMinCharPos;
 	if( nBreakPos >= static_cast<UniCharArrayOffset>(mnEndCharPos) )
 		return STRING_LEN;
 
+	// for the nCharExtra!=0 case the resulting nBreakPos needs be involved
+	if( nCharExtra != 0 )
+	{
+		// age-old nCharExtra!=0 semantic is quite incompatible with ATSUBreakLine()
+		// TODO: use a better way than by testing each the char position
+		InitGIA();
+		ATSUTextMeasurement nATSUSumWidth = 0;
+	    const ATSUTextMeasurement nATSUMaxWidth = Vcl2Fixed( nMaxWidth / nFactor );
+	    const ATSUTextMeasurement nATSUExtraWidth = Vcl2Fixed( nCharExtra ) / nFactor;
+		for( int i = 0; i < mnCharCount; ++i)
+		{
+	        nATSUSumWidth += mpCharWidths[i];
+			if( nATSUSumWidth >= nATSUMaxWidth )
+				return (mnMinCharPos + i);
+			nATSUSumWidth += nATSUExtraWidth;
+		}
+
+		return STRING_LEN;
+	}
+
 	// GetTextBreak()'s callers expect it to return the "stupid visual line break".
 	// Returning anything else result.s in subtle problems in the application layers.
 	static const bool bInWord = true; // TODO: add as argument to GetTextBreak() method
 
 // -----------------------------------------------------------------------
 /**
- * ATSLayout::InitGIA() : Get many informations about layouted text
+ * ATSLayout::InitGIA() : get many informations about layouted text
  *
  * Fills arrays of information about the gylph layout previously done
  *	in ASTLayout::LayoutText() : glyph advance (width), glyph delta Y (from baseline),
  *
  * @return : true if everything could be computed, otherwise false
 **/
-bool ATSLayout::InitGIA() const
+bool ATSLayout::InitGIA( ImplLayoutArgs* pArgs ) const
 {
 	// no need to run InitGIA more than once on the same ATSLayout object
 	if( mnGlyphCount >= 0 )
 		"ATSLayout::InitGIA(): measured widths do not match!\n" );
 #endif
 
-	// Release data array ptr
+	// #i91183# we need to split up the portion into sub-portions
+	// if the ATSU-layout differs too much from the requested layout
+	if( pArgs && pArgs->mpDXArray )
+	{
+		// TODO: non-strong-LTR case cases should be handled too
+		if( 0 == (~pArgs->mnFlags & (TEXT_LAYOUT_BIDI_STRONG|TEXT_LAYOUT_BIDI_LTR)) )
+		{
+			Fixed nSumCharWidths = 0;
+			SubPortion aSubPortion = { mnMinCharPos, 0, 0 };
+			for( int i = 0; i < mnCharCount; ++i )
+			{
+				// calculate related logical position
+				nSumCharWidths += mpCharWidths[i];
+
+				// start new sub-portion if needed
+				const Fixed nNextXPos = Vcl2Fixed(pArgs->mpDXArray[i]);
+				const Fixed nNextXOffset = nNextXPos - nSumCharWidths;
+				const Fixed nFixedDiff = aSubPortion.mnXOffset - nNextXOffset;
+				if( (nFixedDiff < -0xC000) || (nFixedDiff > +0xC000) ) {
+					// get to the end of the current sub-portion
+					// prevent splitting up at diacritics etc.
+					int j = i;
+					while( (++j < mnCharCount) && !mpCharWidths[j] );
+					aSubPortion.mnEndCharPos = mnMinCharPos + j;
+					// emit current sub-portion
+					maSubPortions.push_back( aSubPortion );
+					// prepare next sub-portion
+					aSubPortion.mnMinCharPos = aSubPortion.mnEndCharPos;
+					aSubPortion.mnXOffset = nNextXOffset;
+				}
+			}
+
+			// emit the remaining sub-portion
+			if( !maSubPortions.empty() )
+			{
+				aSubPortion.mnEndCharPos = mnEndCharPos;
+				if( aSubPortion.mnEndCharPos != aSubPortion.mnMinCharPos )
+					maSubPortions.push_back( aSubPortion );
+			}
+		}
+
+		// override layouted charwidths with requested charwidths
+		for( int n = 0; n < mnCharCount; ++n )
+			mpCharWidths[ n ] = pArgs->mpDXArray[ n ];
+	}
+
+	// release the ATSU layout records
 	ATSUDirectReleaseLayoutDataArrayPtr(NULL,
 		kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void**)&pALR );
 
 }
 #endif
 // =======================================================================
-#if 0
-// helper functions for ATSLayout::GetGlyphOutlines()
-OSStatus MyATSCubicMoveToCallback( const Float32Point *pt1, 
-   void* pData )
-{
-	PolyArgs& rA = *reinterpret_cast<PolyArgs*>(pData);
-	// MoveTo implies a new polygon => finish old polygon first
-	rA.ClosePolygon();
-	rA.AddPoint( *pt1, POLY_NORMAL );
-}
-
-OSStatus MyATSCubicLineToCallback( const Float32Point* pt1,
-	void* pData )
-{
-	PolyArgs& rA = *reinterpret_cast<PolyArgs*>(pData);
-	rA.AddPoint( *pt1, POLY_NORMAL );
-}
-
-OSStatus MyATSCubicCurveToCallback( const Float32Point* pt1,
-	const Float32Point* pt2, const Float32Point* pt3, void* pData )
-{
-	PolyArgs& rA = *reinterpret_cast<PolyArgs*>(pData);
-	rA.AddPoint( *pt1, POLY_CONTROL );
-	rA.AddPoint( *pt2, POLY_CONTROL );
-	rA.AddPoint( *pt3, POLY_NORMAL );
-}
-
-OSStatus MyATSCubicClosePathCallback (
-   void *pData )
-{
-	PolyArgs& rA = *reinterpret_cast<PolyArgs*>(pData);
-	rA.ClosePolygon();
-}
-#endif
-// -----------------------------------------------------------------------
-
-bool ATSLayout::GetGlyphOutlines( SalGraphics&, PolyPolyVector& rPPV ) const
-{
-    return false;
-	
-    /*
-	rPPV.clear();
-
-	if( !InitGIA() )
-		return false;
-
-	rPPV.resize( mpGIA->numGlyphs );
-	PolyArgs aPolyArgs;
-	const ATSUGlyphInfo* pG = mpGIA->glyphs;
-	for( int i = 0; i < mpGIA->numGlyphs; ++i, ++pG )
-	{
-		// convert glyphid at glyphpos to outline
-		GlyphID nGlyphId = pG->glyphID;
-		long nDeltaY = Float32ToInt( pG->deltaY );
-		aPolyArgs.Init( &rPPV[i], pG->screenX, nDeltaY );
-		OSStatus nStatus, nCBStatus;
-		nStatus = ATSUGlyphGetCubicPaths(
-			mrATSUStyle, nGlyphId,
-			MyATSCubicMoveToCallback, MyATSCubicLineToCallback,
-			MyATSCubicCurveToCallback, MyATSCubicClosePathCallback,
-			&aPolyArgs, &nCBStatus );
-
-		if( (nStatus != noErr) && (nCBStatus != noErr) )
-		{
-			fprintf(stderr,"ATSUCallback = %d,%d\n", nStatus, nCBStatus );
-			rPPV.resize( i );
-			break;
-		}
-	}
-
-	return true;
-     */
-}
-
-// -----------------------------------------------------------------------
 
 // glyph fallback is supported directly by Aqua
-// so MultiSalLayout-only methods can be dummy implementated
+// so methods used only by MultiSalLayout can be dummy implementated
+bool ATSLayout::GetGlyphOutlines( SalGraphics&, PolyPolyVector& rPPV ) const { return false; }
 void ATSLayout::InitFont() {}
 void ATSLayout::MoveGlyph( int /*nStart*/, long /*nNewXPos*/ ) {}
 void ATSLayout::DropGlyph( int /*nStart*/ ) {}

File vcl/aqua/source/window/salframeview.mm

 #include "salframe.h"
 #include "salframeview.h"
 #include "aqua11yfactory.h"
+#include <sal/alloca.h>
 #include "vcl/window.hxx"
 
 #include "vcl/svapp.hxx"
     { KEY_D, NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask }
 };
 
+static AquaSalFrame* getMouseContainerFrame()
+{
+    int nWindows = 0;
+    NSCountWindows( &nWindows );
+    int* pWindows = (int*)alloca( nWindows * sizeof(int) );
+    // note: NSWindowList is supposed to be in z-order front to back
+    NSWindowList( nWindows, pWindows );
+    AquaSalFrame* pDispatchFrame = NULL;
+    for(int i = 0; i < nWindows && ! pDispatchFrame; i++ )
+    {
+        NSWindow* pWin = [NSApp windowWithWindowNumber: pWindows[i]];
+        if( pWin && [pWin isMemberOfClass: [SalFrameWindow class]] && [(SalFrameWindow*)pWin containsMouse] )
+            pDispatchFrame = [(SalFrameWindow*)pWin getSalFrame];
+    }
+    return pDispatchFrame;
+}
+
 @implementation SalFrameWindow
 -(id)initWithSalFrame: (AquaSalFrame*)pFrame
 {
         {
             // no, it is not
             // now we need to find the one it may be in
-            // use NSApp to check windows in ZOrder whether they contain the mouse pointer
-            NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES];
-            if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] )
-                pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame];
+            /* #i93756# we ant to get enumerate the application windows in z-order
+               to check if any contains the mouse. This could be elegantly done with this
+               code:
+
+               // use NSApp to check windows in ZOrder whether they contain the mouse pointer
+               NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES];
+               if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] )
+                   pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame];
+               
+               However if a non SalFrameWindow is on screen (like e.g. the file dialog)
+               it can be hit with the containsMouse selector, which it doesn't support.
+               Sadly NSApplication:makeWindowsPerform does not check (for performance reasons
+               I assume) whether a window supports a selector before sending it. 
+            */
+            AquaSalFrame* pMouseFrame = getMouseContainerFrame();
+            if( pMouseFrame )
+                pDispatchFrame = pMouseFrame;
         }
     }
     

File vcl/source/gdi/impprn.cxx

 	pQueuePage->mpMtf		= pPage;
 	pQueuePage->mnPage		= nPage;
 	pQueuePage->mbEndJob	= FALSE;
-	if ( bNewJobSetup )
+    // ensure that the first page has a valid setup, this is needed
+    // in GetPaperRanges (used in pullmodel)
+    // caution: this depends on mnCurPage in Printer being
+    // 0: not printing 1: after StartJob, 2 after first EndPage, 3+ at following EndPage calls
+	if ( bNewJobSetup || (nPage == 2 && ImplGetSVData()->maGDIData.mbPrinterPullModel) )
 		pQueuePage->mpSetup = new JobSetup( mpParent->GetJobSetup() );
     maQueue.push_back( pQueuePage );
 }

File vcl/source/gdi/pdfwriter_impl.cxx

 		appendLiteralString( (const sal_Char*)m_pEncryptionBuffer, nChars, rOutBuffer );
 	}
 	else
-		rOutBuffer.append( rInString.getStr(), nChars );
+        appendLiteralString( rInString.getStr(), nChars , rOutBuffer );
 	rOutBuffer.append( ")" );
 }
 
     return 0;
 }
 
-static OUString escapeStringLiteral( const OUString& rStr )
-{
-    OUStringBuffer aBuf( rStr.getLength()*2 );
-    const sal_Unicode* pUni = rStr.getStr();
-    int nLen = rStr.getLength();
-    for( ; nLen; nLen--, pUni++ )
-    {
-        switch( *pUni )
-        {
-            case sal_Unicode(')'):
-            case sal_Unicode('('):
-            case sal_Unicode('\\'):
-                aBuf.append( sal_Unicode( '\\' ) );
-            default:
-                aBuf.append( *pUni );
-                break;
-        }
-    }
-    return aBuf.makeStringAndClear();
-}
-
 sal_Int32 PDFWriterImpl::setLinkURL( sal_Int32 nLinkId, const OUString& rURL )
 {
     if( nLinkId < 0 || nLinkId >= (sal_Int32)m_aLinks.size() )
     if (m_xTrans.is())
         m_xTrans->parseStrict( aURL );
 
-    m_aLinks[ nLinkId ].m_aURL	= escapeStringLiteral( aURL.Complete );
+    m_aLinks[ nLinkId ].m_aURL	= aURL.Complete;
 
     return 0;
 }