diff options
Diffstat (limited to 'vcl')
111 files changed, 3392 insertions, 1742 deletions
diff --git a/vcl/aqua/inc/salbmp.h b/vcl/aqua/inc/salbmp.h index a4ea1bcaee49..1c427cce0cd5 100644 --- a/vcl/aqua/inc/salbmp.h +++ b/vcl/aqua/inc/salbmp.h @@ -36,7 +36,6 @@ #include "salconst.h" #include "vcl/salvd.hxx" #include "salcolorutils.hxx" -#include "salpixmaputils.hxx" #include "vcl/salbmp.hxx" #include "salgdi.h" #include "basebmp/bitmapdevice.hxx" diff --git a/vcl/aqua/inc/salpixmaputils.hxx b/vcl/aqua/inc/salpixmaputils.hxx deleted file mode 100755 index 18d00b9856a0..000000000000 --- a/vcl/aqua/inc/salpixmaputils.hxx +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _SV_SALPIXMAPUTILS_HXX -#define _SV_SALPIXMAPUTILS_HXX - -#include "premac.h" -#include <ApplicationServices/ApplicationServices.h> -#include "postmac.h" - -#include "tools/gen.hxx" -#include "vcl/salbtype.hxx" -#include "vcl/salgtype.hxx" -#include "salconst.h" -#include "salcolorutils.hxx" - -// ------------------------------------------------------------------ - -// Empty. Do we need this? - -// ------------------------------------------------------------------ - -#endif // _SV_SALPIXMAPUTILS_HXX diff --git a/vcl/aqua/source/dtrans/DataFlavorMapping.cxx b/vcl/aqua/source/dtrans/DataFlavorMapping.cxx index 9c88a88e7b6b..e0a95a532bf8 100644 --- a/vcl/aqua/source/dtrans/DataFlavorMapping.cxx +++ b/vcl/aqua/source/dtrans/DataFlavorMapping.cxx @@ -42,7 +42,7 @@ #include <stdio.h> #include <premac.h> -#include <QuickTime/QuickTime.h> +#include <Cocoa/Cocoa.h> #include <postmac.h> using namespace ::com::sun::star::datatransfer; @@ -129,6 +129,7 @@ namespace // private { { NSStringPboardType, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", CPPUTYPE_OUSTRING }, { NSRTFPboardType, "text/richtext", "Rich Text Format", CPPUTYPE_SEQINT8 }, + { NSTIFFPboardType, "image/bmp", "Windows Bitmap", CPPUTYPE_SEQINT8 }, { NSPICTPboardType, "image/bmp", "Windows Bitmap", CPPUTYPE_SEQINT8 }, { NSHTMLPboardType, "text/html", "Plain Html", CPPUTYPE_SEQINT8 }, { NSFilenamesPboardType, "application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", CPPUTYPE_SEQINT8 }, @@ -143,9 +144,6 @@ namespace // private { PBTYPE_EMF, FLAVOR_EMF, "Windows Enhanced MetaFile", CPPUTYPE_SEQINT8 }, { PBTYPE_SODX, FLAVOR_SODX, "Star Object Descriptor (XML)", CPPUTYPE_SEQINT8 }, { PBTYPE_DUMMY_INTERNAL, FLAVOR_DUMMY_INTERNAL, "internal data",CPPUTYPE_SEQINT8 } - // { PBTYPE_UT16, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", CPPUTYPE_OUSTRING } - // { kUTTypePICT, @"PICT", "image/x-macpict;windows_formatname=\"Mac Pict\"", "Mac Pict", CPPUTYPE_SEQINT8 } - // { kUTTypeHTML, @"HTML", "text/html", "Plain Html", CPPUTYPE_SEQINT8 } }; @@ -379,23 +377,26 @@ Any HTMLFormatDataProvider::getOOoData() class BMPDataProvider : public DataProviderBaseImpl { + NSBitmapImageFileType meImageType; public: - BMPDataProvider(const Any& data); + BMPDataProvider(const Any& data, NSBitmapImageFileType eImageType ); - BMPDataProvider(NSData* data); + BMPDataProvider(NSData* data, NSBitmapImageFileType eImageType); virtual NSData* getSystemData(); virtual Any getOOoData(); }; -BMPDataProvider::BMPDataProvider(const Any& data) : - DataProviderBaseImpl(data) +BMPDataProvider::BMPDataProvider(const Any& data, NSBitmapImageFileType eImageType) : + DataProviderBaseImpl(data), + meImageType( eImageType ) { } -BMPDataProvider::BMPDataProvider(NSData* data) : - DataProviderBaseImpl(data) +BMPDataProvider::BMPDataProvider(NSData* data, NSBitmapImageFileType eImageType) : + DataProviderBaseImpl(data), + meImageType( eImageType ) { } @@ -407,7 +408,7 @@ NSData* BMPDataProvider::getSystemData() Sequence<sal_Int8> pictData; NSData* sysData = NULL; - if (BMPtoPICT(bmpData, pictData)) + if (BMPToImage(bmpData, pictData, meImageType)) { sysData = [NSData dataWithBytes: pictData.getArray() length: pictData.getLength()]; } @@ -433,7 +434,7 @@ Any BMPDataProvider::getOOoData() Sequence<sal_Int8> bmpData; - if (PICTtoBMP(pictData, bmpData)) + if (ImageToBMP(pictData, bmpData, meImageType)) { oOOData = makeAny(bmpData); } @@ -555,6 +556,13 @@ NSString* DataFlavorMapper::openOfficeToSystemFlavor(const DataFlavor& oOOFlavor return sysFlavor; } +NSString* DataFlavorMapper::openOfficeImageToSystemFlavor(NSPasteboard* pPasteboard) const +{ + NSArray *supportedTypes = [NSArray arrayWithObjects: NSTIFFPboardType, NSPICTPboardType, nil]; + NSString *sysFlavor = [pPasteboard availableTypeFromArray:supportedTypes]; + return sysFlavor; +} + DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Reference<XTransferable> rTransferable) const { DataProviderPtr_t dp; @@ -573,7 +581,11 @@ DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Refe } else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) { - dp = DataProviderPtr_t(new BMPDataProvider(data)); + dp = DataProviderPtr_t(new BMPDataProvider(data, PICTImageFileType)); + } + else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) + { + dp = DataProviderPtr_t(new BMPDataProvider(data, NSTIFFFileType)); } else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) { @@ -618,7 +630,11 @@ DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor } else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) { - dp = DataProviderPtr_t(new BMPDataProvider(systemData)); + dp = DataProviderPtr_t(new BMPDataProvider(systemData, PICTImageFileType)); + } + else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) + { + dp = DataProviderPtr_t(new BMPDataProvider(systemData, NSTIFFFileType)); } else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) { @@ -655,11 +671,19 @@ NSArray* DataFlavorMapper::flavorSequenceToTypesArray(const com::sun::star::uno: for (sal_uInt32 i = 0; i < nFlavors; i++) { - NSString* str = openOfficeToSystemFlavor(flavors[i]); - - if (str != NULL) + if( flavors[i].MimeType.compareToAscii( "image/bmp", 9 ) == 0 ) { - [array addObject: str]; + [array addObject: NSTIFFPboardType]; + [array addObject: NSPICTPboardType]; + } + else + { + NSString* str = openOfficeToSystemFlavor(flavors[i]); + + if (str != NULL) + { + [array addObject: str]; + } } } diff --git a/vcl/aqua/source/dtrans/DataFlavorMapping.hxx b/vcl/aqua/source/dtrans/DataFlavorMapping.hxx index a1ebac6ab4a9..9847fcbd3987 100644 --- a/vcl/aqua/source/dtrans/DataFlavorMapping.hxx +++ b/vcl/aqua/source/dtrans/DataFlavorMapping.hxx @@ -89,6 +89,11 @@ public: */ NSString* openOfficeToSystemFlavor(const com::sun::star::datatransfer::DataFlavor& oooDataFlavor) const; + /* Select the best available image data type + If there is no suiteable mapping available NULL will + be returned. + */ + NSString* openOfficeImageToSystemFlavor(NSPasteboard* pPasteboard) const; /* Get a data provider which is able to provide the data 'rTransferable' offers in a format that can be put on to the system clipboard. diff --git a/vcl/aqua/source/dtrans/OSXTransferable.cxx b/vcl/aqua/source/dtrans/OSXTransferable.cxx index 7b596768d061..2e6b327de446 100644 --- a/vcl/aqua/source/dtrans/OSXTransferable.cxx +++ b/vcl/aqua/source/dtrans/OSXTransferable.cxx @@ -88,7 +88,10 @@ Any SAL_CALL OSXTransferable::getTransferData( const DataFlavor& aFlavor ) static_cast<XTransferable*>(this)); } - NSString* sysFormat = (NSString*)mDataFlavorMapper->openOfficeToSystemFlavor(aFlavor); + NSString* sysFormat = + (aFlavor.MimeType.compareToAscii( "image/bmp", 9 ) == 0) + ? mDataFlavorMapper->openOfficeImageToSystemFlavor( mPasteboard ) + : mDataFlavorMapper->openOfficeToSystemFlavor(aFlavor); DataProviderPtr_t dp; if ([sysFormat caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) diff --git a/vcl/aqua/source/dtrans/PictToBmpFlt.cxx b/vcl/aqua/source/dtrans/PictToBmpFlt.cxx index 0643efae33ca..1410fc2bd66d 100644 --- a/vcl/aqua/source/dtrans/PictToBmpFlt.cxx +++ b/vcl/aqua/source/dtrans/PictToBmpFlt.cxx @@ -1,22 +1,52 @@ -#include "PictToBmpFlt.hxx" +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OSXTransferable.hxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ /* This is a work-around to prevent 'deprecated' warning for 'KillPicture' API Hopefully we can get rid of this whole code again when the OOo PICT filter are good enough to be used see #i78953 thus this hack would vanish to again. */ +#include <premac.h> #include <AvailabilityMacros.h> #undef DEPRECATED_ATTRIBUTE #define DEPRECATED_ATTRIBUTE -#include <premac.h> #include <Carbon/Carbon.h> #include <QuickTime/QuickTime.h> #include <postmac.h> +#include "PictToBmpFlt.hxx" bool PICTtoBMP(com::sun::star::uno::Sequence<sal_Int8>& aPict, com::sun::star::uno::Sequence<sal_Int8>& aBmp) { + bool result = false; ComponentInstance bmpExporter; @@ -112,3 +142,60 @@ bool BMPtoPICT(com::sun::star::uno::Sequence<sal_Int8>& aBmp, return result; } + +bool ImageToBMP( com::sun::star::uno::Sequence<sal_Int8>& aPict, + com::sun::star::uno::Sequence<sal_Int8>& aBmp, + NSBitmapImageFileType eInFormat) +{ + if( eInFormat == PICTImageFileType ) + return PICTtoBMP( aPict, aBmp ); + + bool bResult = false; + + NSData* pData = [NSData dataWithBytesNoCopy: (void*)aPict.getConstArray() length: aPict.getLength() freeWhenDone: 0]; + if( pData ) + { + NSBitmapImageRep* pRep = [NSBitmapImageRep imageRepWithData: pData]; + if( pRep ) + { + NSData* pOut = [pRep representationUsingType: NSBMPFileType properties: nil]; + if( pOut ) + { + aBmp.realloc( [pOut length] ); + [pOut getBytes: aBmp.getArray() length: aBmp.getLength()]; + bResult = (aBmp.getLength() != 0); + } + } + } + + return bResult; +} + +bool BMPToImage( com::sun::star::uno::Sequence<sal_Int8>& aBmp, + com::sun::star::uno::Sequence<sal_Int8>& aPict, + NSBitmapImageFileType eOutFormat + ) +{ + if( eOutFormat == PICTImageFileType ) + return BMPtoPICT( aBmp, aPict ); + + bool bResult = false; + + NSData* pData = [NSData dataWithBytesNoCopy: const_cast<sal_Int8*>(aBmp.getConstArray()) length: aBmp.getLength() freeWhenDone: 0]; + if( pData ) + { + NSBitmapImageRep* pRep = [NSBitmapImageRep imageRepWithData: pData]; + if( pRep ) + { + NSData* pOut = [pRep representationUsingType: eOutFormat properties: nil]; + if( pOut ) + { + aPict.realloc( [pOut length] ); + [pOut getBytes: aPict.getArray() length: aPict.getLength()]; + bResult = (aPict.getLength() != 0); + } + } + } + + return bResult; +} diff --git a/vcl/aqua/source/dtrans/PictToBmpFlt.hxx b/vcl/aqua/source/dtrans/PictToBmpFlt.hxx index 29e9c535546f..12a73452ad7b 100644 --- a/vcl/aqua/source/dtrans/PictToBmpFlt.hxx +++ b/vcl/aqua/source/dtrans/PictToBmpFlt.hxx @@ -3,6 +3,10 @@ #include <com/sun/star/uno/Sequence.hxx> +#include <premac.h> +#include <Cocoa/Cocoa.h> +#include <postmac.h> + /* Transform PICT into the a Window BMP. Returns true if the conversion was successful false @@ -19,4 +23,15 @@ bool PICTtoBMP(com::sun::star::uno::Sequence<sal_Int8>& aPict, bool BMPtoPICT(com::sun::star::uno::Sequence<sal_Int8>& aBmp, com::sun::star::uno::Sequence<sal_Int8>& aPict); +#define PICTImageFileType ((NSBitmapImageFileType)~0) + +bool ImageToBMP( com::sun::star::uno::Sequence<sal_Int8>& aPict, + com::sun::star::uno::Sequence<sal_Int8>& aBmp, + NSBitmapImageFileType eInFormat); + +bool BMPToImage( com::sun::star::uno::Sequence<sal_Int8>& aBmp, + com::sun::star::uno::Sequence<sal_Int8>& aPict, + NSBitmapImageFileType eOutFormat + ); + #endif diff --git a/vcl/aqua/source/dtrans/aqua_clipboard.cxx b/vcl/aqua/source/dtrans/aqua_clipboard.cxx index d3a4e9bc604c..52fb13e1e11f 100644 --- a/vcl/aqua/source/dtrans/aqua_clipboard.cxx +++ b/vcl/aqua/source/dtrans/aqua_clipboard.cxx @@ -189,6 +189,10 @@ void SAL_CALL AquaClipboard::setContents(const Reference<XTransferable>& xTransf const Reference<XClipboardOwner>& xClipboardOwner) throw( RuntimeException ) { + NSArray* types = xTransferable.is() ? + mpDataFlavorMapper->flavorSequenceToTypesArray(xTransferable->getTransferDataFlavors()) : + [NSArray array]; + ClearableMutexGuard aGuard(m_aMutex); Reference<XClipboardOwner> oldOwner(mXClipboardOwner); @@ -197,11 +201,10 @@ void SAL_CALL AquaClipboard::setContents(const Reference<XTransferable>& xTransf Reference<XTransferable> oldContent(mXClipboardContent); mXClipboardContent = xTransferable; - NSArray* types = mXClipboardContent.is() ? - mpDataFlavorMapper->flavorSequenceToTypesArray(mXClipboardContent->getTransferDataFlavors()) : - [NSArray array]; mPasteboardChangeCount = [mPasteboard declareTypes: types owner: mEventListener]; + aGuard.clear(); + // if we are already the owner of the clipboard // then fire lost ownership event if (oldOwner.is()) @@ -253,7 +256,7 @@ void SAL_CALL AquaClipboard::removeClipboardListener(const Reference< XClipboard void AquaClipboard::applicationDidBecomeActive(NSNotification* aNotification) { - MutexGuard aGuard(m_aMutex); + ClearableMutexGuard aGuard(m_aMutex); int currentPboardChgCount = [mPasteboard changeCount]; @@ -270,6 +273,8 @@ void AquaClipboard::applicationDidBecomeActive(NSNotification* aNotification) Reference<XTransferable> oldContent(mXClipboardContent); mXClipboardContent = Reference<XTransferable>(); + aGuard.clear(); + if (oldOwner.is()) { fireLostClipboardOwnershipEvent(oldOwner, oldContent); diff --git a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm index 74c66ab1401d..d00fc9a6cd0e 100644 --- a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm +++ b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm @@ -318,6 +318,12 @@ class ControllerProperties double fScaleX = double(aLogicSize.Width())/double(aPageSize.aSize.Width()); double fScaleY = double(aLogicSize.Height())/double(aPageSize.aSize.Height()); double fScale = (fScaleX < fScaleY) ? fScaleX : fScaleY; + // #i104784# if we render the page too small then rounding issues result in + // layout artifacts looking really bad. So scale the page unto a device that is not + // full page size but not too small either. This also results in much better visual + // quality of the preview, e.g. when its height approaches the number of text lines + if( fScale < 0.1 ) + fScale = 0.1; aMtf.WindStart(); aMtf.Scale( fScale, fScale ); aMtf.WindStart(); @@ -358,9 +364,10 @@ class ControllerProperties NSSize aMargins = [mpPreviewBox contentViewMargins]; aPreviewFrame.origin.x = 0; aPreviewFrame.origin.y = 34; + aPreviewFrame.size.width -= 2*(aMargins.width+1); aPreviewFrame.size.height -= 61; mpPreview = [[NSImageView alloc] initWithFrame: aPreviewFrame]; - [mpPreview setImageScaling: NSScaleNone]; + [mpPreview setImageScaling: NSScaleProportionally]; [mpPreview setImageAlignment: NSImageAlignCenter]; [mpPreview setImageFrameStyle: NSImageFrameNone]; [mpPreviewBox addSubview: [mpPreview autorelease]]; diff --git a/vcl/aqua/source/gdi/makefile.mk b/vcl/aqua/source/gdi/makefile.mk index 6cf1d498cce2..2aea58e49250 100644 --- a/vcl/aqua/source/gdi/makefile.mk +++ b/vcl/aqua/source/gdi/makefile.mk @@ -49,7 +49,6 @@ dummy: SLOFILES= $(SLO)$/salmathutils.obj \ $(SLO)$/salcolorutils.obj \ - $(SLO)$/salpixmaputils.obj \ $(SLO)$/salgdiutils.obj \ $(SLO)$/salnativewidgets.obj \ $(SLO)$/salatsuifontutils.obj \ diff --git a/vcl/aqua/source/gdi/salatsuifontutils.cxx b/vcl/aqua/source/gdi/salatsuifontutils.cxx index 1566f0961f54..8281c41ceeab 100644 --- a/vcl/aqua/source/gdi/salatsuifontutils.cxx +++ b/vcl/aqua/source/gdi/salatsuifontutils.cxx @@ -217,9 +217,6 @@ static bool GetDevFontAttributes( ATSUFontID nFontID, ImplDevFontAttributes& rDF // all scalable fonts on this platform are subsettable rDFA.mbSubsettable = true; rDFA.mbEmbeddable = false; - // TODO: these members are needed only for our X11 platform targets - rDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - rDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; // prepare iterating over all name strings of the font ItemCount nFontNameCount = 0; diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index a54a7fad7ac5..38fb068bb353 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -1095,7 +1095,8 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap DBG_ASSERT( pSrc->mxLayer!=NULL, "AquaSalGraphics::copyBits() from non-layered graphics" ); const CGPoint aDstPoint = { +pPosAry->mnDestX - pPosAry->mnSrcX, pPosAry->mnDestY - pPosAry->mnSrcY }; - if( !mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth ) // workaround a Quartz crasher + if( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth && pPosAry->mnSrcHeight == pPosAry->mnDestHeight) && + (!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher { // in XOR mode the drawing context is redirected to the XOR mask // if source and target are identical then copyBits() paints onto the target context though diff --git a/vcl/aqua/source/gdi/salnativewidgets.cxx b/vcl/aqua/source/gdi/salnativewidgets.cxx index 3baa38320075..b4b843eaca58 100644 --- a/vcl/aqua/source/gdi/salnativewidgets.cxx +++ b/vcl/aqua/source/gdi/salnativewidgets.cxx @@ -267,6 +267,11 @@ BOOL AquaSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart n return true; break; + case CTRL_SLIDER: + if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) + return true; + break; + case CTRL_EDITBOX: if( nPart == PART_ENTIRE_CONTROL || nPart == HAS_BACKGROUND_TEXTURE ) @@ -561,7 +566,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, // the Aqua grey theme when the item is selected is drawn here. aMenuItemDrawInfo.itemType = kThemeMenuItemPlain; - if ((nPart == PART_MENU_ITEM )) + if ((nPart == PART_MENU_ITEM ) && (nState & CTRL_STATE_SELECTED)) { // the blue theme when the item is selected is drawn here. aMenuItemDrawInfo.state = kThemeMenuSelected; @@ -785,6 +790,36 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, } break; + case CTRL_SLIDER: + { + SliderValue* pSLVal = (SliderValue*)aValue.getOptionalVal(); + + HIThemeTrackDrawInfo aTrackDraw; + aTrackDraw.kind = kThemeSliderMedium; + if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) + { + aTrackDraw.bounds = rc; + aTrackDraw.min = pSLVal->mnMin; + aTrackDraw.max = pSLVal->mnMax;; + aTrackDraw.value = pSLVal->mnCur; + aTrackDraw.reserved = 0; + aTrackDraw.attributes = kThemeTrackShowThumb; + if( nPart == PART_TRACK_HORZ_AREA ) + aTrackDraw.attributes |= kThemeTrackHorizontal; + aTrackDraw.enableState = (nState & CTRL_STATE_ENABLED) + ? kThemeTrackActive : kThemeTrackInactive; + + SliderTrackInfo aSlideInfo; + aSlideInfo.thumbDir = kThemeThumbUpward; + aSlideInfo.pressState = 0; + aTrackDraw.trackInfo.slider = aSlideInfo; + + HIThemeDrawTrack( &aTrackDraw, NULL, mrContext, kHIThemeOrientationNormal ); + bOK = true; + } + } + break; + case CTRL_SCROLLBAR: { ScrollbarValue* pScrollbarVal = (ScrollbarValue *)(aValue.getOptionalVal()); @@ -1223,18 +1258,38 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa { BOOL toReturn = FALSE; - short x = rControlRegion.GetBoundRect().Left(); - short y = rControlRegion.GetBoundRect().Top(); + Rectangle aCtrlBoundRect( rControlRegion.GetBoundRect() ); + short x = aCtrlBoundRect.Left(); + short y = aCtrlBoundRect.Top(); short w, h; sal_uInt8 nBorderCleanup = 0; switch (nType) { + case CTRL_SLIDER: + { + if( nPart == PART_THUMB_HORZ ) + { + w = 19; // taken from HIG + h = aCtrlBoundRect.GetHeight(); + rNativeBoundingRegion = rNativeContentRegion = Region( Rectangle( Point( x, y ), Size( w, h ) ) ); + toReturn = true; + } + else if( nPart == PART_THUMB_VERT ) + { + w = aCtrlBoundRect.GetWidth(); + h = 18; // taken from HIG + rNativeBoundingRegion = rNativeContentRegion = Region( Rectangle( Point( x, y ), Size( w, h ) ) ); + toReturn = true; + } + } + break; + case CTRL_SCROLLBAR: { Rectangle aRect; - if( AquaGetScrollRect( /* m_nScreen */ nPart, rControlRegion.GetBoundRect(), aRect ) ) + if( AquaGetScrollRect( /* m_nScreen */ nPart, aCtrlBoundRect, aRect ) ) { toReturn = TRUE; rNativeBoundingRegion = aRect; @@ -1249,8 +1304,8 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa { if ( nType == CTRL_PUSHBUTTON ) { - w = rControlRegion.GetBoundRect().GetWidth(); - h = rControlRegion.GetBoundRect().GetHeight(); + w = aCtrlBoundRect.GetWidth(); + h = aCtrlBoundRect.GetHeight(); } else { @@ -1271,7 +1326,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa break; case CTRL_PROGRESS: { - Rectangle aRect( rControlRegion.GetBoundRect() ); + Rectangle aRect( aCtrlBoundRect ); if( aRect.GetHeight() < 16 ) aRect.Bottom() = aRect.Top() + 9; // values taken from HIG for medium progress else @@ -1284,7 +1339,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa case CTRL_INTROPROGRESS: { - Rectangle aRect( rControlRegion.GetBoundRect() ); + Rectangle aRect( aCtrlBoundRect ); aRect.Bottom() = aRect.Top() + INTRO_PROGRESS_HEIGHT; // values taken from HIG for medium progress rNativeBoundingRegion = aRect; rNativeContentRegion = aRect; @@ -1294,7 +1349,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa case CTRL_TAB_ITEM: - w = rControlRegion.GetBoundRect().GetWidth() + 2*TAB_TEXT_OFFSET - 2*VCL_TAB_TEXT_OFFSET; + w = aCtrlBoundRect.GetWidth() + 2*TAB_TEXT_OFFSET - 2*VCL_TAB_TEXT_OFFSET; #ifdef OLD_TAB_STYLE h = TAB_HEIGHT_NORMAL; @@ -1310,7 +1365,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa case CTRL_EDITBOX: { - w = rControlRegion.GetBoundRect().GetWidth(); + w = aCtrlBoundRect.GetWidth(); if( w < 3+2*FOCUS_RING_WIDTH ) w = 3+2*FOCUS_RING_WIDTH; h = TEXT_EDIT_HEIGHT_NORMAL; @@ -1326,7 +1381,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa { if( nPart == PART_ENTIRE_CONTROL ) { - w = rControlRegion.GetBoundRect().GetWidth(); + w = aCtrlBoundRect.GetWidth(); h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*FOCUS_RING_WIDTH, h ) ); @@ -1336,7 +1391,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa } else if( nPart == PART_BUTTON_DOWN ) { - w = rControlRegion.GetBoundRect().GetWidth(); + w = aCtrlBoundRect.GetWidth(); if( w < 3+2*FOCUS_RING_WIDTH ) w = 3+2*FOCUS_RING_WIDTH; h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height @@ -1352,7 +1407,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa } else if( nPart == PART_SUB_EDIT ) { - w = rControlRegion.GetBoundRect().GetWidth(); + w = aCtrlBoundRect.GetWidth(); h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height x += FOCUS_RING_WIDTH; @@ -1373,7 +1428,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa break; case CTRL_SPINBOX: if( nPart == PART_ENTIRE_CONTROL ) { - w = rControlRegion.GetBoundRect().GetWidth(); + w = aCtrlBoundRect.GetWidth(); if( w < 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH ) w = 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH; h = TEXT_EDIT_HEIGHT_NORMAL; @@ -1384,7 +1439,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa toReturn = TRUE; } else if( nPart == PART_SUB_EDIT ) { - w = rControlRegion.GetBoundRect().GetWidth() - SPIN_BUTTON_SPACE - SPIN_BUTTON_WIDTH; + w = aCtrlBoundRect.GetWidth() - SPIN_BUTTON_SPACE - SPIN_BUTTON_WIDTH; h = TEXT_EDIT_HEIGHT_NORMAL; x += 4; // add an offset for rounded borders y += 2; // don't draw into upper border @@ -1397,10 +1452,10 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa toReturn = TRUE; } else if( nPart == PART_BUTTON_UP ) { - //rControlRegion.GetBoundRect().GetWidth() contains the width of the full control + //aCtrlBoundRect.GetWidth() contains the width of the full control //ie the width of the textfield + button //x is the position of the left corner of the full control - x += rControlRegion.GetBoundRect().GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ; + x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ; y += FOCUS_RING_WIDTH - CLIP_FUZZ; w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ; h = SPIN_UPPER_BUTTON_HEIGHT + 2*CLIP_FUZZ; @@ -1411,7 +1466,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa toReturn = TRUE; } else if( nPart == PART_BUTTON_DOWN ) { - x += rControlRegion.GetBoundRect().GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ; + x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ; y += SPIN_UPPER_BUTTON_HEIGHT + FOCUS_RING_WIDTH - CLIP_FUZZ; w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ; h = SPIN_LOWER_BUTTON_HEIGHT + 2*CLIP_FUZZ; @@ -1428,7 +1483,7 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa if( ( nPart == PART_BORDER ) && !( nStyle & (FRAME_DRAW_MENU | FRAME_DRAW_WINDOWBORDER | FRAME_DRAW_BORDERWINDOWBORDER) ) ) { - Rectangle aRect = rControlRegion.GetBoundRect(); + Rectangle aRect(aCtrlBoundRect); if( nStyle & FRAME_DRAW_DOUBLEIN ) { aRect.Left() += 1; diff --git a/vcl/aqua/source/gdi/salpixmaputils.cxx b/vcl/aqua/source/gdi/salpixmaputils.cxx deleted file mode 100755 index b39120080b88..000000000000 --- a/vcl/aqua/source/gdi/salpixmaputils.cxx +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" - -#include "salpixmaputils.hxx" - -// ======================================================================= - -// ======================================================================= - diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx index cee243093ff3..1c0401f769b5 100644 --- a/vcl/aqua/source/gdi/salprn.cxx +++ b/vcl/aqua/source/gdi/salprn.cxx @@ -532,8 +532,6 @@ BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName, PrintAccessoryViewState aAccViewState; sal_Int32 nAllPages = 0; - aAccViewState.bNeedRestart = true; - // reset IsLastPage i_rController.setLastPage( sal_False ); @@ -549,111 +547,133 @@ BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName, if( ! i_rController.isShowDialogs() ) bShowProgressPanel = sal_False; + // possibly create one job for collated output + sal_Bool bSinglePrintJobs = sal_False; + beans::PropertyValue* pSingleValue = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) ); + if( pSingleValue ) + { + pSingleValue->Value >>= bSinglePrintJobs; + } + // FIXME: jobStarted() should be done after the print dialog has ended (if there is one) // how do I know when that might be ? i_rController.jobStarted(); - do - { - if( aAccViewState.bNeedRestart ) - { - mnCurPageRangeStart = 0; - mnCurPageRangeCount = 0; - nAllPages = i_rController.getFilteredPageCount(); - } - aAccViewState.bNeedRestart = false; - Size aCurSize( 21000, 29700 ); - if( nAllPages > 0 ) + int nCopies = i_rController.getPrinter()->GetCopyCount(); + int nJobs = 1; + if( bSinglePrintJobs ) + { + nJobs = nCopies; + nCopies = 1; + } + + for( int nCurJob = 0; nCurJob < nJobs; nCurJob++ ) + { + aAccViewState.bNeedRestart = true; + do { - mnCurPageRangeCount = 1; - aCurSize = getPageSize( i_rController, mnCurPageRangeStart ); - Size aNextSize( aCurSize ); + if( aAccViewState.bNeedRestart ) + { + mnCurPageRangeStart = 0; + mnCurPageRangeCount = 0; + nAllPages = i_rController.getFilteredPageCount(); + } - // print pages up to a different size - while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages ) + aAccViewState.bNeedRestart = false; + + Size aCurSize( 21000, 29700 ); + if( nAllPages > 0 ) { - aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount ); - if( aCurSize == aNextSize // same page size - || - (aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation - ) + mnCurPageRangeCount = 1; + aCurSize = getPageSize( i_rController, mnCurPageRangeStart ); + Size aNextSize( aCurSize ); + + // print pages up to a different size + while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages ) { - mnCurPageRangeCount++; + aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount ); + if( aCurSize == aNextSize // same page size + || + (aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation + ) + { + mnCurPageRangeCount++; + } + else + break; } - else - break; } - } - else - mnCurPageRangeCount = 0; - - // now for the current run - mnStartPageOffsetX = mnStartPageOffsetY = 0; - // setup the paper size and orientation - // do this on our associated Printer object, since that is - // out interface to the applications which occasionally rely on the paper - // information (e.g. brochure printing scales to the found paper size) - // also SetPaperSizeUser has the advantage that we can share a - // platform independent paper matching algorithm - boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); - pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); - pPrinter->SetPaperSizeUser( aCurSize, true ); - - // create view - NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this]; - - NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary]; - - // set filename - if( i_pFileName ) - { - [mpPrintInfo setJobDisposition: NSPrintSaveJob]; - NSString* pPath = CreateNSString( *i_pFileName ); - [pPrintDict setObject: pPath forKey: NSPrintSavePath]; - [pPath release]; - } + else + mnCurPageRangeCount = 0; + + // now for the current run + mnStartPageOffsetX = mnStartPageOffsetY = 0; + // setup the paper size and orientation + // do this on our associated Printer object, since that is + // out interface to the applications which occasionally rely on the paper + // information (e.g. brochure printing scales to the found paper size) + // also SetPaperSizeUser has the advantage that we can share a + // platform independent paper matching algorithm + boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); + pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); + pPrinter->SetPaperSizeUser( aCurSize, true ); + + // create view + NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this]; + + NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary]; + + // set filename + if( i_pFileName ) + { + [mpPrintInfo setJobDisposition: NSPrintSaveJob]; + NSString* pPath = CreateNSString( *i_pFileName ); + [pPrintDict setObject: pPath forKey: NSPrintSavePath]; + [pPath release]; + } - [pPrintDict setObject: [[NSNumber numberWithInt: (int)i_rController.getPrinter()->GetCopyCount()] autorelease] forKey: NSPrintCopies]; - [pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting]; - [pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage]; - // #i103253# weird: for some reason, autoreleasing the value below like the others above - // leads do a double free malloc error. Why this value should behave differently from all the others - // is a mystery. - [pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage]; + [pPrintDict setObject: [[NSNumber numberWithInt: nCopies] autorelease] forKey: NSPrintCopies]; + [pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting]; + [pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage]; + // #i103253# weird: for some reason, autoreleasing the value below like the others above + // leads do a double free malloc error. Why this value should behave differently from all the others + // is a mystery. + [pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage]; - // create print operation - NSPrintOperation* pPrintOperation = [NSPrintOperation printOperationWithView: pPrintView printInfo: mpPrintInfo]; + // create print operation + NSPrintOperation* pPrintOperation = [NSPrintOperation printOperationWithView: pPrintView printInfo: mpPrintInfo]; - if( pPrintOperation ) - { - NSObject* pReleaseAfterUse = nil; - bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() ); - [pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ]; - [pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO]; - - // set job title (since MacOSX 10.5) - if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] ) - [pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]]; - - if( bShowPanel && mnCurPageRangeStart == 0 ) // only the first range of pages gets the accesory view - pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState]; - - bSuccess = TRUE; - mbJob = true; - pInst->startedPrintJob(); - [pPrintOperation runOperation]; - pInst->endedPrintJob(); - bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame; - mbJob = false; - if( pReleaseAfterUse ) - [pReleaseAfterUse release]; - } + if( pPrintOperation ) + { + NSObject* pReleaseAfterUse = nil; + bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() ); + [pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ]; + [pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO]; + + // set job title (since MacOSX 10.5) + if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] ) + [pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]]; + + if( bShowPanel && mnCurPageRangeStart == 0 && nCurJob == 0) // only the first range of pages (in the first job) gets the accesory view + pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState]; + + bSuccess = TRUE; + mbJob = true; + pInst->startedPrintJob(); + [pPrintOperation runOperation]; + pInst->endedPrintJob(); + bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame; + mbJob = false; + if( pReleaseAfterUse ) + [pReleaseAfterUse release]; + } - mnCurPageRangeStart += mnCurPageRangeCount; - mnCurPageRangeCount = 1; - } while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages ); + mnCurPageRangeStart += mnCurPageRangeCount; + mnCurPageRangeCount = 1; + } while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages ); + } // inform application that it can release its data // this is awkward, but the XRenderable interface has no method for this, diff --git a/vcl/inc/postgraphitestl.h b/vcl/inc/postgraphitestl.h deleted file mode 100644 index 736aa248b7ff..000000000000 --- a/vcl/inc/postgraphitestl.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef std_was_redefined_as_stlport -// put things back the way they were -# define std std_was_redefined_as_stlport -# undef _STLP_OUTERMOST_HEADER_ID -// force config to be re-read -# undef _STLP_NOTHROW_INHERENTLY -# undef _STLP_CONFIG_H -# include <stddef.h> -#endif diff --git a/vcl/inc/pregraphitestl.h b/vcl/inc/pregraphitestl.h deleted file mode 100644 index ece0af477113..000000000000 --- a/vcl/inc/pregraphitestl.h +++ /dev/null @@ -1,30 +0,0 @@ -#if defined(GRAPHITEADAPTSTL) && defined(std) -# include <ostream> -# include <istream> -# include <fstream> -# include <iostream> -# include <vector> -# include <algorithm> -# define std_was_redefined_as_stlport std -# undef std -# define _STLP_OUTERMOST_HEADER_ID 0xdeadbeaf -# pragma GCC visibility push(default) -# include _STLP_NATIVE_HEADER(exception_defines.h) -# include _STLP_NATIVE_HEADER(limits) -# include _STLP_NATIVE_HEADER(memory) -# include _STLP_NATIVE_HEADER(exception) -# include _STLP_NATIVE_HEADER(iosfwd) -# include _STLP_NATIVE_HEADER(algorithm) -# include _STLP_NATIVE_HEADER(string) -# include _STLP_NATIVE_HEADER(streambuf) -# include _STLP_NATIVE_HEADER(ios) -# include _STLP_NATIVE_HEADER(locale) -# include _STLP_NATIVE_HEADER(stdexcept) -# include _STLP_NATIVE_HEADER(ostream) -# include _STLP_NATIVE_HEADER(istream) -# include _STLP_NATIVE_HEADER(iostream) -# include _STLP_NATIVE_HEADER(vector) -# pragma GCC visibility pop -#endif -//sil_std resolves to the std that Graphite was built with -namespace sil_std = std; diff --git a/vcl/inc/vcl/decoview.hxx b/vcl/inc/vcl/decoview.hxx index a30f209c69fc..2412ceda8431 100644 --- a/vcl/inc/vcl/decoview.hxx +++ b/vcl/inc/vcl/decoview.hxx @@ -33,6 +33,7 @@ #include <vcl/symbol.hxx> class Rectangle; +class Point; class Color; class OutputDevice; @@ -103,6 +104,7 @@ public: USHORT nStyle = FRAME_HIGHLIGHT_OUT ); Rectangle DrawFrame( const Rectangle& rRect, USHORT nStyle = FRAME_DRAW_OUT ); Rectangle DrawButton( const Rectangle& rRect, USHORT nStyle ); + void DrawSeparator( const Point& rStart, const Point& rStop, bool bVertical = true ); }; #endif // _SV_DECOVIEW_HXX diff --git a/vcl/inc/vcl/fontmanager.hxx b/vcl/inc/vcl/fontmanager.hxx index 7e1733b49bca..33fece8d88e1 100644 --- a/vcl/inc/vcl/fontmanager.hxx +++ b/vcl/inc/vcl/fontmanager.hxx @@ -49,6 +49,7 @@ // forward declarations namespace utl { class MultiAtomProvider; } // see unotools/atom.hxx class FontSubsetInfo; +class ImplFontOptions; namespace psp { class PPDParser; // see ppdparser.hxx @@ -162,8 +163,6 @@ struct FastPrintFontInfo weight::type m_eWeight; pitch::type m_ePitch; rtl_TextEncoding m_aEncoding; - fcstatus::type m_eEmbeddedbitmap; - fcstatus::type m_eAntialias; bool m_bSubsettable; bool m_bEmbeddable; @@ -175,9 +174,7 @@ struct FastPrintFontInfo m_eWidth( width::Unknown ), m_eWeight( weight::Unknown ), m_ePitch( pitch::Unknown ), - m_aEncoding( RTL_TEXTENCODING_DONTKNOW ), - m_eEmbeddedbitmap( fcstatus::isunset ), - m_eAntialias( fcstatus::isunset ) + m_aEncoding( RTL_TEXTENCODING_DONTKNOW ) {} }; @@ -294,9 +291,6 @@ class VCL_DLLPUBLIC PrintFontManager bool m_bHaveVerticalSubstitutedGlyphs; bool m_bUserOverride; - fcstatus::type m_eEmbeddedbitmap; - fcstatus::type m_eAntialias; - std::map< sal_Unicode, sal_Int32 > m_aEncodingVector; std::map< sal_Unicode, rtl::OString > m_aNonEncoded; @@ -443,7 +437,7 @@ class VCL_DLLPUBLIC PrintFontManager false else (e.g. no libfontconfig found) */ bool initFontconfig(); - int countFontconfigFonts(); + int countFontconfigFonts( std::hash_map<rtl::OString, int, rtl::OStringHash>& o_rVisitedPaths ); /* deinitialize fontconfig */ void deinitFontconfig(); @@ -736,10 +730,11 @@ public: false else */ bool matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale ); + bool getFontOptions( const FastPrintFontInfo&, int nSize, void (*subcallback)(void*), ImplFontOptions& rResult ) const; rtl::OUString Substitute( const rtl::OUString& rFontName, rtl::OUString& rMissingCodes, - const rtl::OString& rLangAttrib, italic::type eItalic, weight::type eWeight, - width::type eWidth, pitch::type ePitch) const; + const rtl::OString& rLangAttrib, italic::type& rItalic, weight::type& rWeight, + width::type& rWidth, pitch::type& rPitch) const; bool hasFontconfig() const { return m_bFontconfigSuccess; } int FreeTypeCharIndex( void *pFace, sal_uInt32 aChar ); diff --git a/vcl/inc/vcl/glyphcache.hxx b/vcl/inc/vcl/glyphcache.hxx index 8c7d6e41b168..fa3e99f2373f 100644 --- a/vcl/inc/vcl/glyphcache.hxx +++ b/vcl/inc/vcl/glyphcache.hxx @@ -39,6 +39,7 @@ class ServerFontLayoutEngine; class ServerFontLayout; class ExtraKernInfo; struct ImplKernPairData; +class ImplFontOptions; #include <tools/gen.hxx> #include <hash_map> @@ -59,8 +60,8 @@ class ServerFontLayout; class VCL_DLLPUBLIC GlyphCache { public: - GlyphCache( GlyphCachePeer& ); - ~GlyphCache(); + explicit GlyphCache( GlyphCachePeer& ); + /*virtual*/ ~GlyphCache(); static GlyphCache& GetInstance(); void LoadFonts(); @@ -74,6 +75,7 @@ public: ServerFont* CacheFont( const ImplFontSelectData& ); void UncacheFont( ServerFont& ); + void InvalidateAllGlyphs(); protected: GlyphCachePeer& mrPeer; @@ -96,7 +98,6 @@ private: struct IFSD_Hash{ size_t operator()( const ImplFontSelectData& ) const; }; typedef ::std::hash_map<ImplFontSelectData,ServerFont*,IFSD_Hash,IFSD_Equal > FontList; FontList maFontList; - ULONG mnMaxSize; // max overall cache size in bytes mutable ULONG mnBytesUsed; mutable long mnLruIndex; @@ -179,6 +180,7 @@ public: virtual bool TestFont() const { return true; } virtual void* GetFtFace() const { return 0; } virtual int GetLoadFlags() const { return 0; } + virtual void SetFontOptions( const ImplFontOptions&) {} virtual bool NeedsArtificialBold() const { return false; } virtual bool NeedsArtificialItalic() const { return false; } @@ -208,7 +210,7 @@ public: protected: friend class GlyphCache; friend class ServerFontLayout; - ServerFont( const ImplFontSelectData& ); + explicit ServerFont( const ImplFontSelectData& ); virtual ~ServerFont(); void AddRef() const { ++mnRefCount; } diff --git a/vcl/inc/vcl/graphite_adaptors.hxx b/vcl/inc/vcl/graphite_adaptors.hxx index 0b5f88184ce4..43c2e37a5fb2 100644 --- a/vcl/inc/vcl/graphite_adaptors.hxx +++ b/vcl/inc/vcl/graphite_adaptors.hxx @@ -55,11 +55,11 @@ #include "vcl/dllapi.h" // Libraries -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> // Module type definitions and forward declarations. // @@ -119,7 +119,7 @@ public: const grutils::GrFeatureParser * features() const { return mpFeatures; }; private: - virtual void UniqueCacheInfo(sil_std::wstring &, bool &, bool &); + virtual void UniqueCacheInfo(ext_std::wstring &, bool &, bool &); FreetypeServerFont& mrFont; FontProperties maFontProperties; diff --git a/vcl/inc/vcl/graphite_features.hxx b/vcl/inc/vcl/graphite_features.hxx index 9f63a029eb5f..47f4c3a01e7f 100644 --- a/vcl/inc/vcl/graphite_features.hxx +++ b/vcl/inc/vcl/graphite_features.hxx @@ -29,11 +29,11 @@ // Parse a string of features specified as ; separated pairs. // e.g. // 1001=1&2002=2&fav1=0 -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/GrFeature.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> namespace grutils { diff --git a/vcl/inc/vcl/graphite_layout.hxx b/vcl/inc/vcl/graphite_layout.hxx index b3a3814e9ce6..1fbb11211ca0 100644 --- a/vcl/inc/vcl/graphite_layout.hxx +++ b/vcl/inc/vcl/graphite_layout.hxx @@ -40,13 +40,13 @@ #include <vector> #include <utility> // Libraries -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/GrConstants.h> #include <graphite/GrAppData.h> #include <graphite/SegmentAux.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> // Platform #include <vcl/sallayout.hxx> #include <vcl/dllapi.h> diff --git a/vcl/inc/vcl/impfont.hxx b/vcl/inc/vcl/impfont.hxx index d53785bc691a..6ce9f21500b5 100644 --- a/vcl/inc/vcl/impfont.hxx +++ b/vcl/inc/vcl/impfont.hxx @@ -133,6 +133,41 @@ public: bool operator==( const ImplFontMetric& ) const; }; +// ------------------ +// - ImplFontHints - +// ------------------ + +class ImplFontOptions +{ +public: + FontEmbeddedBitmap meEmbeddedBitmap; // whether the embedded bitmaps should be used + FontAntiAlias meAntiAlias; // whether the font should be antialiased + FontAutoHint meAutoHint; // whether the font should be autohinted + FontHinting meHinting; // whether the font should be hinted + FontHintStyle meHintStyle; // type of font hinting to be used +public: + ImplFontOptions() : + meEmbeddedBitmap(EMBEDDEDBITMAP_DONTKNOW), + meAntiAlias(ANTIALIAS_DONTKNOW), + meAutoHint(AUTOHINT_DONTKNOW), + meHinting(HINTING_DONTKNOW), + meHintStyle(HINT_SLIGHT) + {} + ImplFontOptions( FontEmbeddedBitmap eEmbeddedBitmap, FontAntiAlias eAntiAlias, + FontAutoHint eAutoHint, FontHinting eHinting, FontHintStyle eHintStyle) : + meEmbeddedBitmap(eEmbeddedBitmap), + meAntiAlias(eAntiAlias), + meAutoHint(eAutoHint), + meHinting(eHinting), + meHintStyle(eHintStyle) + {} + FontAutoHint GetUseAutoHint() const { return meAutoHint; } + FontHintStyle GetHintStyle() const { return meHintStyle; } + bool DontUseEmbeddedBitmaps() const { return meEmbeddedBitmap == EMBEDDEDBITMAP_FALSE; } + bool DontUseAntiAlias() const { return meAntiAlias == ANTIALIAS_FALSE; } + bool DontUseHinting() const { return (meHinting == HINTING_FALSE) || (GetHintStyle() == HINT_NONE); } +}; + // ------------------- // - ImplFontCharMap - // ------------------- diff --git a/vcl/inc/vcl/introwin.hxx b/vcl/inc/vcl/introwin.hxx index 5ffefe0950f8..40644019bc15 100644 --- a/vcl/inc/vcl/introwin.hxx +++ b/vcl/inc/vcl/introwin.hxx @@ -31,6 +31,7 @@ #include <vcl/sv.h> #include <vcl/dllapi.h> #include <vcl/wrkwin.hxx> +#include <vcl/bitmapex.hxx> // -------------- // - IntroWindow - @@ -46,6 +47,7 @@ public: ~IntroWindow(); void SetBackgroundBitmap( const Bitmap& rBitmap ); + void SetBackgroundBitmap( const BitmapEx& rBitmapEx ); }; #endif // _SV_INTROWIN_HXX diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 101a368b0586..70c1e6aa624d 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -77,6 +77,7 @@ class AlphaMask; class FontCharMap; class SalLayout; class ImplLayoutArgs; +class ImplFontAttributes; class VirtualDevice; namespace com { @@ -541,7 +542,6 @@ public: SAL_DLLPRIVATE static FontEmphasisMark ImplGetEmphasisMarkStyle( const Font& rFont ); SAL_DLLPRIVATE static BOOL ImplIsUnderlineAbove( const Font& ); - // tells whether this output device is RTL in an LTR UI or LTR in a RTL UI SAL_DLLPRIVATE bool ImplIsAntiparallel() const ; @@ -931,6 +931,10 @@ public: basegfx::B2DHomMatrix GetViewTransformation() const; basegfx::B2DHomMatrix GetInverseViewTransformation() const; + basegfx::B2DHomMatrix GetViewTransformation( const MapMode& rMapMode ) const; + basegfx::B2DHomMatrix GetInverseViewTransformation( const MapMode& rMapMode ) const; + + /** Set an offset in pixel This method offsets every drawing operation that converts its @@ -967,7 +971,9 @@ public: Size LogicToPixel( const Size& rLogicSize ) const; Rectangle LogicToPixel( const Rectangle& rLogicRect ) const; Polygon LogicToPixel( const Polygon& rLogicPoly ) const; + basegfx::B2DPolygon LogicToPixel( const basegfx::B2DPolygon& rLogicPolyPoly ) const; PolyPolygon LogicToPixel( const PolyPolygon& rLogicPolyPoly ) const; + basegfx::B2DPolyPolygon LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const; Region LogicToPixel( const Region& rLogicRegion )const; Point LogicToPixel( const Point& rLogicPt, const MapMode& rMapMode ) const; @@ -977,15 +983,21 @@ public: const MapMode& rMapMode ) const; Polygon LogicToPixel( const Polygon& rLogicPoly, const MapMode& rMapMode ) const; + basegfx::B2DPolygon LogicToPixel( const basegfx::B2DPolygon& rLogicPoly, + const MapMode& rMapMode ) const; PolyPolygon LogicToPixel( const PolyPolygon& rLogicPolyPoly, const MapMode& rMapMode ) const; + basegfx::B2DPolyPolygon LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly, + const MapMode& rMapMode ) const; Region LogicToPixel( const Region& rLogicRegion, const MapMode& rMapMode ) const; Point PixelToLogic( const Point& rDevicePt ) const; Size PixelToLogic( const Size& rDeviceSize ) const; Rectangle PixelToLogic( const Rectangle& rDeviceRect ) const; Polygon PixelToLogic( const Polygon& rDevicePoly ) const; + basegfx::B2DPolygon PixelToLogic( const basegfx::B2DPolygon& rDevicePoly ) const; PolyPolygon PixelToLogic( const PolyPolygon& rDevicePolyPoly ) const; + basegfx::B2DPolyPolygon PixelToLogic( const basegfx::B2DPolyPolygon& rDevicePolyPoly ) const; Region PixelToLogic( const Region& rDeviceRegion ) const; Point PixelToLogic( const Point& rDevicePt, const MapMode& rMapMode ) const; @@ -995,8 +1007,12 @@ public: const MapMode& rMapMode ) const; Polygon PixelToLogic( const Polygon& rDevicePoly, const MapMode& rMapMode ) const; + basegfx::B2DPolygon PixelToLogic( const basegfx::B2DPolygon& rDevicePoly, + const MapMode& rMapMode ) const; PolyPolygon PixelToLogic( const PolyPolygon& rDevicePolyPoly, const MapMode& rMapMode ) const; + basegfx::B2DPolyPolygon PixelToLogic( const basegfx::B2DPolyPolygon& rDevicePolyPoly, + const MapMode& rMapMode ) const; Region PixelToLogic( const Region& rDeviceRegion, const MapMode& rMapMode ) const; @@ -1026,6 +1042,13 @@ public: MapUnit eUnitSource, MapUnit eUnitDest ); + static basegfx::B2DPolygon LogicToLogic( const basegfx::B2DPolygon& rPoly, + const MapMode& rMapModeSource, + const MapMode& rMapModeDest ); + static basegfx::B2DPolyPolygon LogicToLogic( const basegfx::B2DPolyPolygon& rPolyPoly, + const MapMode& rMapModeSource, + const MapMode& rMapModeDest ); + Size GetOutputSizePixel() const { return Size( mnOutWidth, mnOutHeight ); } long GetOutputWidthPixel() const { return mnOutWidth; } diff --git a/vcl/inc/vcl/outfont.hxx b/vcl/inc/vcl/outfont.hxx index 87c20ebfd7f9..995fcd6009ff 100644 --- a/vcl/inc/vcl/outfont.hxx +++ b/vcl/inc/vcl/outfont.hxx @@ -94,8 +94,6 @@ public: // TODO: create matching interface class bool IsDeviceFont() const { return mbDevice; } bool IsEmbeddable() const { return mbEmbeddable; } bool IsSubsettable() const { return mbSubsettable; } - FontEmbeddedBitmap UseEmbeddedBitmap() const { return meEmbeddedBitmap; } - FontAntiAlias UseAntiAlias() const { return meAntiAlias; } public: // TODO: hide members behind accessor methods String maMapNames; // List of family name aliass separated with ';' @@ -104,8 +102,6 @@ public: // TODO: hide members behind accessor methods bool mbDevice; // true: built in font bool mbSubsettable; // true: a subset of the font can be created bool mbEmbeddable; // true: the font can be embedded - FontEmbeddedBitmap meEmbeddedBitmap; // whether the embedded bitmaps should be used - FontAntiAlias meAntiAlias; // whether the font should be antialiased }; // ---------------- @@ -339,15 +335,17 @@ public: // TODO: make data members private short mnOrientation; // text angle in 3600 system bool mbInit; // true if maMetric member is valid - void AddFallbackForUnicode( sal_UCS4, const String& rFontName ); - bool GetFallbackForUnicode( sal_UCS4, String* pFontName ) const; - void IgnoreFallbackForUnicode( sal_UCS4, const String& rFontName ); + void AddFallbackForUnicode( sal_UCS4, FontWeight eWeight, const String& rFontName ); + bool GetFallbackForUnicode( sal_UCS4, FontWeight eWeight, String* pFontName ) const; + void IgnoreFallbackForUnicode( sal_UCS4, FontWeight eWeight, const String& rFontName ); private: // cache of Unicode characters and replacement font names // TODO: a fallback map can be shared with many other ImplFontEntries // TODO: at least the ones which just differ in orientation, stretching or height - typedef ::std::hash_map<sal_UCS4,String> UnicodeFallbackList; + typedef ::std::pair<sal_UCS4,FontWeight> GFBCacheKey; + struct GFBCacheKey_Hash{ size_t operator()( const GFBCacheKey& ) const; }; + typedef ::std::hash_map<GFBCacheKey,String,GFBCacheKey_Hash> UnicodeFallbackList; UnicodeFallbackList* mpUnicodeFallbackList; }; diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx index b4bdcce5c1b8..419814e5ce97 100644 --- a/vcl/inc/vcl/pdfwriter.hxx +++ b/vcl/inc/vcl/pdfwriter.hxx @@ -47,7 +47,6 @@ class Font; class Point; class OutputDevice; -class Region; class MapMode; class Polygon; class LineInfo; @@ -199,7 +198,7 @@ public: enum WidgetType { - PushButton, RadioButton, CheckBox, Edit, ListBox, ComboBox + PushButton, RadioButton, CheckBox, Edit, ListBox, ComboBox, Hierarchy }; enum WidgetState @@ -671,10 +670,10 @@ The following structure describes the permissions used in PDF security void Pop(); void SetClipRegion(); - void SetClipRegion( const Region& rRegion ); + void SetClipRegion( const basegfx::B2DPolyPolygon& rRegion ); void MoveClipRegion( long nHorzMove, long nVertMove ); void IntersectClipRegion( const Rectangle& rRect ); - void IntersectClipRegion( const Region& rRegion ); + void IntersectClipRegion( const basegfx::B2DPolyPolygon& rRegion ); void SetAntialiasing( USHORT nMode = 0 ); diff --git a/vcl/inc/vcl/ppdparser.hxx b/vcl/inc/vcl/ppdparser.hxx index 12e8a16f6264..c7a1e09b81e4 100644 --- a/vcl/inc/vcl/ppdparser.hxx +++ b/vcl/inc/vcl/ppdparser.hxx @@ -221,7 +221,7 @@ public: bool isType42Capable() const { return m_bType42Capable; } ULONG getLanguageLevel() const { return m_nLanguageLevel; } - const String& getDefaultPaperDimension() const; + String getDefaultPaperDimension() const; void getDefaultPaperDimension( int& rWidth, int& rHeight ) const { getPaperDimension( getDefaultPaperDimension(), rWidth, rHeight ); } bool getPaperDimension( const String& rPaperName, @@ -230,12 +230,12 @@ public: // returns false if paper not found int getPaperDimensions() const { return m_pPaperDimensions ? m_pPaperDimensions->countValues() : 0; } - const String& getPaperDimension( int ) const; - const String& getPaperDimensionCommand( int ) const; - const String& getPaperDimensionCommand( const String & ) const; + String getPaperDimension( int ) const; + String getPaperDimensionCommand( int ) const; + String getPaperDimensionCommand( const String & ) const; // match the best paper for width and height - const String& matchPaper( int nWidth, int nHeight ) const; + String matchPaper( int nWidth, int nHeight ) const; bool getMargins( const String& rPaperName, int &rLeft, int& rRight, @@ -245,27 +245,27 @@ public: // values int pt - const String& getDefaultInputSlot() const; + String getDefaultInputSlot() const; int getInputSlots() const { return m_pInputSlots ? m_pInputSlots->countValues() : 0; } - const String& getSlot( int ) const; - const String& getSlotCommand( int ) const; - const String& getSlotCommand( const String& ) const; + String getSlot( int ) const; + String getSlotCommand( int ) const; + String getSlotCommand( const String& ) const; void getDefaultResolution( int& rXRes, int& rYRes ) const; int getResolutions() const; void getResolution( int, int& rXRes, int& rYRes ) const; - const String& getResolutionCommand( int nXRes, int nYRes ) const; + String getResolutionCommand( int nXRes, int nYRes ) const; // values in dpi void getResolutionFromString( const String&, int&, int& ) const; // helper function - const String& getDefaultDuplexType() const; + String getDefaultDuplexType() const; int getDuplexTypes() const { return m_pDuplexTypes ? m_pDuplexTypes->countValues() : 0; } - const String& getDuplex( int ) const; - const String& getDuplexCommand( int ) const; - const String& getDuplexCommand( const String& ) const; + String getDuplex( int ) const; + String getDuplexCommand( int ) const; + String getDuplexCommand( const String& ) const; int getFonts() const { return m_pFontList ? m_pFontList->countValues() : 0; } @@ -275,7 +275,7 @@ public: void getFontAttributes( const String&, String& rEncoding, String& rCharset ) const; - const String& getFont( int ) const; + String getFont( int ) const; rtl::OUString translateKey( const rtl::OUString& i_rKey, diff --git a/vcl/inc/vcl/prndlg.hxx b/vcl/inc/vcl/prndlg.hxx index bec612b65593..fdaf06c9854e 100644 --- a/vcl/inc/vcl/prndlg.hxx +++ b/vcl/inc/vcl/prndlg.hxx @@ -55,9 +55,12 @@ namespace vcl { GDIMetaFile maMtf; Size maOrigSize; + Size maPreviewSize; VirtualDevice maPageVDev; rtl::OUString maReplacementString; rtl::OUString maToolTipString; + + bool useHCColorReplacement() const; public: PrintPreviewWindow( Window* pParent, const ResId& ); virtual ~PrintPreviewWindow(); @@ -293,6 +296,7 @@ namespace vcl bool isPrintToFile(); int getCopyCount(); bool isCollate(); + bool isSingleJobs(); void previewForward(); void previewBackward(); @@ -321,6 +325,7 @@ namespace vcl bool isCanceled() const { return mbCanceled; } void setProgress( int i_nCurrent, int i_nMax = -1 ); void tick(); + void reset(); virtual void Paint( const Rectangle& ); }; diff --git a/vcl/inc/vcl/region.hxx b/vcl/inc/vcl/region.hxx index d4fe05ebe8a3..ddfba57ffdcf 100644 --- a/vcl/inc/vcl/region.hxx +++ b/vcl/inc/vcl/region.hxx @@ -113,7 +113,11 @@ public: BOOL HasPolyPolygon() const; PolyPolygon GetPolyPolygon() const; + // returns an empty polypolygon in case HasPolyPolygon is FALSE const basegfx::B2DPolyPolygon GetB2DPolyPolygon() const; + // returns a PolyPolygon either copied from the set PolyPolygon region + // or created from the constituent rectangles + basegfx::B2DPolyPolygon ConvertToB2DPolyPolygon(); ULONG GetRectCount() const; RegionHandle BeginEnumRects(); diff --git a/vcl/inc/vcl/salgdi.hxx b/vcl/inc/vcl/salgdi.hxx index f72c4df57481..02e9efbc0f94 100644 --- a/vcl/inc/vcl/salgdi.hxx +++ b/vcl/inc/vcl/salgdi.hxx @@ -234,9 +234,10 @@ public: void ReleaseFonts() { SetFont( NULL, 0 ); } // get the current font's metrics virtual void GetFontMetric( ImplFontMetricData* ) = 0; + // get kernign pairs of the current font // return only PairCount if (pKernPairs == NULL) - virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) = 0; + virtual ULONG GetKernPairs( ULONG nMaxPairCount, ImplKernPairData* ) = 0; // get the repertoire of the current font virtual ImplFontCharMap* GetImplFontCharMap() const = 0; // graphics must fill supplied font list diff --git a/vcl/inc/vcl/salnativewidgets.hxx b/vcl/inc/vcl/salnativewidgets.hxx index 8ce4c5c20615..8e98791d9f78 100644 --- a/vcl/inc/vcl/salnativewidgets.hxx +++ b/vcl/inc/vcl/salnativewidgets.hxx @@ -95,6 +95,8 @@ typedef sal_uInt32 ControlType; // all parts like slider, buttons #define CTRL_SCROLLBAR 60 +#define CTRL_SLIDER 65 + // Border around a group of related // items, perhaps also displaying // a label of identification @@ -289,6 +291,20 @@ class VCL_DLLPUBLIC ScrollbarValue inline ~ScrollbarValue() {}; }; +class VCL_DLLPUBLIC SliderValue +{ + public: + long mnMin; + long mnMax; + long mnCur; + Rectangle maThumbRect; + ControlState mnThumbState; + + SliderValue() : mnMin( 0 ), mnMax( 0 ), mnCur( 0 ), mnThumbState( 0 ) + {} + ~SliderValue() {} +}; + /* TabitemValue: * * Value container for tabitems. diff --git a/vcl/inc/vcl/settings.hxx b/vcl/inc/vcl/settings.hxx index e55c2a53345b..24fd30750501 100644 --- a/vcl/inc/vcl/settings.hxx +++ b/vcl/inc/vcl/settings.hxx @@ -437,6 +437,7 @@ private: ULONG mnPreferredSymbolsStyle; USHORT mnSkipDisabledInMenus; Wallpaper maWorkspaceGradient; + const void* mpFontOptions; }; #define DEFAULT_WORKSPACE_GRADIENT_START_COLOR Color( 0xa3, 0xae, 0xb8 ) @@ -754,6 +755,11 @@ public: BOOL GetSkipDisabledInMenus() const { return (BOOL) mpData->mnSkipDisabledInMenus; } + void SetCairoFontOptions( const void *pOptions ) + { CopyData(); mpData->mpFontOptions = pOptions; } + const void* GetCairoFontOptions() const + { return mpData->mpFontOptions; } + void SetAppFont( const Font& rFont ) { CopyData(); mpData->maAppFont = rFont; } const Font& GetAppFont() const diff --git a/vcl/inc/vcl/status.hxx b/vcl/inc/vcl/status.hxx index 4d41ee450dd7..810ecf230960 100644 --- a/vcl/inc/vcl/status.hxx +++ b/vcl/inc/vcl/status.hxx @@ -116,6 +116,7 @@ private: USHORT nOldPerc, USHORT nNewPerc ); SAL_DLLPRIVATE void ImplCalcProgressRect(); SAL_DLLPRIVATE Rectangle ImplGetItemRectPos( USHORT nPos ) const; + SAL_DLLPRIVATE USHORT ImplGetFirstVisiblePos() const; SAL_DLLPRIVATE void ImplCalcBorder(); public: diff --git a/vcl/inc/vcl/tabctrl.hxx b/vcl/inc/vcl/tabctrl.hxx index e7b87ff448d1..4c63b12f15fe 100644 --- a/vcl/inc/vcl/tabctrl.hxx +++ b/vcl/inc/vcl/tabctrl.hxx @@ -92,12 +92,12 @@ private: SAL_DLLPRIVATE void ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bool bLayout = false, bool bFirstInGroup = false, bool bLastInGroup = false, bool bIsCurrentItem = false ); SAL_DLLPRIVATE void ImplPaint( const Rectangle& rRect, bool bLayout = false ); SAL_DLLPRIVATE void ImplFreeLayoutData(); + SAL_DLLPRIVATE long ImplHandleKeyEvent( const KeyEvent& rKeyEvent ); + DECL_DLLPRIVATE_LINK( ImplScrollBtnHdl, PushButton* pBtn ); DECL_DLLPRIVATE_LINK( ImplListBoxSelectHdl, ListBox* ); + DECL_DLLPRIVATE_LINK( ImplWindowEventListener, VclSimpleEvent* ); -public: - // just for dialog control - SAL_DLLPRIVATE bool ImplHandleNotifyEvent( NotifyEvent& rEvt ); protected: using Window::ImplInit; diff --git a/vcl/inc/vcl/tabdlg.hxx b/vcl/inc/vcl/tabdlg.hxx index b5f1dc14de5d..35543bb6aac0 100644 --- a/vcl/inc/vcl/tabdlg.hxx +++ b/vcl/inc/vcl/tabdlg.hxx @@ -59,8 +59,6 @@ public: virtual void Resize(); virtual void StateChanged( StateChangedType nStateChange ); - SAL_DLLPRIVATE TabControl* ImplGetFirstTabControl() const; - void AdjustLayout(); void SetViewWindow( Window* pWindow ) { mpViewWindow = pWindow; } diff --git a/vcl/inc/vcl/vclenum.hxx b/vcl/inc/vcl/vclenum.hxx index ded36cc163f0..a34c633479e7 100644 --- a/vcl/inc/vcl/vclenum.hxx +++ b/vcl/inc/vcl/vclenum.hxx @@ -281,6 +281,27 @@ enum FontAntiAlias { ANTIALIAS_DONTKNOW, ANTIALIAS_FALSE, ANTIALIAS_TRUE }; #endif +#ifndef ENUM_FONTAUTOHINT_DECLARED +#define ENUM_FONTAUTOHINT_DECLARED + +enum FontAutoHint { AUTOHINT_DONTKNOW, AUTOHINT_FALSE, AUTOHINT_TRUE }; + +#endif + +#ifndef ENUM_FONTHINTING_DECLARED +#define ENUM_FONTHINTING_DECLARED + +enum FontHinting { HINTING_DONTKNOW, HINTING_FALSE, HINTING_TRUE }; + +#endif + +#ifndef ENUM_FONTHINTSTYLE_DECLARED +#define ENUM_FONTHINTSTYLE_DECLARED + +enum FontHintStyle { HINT_NONE, HINT_SLIGHT, HINT_MEDIUM, HINT_FULL }; + +#endif + // ------------------------------------------------------------ #ifndef ENUM_KEYFUNCTYPE_DECLARED diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx index b22a7d21f357..dd9a5b4a15ee 100644 --- a/vcl/source/app/dbggui.cxx +++ b/vcl/source/app/dbggui.cxx @@ -1783,8 +1783,6 @@ void DbgDialogTest( Window* pWindow ) } // ======================================================================= -void DbgPrintShell( const char* pLine ); - #ifndef WNT #define USE_VCL_MSGBOX #define COPY_BUTTON_ID 25 @@ -1963,27 +1961,6 @@ void DbgPrintWindow( const char* pLine ) bIn = FALSE; } -// ----------------------------------------------------------------------- - -void DbgPrintShell( const char* pLine ) -{ -#if defined( WNT ) - // TODO: Shouldn't this be a IsDebuggerPresent()? - if ( GetSystemMetrics( SM_DEBUG ) ) - { - strcpy( aDbgOutBuf, pLine ); - strcat( aDbgOutBuf, "\r\n" ); - OutputDebugString( aDbgOutBuf ); - return; - } - - DbgPrintWindow( pLine ); -#endif -#ifdef UNX - fprintf( stderr, "%s\n", pLine ); -#endif -} - // ======================================================================= #ifdef WNT @@ -1996,7 +1973,6 @@ void DbgGUIInit() { DbgSetPrintMsgBox( DbgPrintMsgBox ); DbgSetPrintWindow( DbgPrintWindow ); - DbgSetPrintShell( DbgPrintShell ); #ifdef WNT DbgSetTestSolarMutex( ImplDbgTestSolarMutex ); #endif @@ -2008,7 +1984,6 @@ void DbgGUIDeInit() { DbgSetPrintMsgBox( NULL ); DbgSetPrintWindow( NULL ); - DbgSetPrintShell( NULL ); #ifdef WNT DbgSetTestSolarMutex( NULL ); #endif diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx index 1aebe5913959..5ad3f6787461 100644..100755 --- a/vcl/source/app/settings.cxx +++ b/vcl/source/app/settings.cxx @@ -433,6 +433,7 @@ ImplStyleData::ImplStyleData() mnToolbarIconSize = STYLE_TOOLBAR_ICONSIZE_UNKNOWN; mnSymbolsStyle = STYLE_SYMBOLS_AUTO; mnPreferredSymbolsStyle = STYLE_SYMBOLS_AUTO; + mpFontOptions = NULL; SetStandardStyles(); } @@ -539,6 +540,7 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) : mnToolbarIconSize = rData.mnToolbarIconSize; mnSymbolsStyle = rData.mnSymbolsStyle; mnPreferredSymbolsStyle = rData.mnPreferredSymbolsStyle; + mpFontOptions = rData.mpFontOptions; } // ----------------------------------------------------------------------- diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx index 1cda2308aa9c..1f45b5902381 100644 --- a/vcl/source/control/button.cxx +++ b/vcl/source/control/button.cxx @@ -1191,7 +1191,10 @@ void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags else { Rectangle aSymbolRect; - ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1, nDrawFlags, + ULONG nImageSep = 1 + (pDev->GetTextHeight()-10)/2; + if( nImageSep < 1 ) + nImageSep = 1; + ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep, nDrawFlags, nTextStyle, IsSymbol() ? &aSymbolRect : NULL ); if ( IsSymbol() && ! bLayout ) @@ -1320,6 +1323,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) if( bNativeOK ) return; + bool bRollOver = (IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() )); if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == TRUE ) { PushButtonValue aPBVal; @@ -1334,7 +1338,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED; - if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) ) + if ( bRollOver ) nState |= CTRL_STATE_ROLLOVER; if( GetStyle() & WB_BEVELBUTTON ) @@ -1359,8 +1363,15 @@ void PushButton::ImplDrawPushButton( bool bLayout ) Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) ); aPBVal.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() ); - bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, - aControlValue, rtl::OUString()/*PushButton::GetText()*/ ); + if( ((nState & CTRL_STATE_ROLLOVER) || HasFocus()) || ! (GetStyle() & WB_FLATBUTTON) ) + { + bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, + aControlValue, rtl::OUString()/*PushButton::GetText()*/ ); + } + else + { + bNativeOK = true; + } // draw content using the same aInRect as non-native VCL would do ImplDrawPushButtonContent( this, @@ -1374,8 +1385,21 @@ void PushButton::ImplDrawPushButton( bool bLayout ) if ( bNativeOK == FALSE ) { // draw PushButtonFrame, aInRect has content size afterwards - if( ! bLayout ) - ImplDrawPushButtonFrame( this, aInRect, nButtonStyle ); + if( (GetStyle() & WB_FLATBUTTON) ) + { + Rectangle aTempRect( aInRect ); + if( ! bLayout && (bRollOver || HasFocus()) ) + ImplDrawPushButtonFrame( this, aTempRect, nButtonStyle ); + aInRect.Left() += 2; + aInRect.Top() += 2; + aInRect.Right() -= 2; + aInRect.Bottom() -= 2; + } + else + { + if( ! bLayout ) + ImplDrawPushButtonFrame( this, aInRect, nButtonStyle ); + } // draw content ImplDrawPushButtonContent( this, 0, aInRect, bLayout ); diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx index 4b83540c1aa1..37406293d7cf 100644 --- a/vcl/source/control/fixed.cxx +++ b/vcl/source/control/fixed.cxx @@ -496,16 +496,11 @@ void FixedLine::ImplDraw( bool bLayout ) { Size aOutSize = GetOutputSizePixel(); String aText = GetText(); - const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); WinBits nWinStyle = GetStyle(); MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL; String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL; - if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) - SetLineColor( Color( COL_BLACK ) ); - else - SetLineColor( rStyleSettings.GetShadowColor() ); - + DecorationView aDecoView( this ); if ( !aText.Len() || (nWinStyle & WB_VERT) ) { if( !pVector ) @@ -516,21 +511,12 @@ void FixedLine::ImplDraw( bool bLayout ) if ( nWinStyle & WB_VERT ) { nX = (aOutSize.Width()-1)/2; - DrawLine( Point( nX, 0 ), Point( nX, aOutSize.Height()-1 ) ); + aDecoView.DrawSeparator( Point( nX, 0 ), Point( nX, aOutSize.Height()-1 ) ); } else { nY = (aOutSize.Height()-1)/2; - DrawLine( Point( 0, nY ), Point( aOutSize.Width()-1, nY ) ); - } - - if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ) - { - SetLineColor( rStyleSettings.GetLightColor() ); - if ( nWinStyle & WB_VERT ) - DrawLine( Point( nX+1, 0 ), Point( nX+1, aOutSize.Height()-1 ) ); - else - DrawLine( Point( 0, nY+1 ), Point( aOutSize.Width()-1, nY+1 ) ); + aDecoView.DrawSeparator( Point( 0, nY ), Point( aOutSize.Width()-1, nY ), false ); } } } @@ -538,6 +524,7 @@ void FixedLine::ImplDraw( bool bLayout ) { USHORT nStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS; Rectangle aRect( 0, 0, aOutSize.Width(), aOutSize.Height() ); + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); if ( !IsEnabled() ) nStyle |= TEXT_DRAW_DISABLE; @@ -551,12 +538,7 @@ void FixedLine::ImplDraw( bool bLayout ) if( !pVector ) { long nTop = aRect.Top() + ((aRect.GetHeight()-1)/2); - DrawLine( Point( aRect.Right()+FIXEDLINE_TEXT_BORDER, nTop ), Point( aOutSize.Width()-1, nTop ) ); - if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ) - { - SetLineColor( rStyleSettings.GetLightColor() ); - DrawLine( Point( aRect.Right()+FIXEDLINE_TEXT_BORDER, nTop+1 ), Point( aOutSize.Width()-1, nTop+1 ) ); - } + aDecoView.DrawSeparator( Point( aRect.Right()+FIXEDLINE_TEXT_BORDER, nTop ), Point( aOutSize.Width()-1, nTop ), false ); } } } diff --git a/vcl/source/control/slider.cxx b/vcl/source/control/slider.cxx index 5e7e9709607f..2390a8e3e9a6 100644 --- a/vcl/source/control/slider.cxx +++ b/vcl/source/control/slider.cxx @@ -168,6 +168,7 @@ void Slider::ImplInitSettings() void Slider::ImplUpdateRects( BOOL bUpdate ) { Rectangle aOldThumbRect = maThumbRect; + bool bInvalidateAll = false; if ( mnThumbPixRange ) { @@ -193,6 +194,18 @@ void Slider::ImplUpdateRects( BOOL bUpdate ) } else maChannel2Rect.SetEmpty(); + + const Region aControlRegion( Rectangle( Point(0,0), Size( SLIDER_THUMB_SIZE, 10 ) ) ); + Region aThumbBounds, aThumbContent; + if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_HORZ, + aControlRegion, 0, ImplControlValue(), rtl::OUString(), + aThumbBounds, aThumbContent ) ) + { + Rectangle aRect( aThumbBounds.GetBoundRect() ); + maThumbRect.Left() = mnThumbPixPos - aRect.GetWidth()/2; + maThumbRect.Right() = maThumbRect.Left() + aRect.GetWidth() - 1; + bInvalidateAll = true; + } } else { @@ -216,6 +229,18 @@ void Slider::ImplUpdateRects( BOOL bUpdate ) } else maChannel2Rect.SetEmpty(); + + const Region aControlRegion( Rectangle( Point(0,0), Size( 10, SLIDER_THUMB_SIZE ) ) ); + Region aThumbBounds, aThumbContent; + if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_VERT, + aControlRegion, 0, ImplControlValue(), rtl::OUString(), + aThumbBounds, aThumbContent ) ) + { + Rectangle aRect( aThumbBounds.GetBoundRect() ); + maThumbRect.Top() = mnThumbPixPos - aRect.GetHeight()/2; + maThumbRect.Bottom() = maThumbRect.Top() + aRect.GetHeight() - 1; + bInvalidateAll = true; + } } } else @@ -229,17 +254,22 @@ void Slider::ImplUpdateRects( BOOL bUpdate ) { if ( aOldThumbRect != maThumbRect ) { - Region aInvalidRegion( aOldThumbRect ); - aInvalidRegion.Union( maThumbRect ); - - if( !IsBackground() && GetParent() ) + if( bInvalidateAll ) + Invalidate(); + else { - const Point aPos( GetPosPixel() ); - aInvalidRegion.Move( aPos.X(), aPos.Y() ); - GetParent()->Invalidate( aInvalidRegion, INVALIDATE_TRANSPARENT | INVALIDATE_UPDATE ); + Region aInvalidRegion( aOldThumbRect ); + aInvalidRegion.Union( maThumbRect ); + + if( !IsBackground() && GetParent() ) + { + const Point aPos( GetPosPixel() ); + aInvalidRegion.Move( aPos.X(), aPos.Y() ); + GetParent()->Invalidate( aInvalidRegion, INVALIDATE_TRANSPARENT | INVALIDATE_UPDATE ); + } + else + Invalidate( aInvalidRegion ); } - else - Invalidate( aInvalidRegion ); } } } @@ -357,6 +387,29 @@ void Slider::ImplDraw( USHORT nDrawFlags ) if ( mbCalcSize ) ImplCalc( FALSE ); + ControlPart nPart = (GetStyle() & WB_HORZ) ? PART_TRACK_HORZ_AREA : PART_TRACK_VERT_AREA; + ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 ); + ControlState nState = ( IsEnabled() ? CTRL_STATE_ENABLED : 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED : 0 ); + SliderValue sldValue; + + sldValue.mnMin = mnMinRange; + sldValue.mnMax = mnMaxRange; + sldValue.mnCur = mnThumbPos; + sldValue.maThumbRect = maThumbRect; + + if( IsMouseOver() ) + { + if( maThumbRect.IsInside( GetPointerPosPixel() ) ) + sldValue.mnThumbState |= CTRL_STATE_ROLLOVER; + } + aControlValue.setOptionalVal( (void *)(&sldValue) ); + + const Region aCtrlRegion( Rectangle( Point(0,0), GetOutputSizePixel() ) ); + bool bNativeOK = DrawNativeControl( CTRL_SLIDER, nPart, + aCtrlRegion, nState, aControlValue, rtl::OUString() ); + if( bNativeOK ) + return; + if ( (nDrawFlags & SLIDER_DRAW_CHANNEL1) && !maChannel1Rect.IsEmpty() ) { long nRectSize; diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx index 5c08cdb8a36b..741267044829 100644 --- a/vcl/source/control/tabctrl.cxx +++ b/vcl/source/control/tabctrl.cxx @@ -174,6 +174,9 @@ void TabControl::ImplInit( Window* pParent, WinBits nStyle ) // otherwise they will paint with a wrong background if( IsNativeControlSupported(CTRL_TAB_PANE, PART_ENTIRE_CONTROL) ) EnableChildTransparentMode( TRUE ); + + if ( pParent->IsDialog() ) + pParent->AddChildEventListener( LINK( this, TabControl, ImplWindowEventListener ) ); } // ----------------------------------------------------------------- @@ -288,6 +291,9 @@ void TabControl::ImplLoadRes( const ResId& rResId ) TabControl::~TabControl() { + if ( GetParent()->IsDialog() ) + GetParent()->RemoveChildEventListener( LINK( this, TabControl, ImplWindowEventListener ) ); + ImplFreeLayoutData(); // TabCtrl-Daten loeschen @@ -1070,6 +1076,42 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo // ----------------------------------------------------------------------- +long TabControl::ImplHandleKeyEvent( const KeyEvent& rKeyEvent ) +{ + long nRet = 0; + + if ( GetPageCount() > 1 ) + { + KeyCode aKeyCode = rKeyEvent.GetKeyCode(); + USHORT nKeyCode = aKeyCode.GetCode(); + + if ( aKeyCode.IsMod1() ) + { + if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) ) + { + if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) ) + { + ImplActivateTabPage( FALSE ); + nRet = 1; + } + } + else + { + if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) ) + { + ImplActivateTabPage( TRUE ); + nRet = 1; + } + } + } + } + + return nRet; +} + + +// ----------------------------------------------------------------------- + IMPL_LINK( TabControl, ImplScrollBtnHdl, PushButton*, EMPTYARG ) { ImplSetScrollBtnsState(); @@ -1086,6 +1128,24 @@ IMPL_LINK( TabControl, ImplListBoxSelectHdl, ListBox*, EMPTYARG ) // ----------------------------------------------------------------------- +IMPL_LINK( TabControl, ImplWindowEventListener, VclSimpleEvent*, pEvent ) +{ + if ( pEvent && pEvent->ISA( VclWindowEvent ) && (pEvent->GetId() == VCLEVENT_WINDOW_KEYINPUT) ) + { + VclWindowEvent* pWindowEvent = static_cast< VclWindowEvent* >(pEvent); + // Do not handle events from TabControl or it's children, which is done in Notify(), where the events can be consumed. + if ( !IsWindowOrChild( pWindowEvent->GetWindow() ) ) + { + KeyEvent* pKeyEvent = static_cast< KeyEvent* >(pWindowEvent->GetData()); + ImplHandleKeyEvent( *pKeyEvent ); + } + } + return 0; +} + + +// ----------------------------------------------------------------------- + void TabControl::MouseButtonDown( const MouseEvent& rMEvt ) { if( mpTabCtrlData->mpListBox == NULL ) @@ -1655,44 +1715,14 @@ long TabControl::PreNotify( NotifyEvent& rNEvt ) // ----------------------------------------------------------------------- -bool TabControl::ImplHandleNotifyEvent( NotifyEvent& rNEvt ) -{ - if ( (rNEvt.GetType() == EVENT_KEYINPUT) && (GetPageCount() > 1) ) - { - const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); - KeyCode aKeyCode = pKEvt->GetKeyCode(); - USHORT nKeyCode = aKeyCode.GetCode(); - - if ( aKeyCode.IsMod1() ) - { - if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) ) - { - if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) ) - { - ImplActivateTabPage( FALSE ); - return TRUE; - } - } - else - { - if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) ) - { - ImplActivateTabPage( TRUE ); - return TRUE; - } - } - } - } - return false; -} - - -// ----------------------------------------------------------------------- - long TabControl::Notify( NotifyEvent& rNEvt ) { + long nRet = 0; + + if ( rNEvt.GetType() == EVENT_KEYINPUT ) + nRet = ImplHandleKeyEvent( *rNEvt.GetKeyEvent() ); - return ImplHandleNotifyEvent( rNEvt ) ? TRUE : Control::Notify( rNEvt ); + return nRet ? nRet : Control::Notify( rNEvt ); } // ----------------------------------------------------------------------- diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx index 39964f635c9c..9884e7016fee 100644 --- a/vcl/source/fontsubset/cff.cxx +++ b/vcl/source/fontsubset/cff.cxx @@ -391,11 +391,9 @@ public: // used by charstring converter void setCharStringType( int); void fakeLocalSubrCount( int nLocalSubrs ) { maCffLocal[0].mnLocalSubrCount=nLocalSubrs;} - void readCharString( const U8* pTypeOps, int nTypeLen); protected: int convert2Type1Ops( CffLocal*, const U8* pType2Ops, int nType2Len, U8* pType1Ops); private: - void readTypeOp( CffSubsetterContext&); void convertOneTypeOp( void); void convertOneTypeEsc( void); void callType2Subr( bool bGlobal, int nSubrNumber); @@ -431,7 +429,6 @@ private: int getGlyphSID( int nGlyphIndex) const; const char* getGlyphName( int nGlyphIndex); - void readTypeOp( void); void read2push( void); void pop2write( void); void writeType1Val( ValType); @@ -611,25 +608,6 @@ void CffSubsetterContext::setCharStringType( int nVal) // -------------------------------------------------------------------- -void CffSubsetterContext::readCharString( const U8* pTypeOps, int nTypeLen) -{ - mnStackIdx = 0; - mnHintSize = 0; - mnHorzHintSize = 0; - maCharWidth = -1; - - assert( nTypeLen >= 0); -// assert( nEnd <= getLength()); - mpReadPtr = pTypeOps; - mpReadEnd = mpReadPtr + nTypeLen; - // reset the execution context - while( mpReadPtr < mpReadEnd) - readTypeOp(); -//### assert( tellRel() == nEnd); -} - -// -------------------------------------------------------------------- - void CffSubsetterContext::readDictOp( void) { ValType nVal = 0; @@ -765,112 +743,6 @@ void CffSubsetterContext::readDictOp( void) // -------------------------------------------------------------------- -void CffSubsetterContext::readTypeOp( void) -{ - int nVal = 0; - const U8 c = *mpReadPtr; - if( (c <= 31) && (c != 28) ) { - const int nOpId = *(mpReadPtr++); - const char* pCmdName; - if( nOpId != 12) - pCmdName = mpCharStringOps[ nOpId]; - else { - const int nExtId = *(mpReadPtr++); - pCmdName = mpCharStringEscs[ nExtId]; - } - - if( !pCmdName ) - pCmdName = ".NULL"; - // handle typeop parameters - int nMinStack = -1, nMaxStack = -1; - switch( *pCmdName) { - default: fprintf( stderr, "unsupported TypeOp.type=\'%c\'\n", *pCmdName); break; - case '.': nMinStack = 0; nMaxStack = 999; break; - case '0': nMinStack = nMaxStack = 0; break; - case '1': nMinStack = nMaxStack = 1; break; - case '2': nMinStack = nMaxStack = 2; break; - case '4': nMinStack = nMaxStack = 4; break; - case '5': nMinStack = nMaxStack = 5; break; // not used for Type2 ops - case '6': nMinStack = nMaxStack = 6; break; - case '7': nMinStack = nMaxStack = 7; break; - case '9': nMinStack = nMaxStack = 9; break; - case 'f': nMinStack = nMaxStack = 11; break; - case 'F': nMinStack = nMaxStack = 13; break; - case 'A': nMinStack = 2; nMaxStack = 999; break; - case 'C': nMinStack = 6; nMaxStack = 999; break; - case 'E': nMinStack = 1; nMaxStack = 999; break; - case 'G': nMinStack = 1; nMaxStack = 999; // global subr - nVal = peekInt(); - // TODO global subr - break; - case 'L': // local subr - nMinStack = 1; nMaxStack = 999; - nVal = peekInt(); - // TODO local subr - break; - case 'I': // operands for "index" -#if 0 - nMinStack = nValStack[ nStackIdx-1]; - if( nMinStack < 0) nMinStack = 0; - nMinStack += 1; -#else - fprintf( stderr, "TODO: Iindex op\n"); -#endif - break; - case 'R': // operands for "rol" -#if 0 - nMinStack = nValStack[ nStackIdx-2]; -#else - fprintf( stderr, "TODO: Rrol op\n"); -#endif - case 'X': // operands for "return" - nMinStack = 0; - nMaxStack = /*### (!bInSubrs)? 0 :###*/999; - break; - case 'H': // "hstemhm" - case 'h': // "hstem" - addHints( false); - nMinStack = nMaxStack = 0; - break; - case 'V': // "vstemhm" - case 'v': // "vstem" - addHints( true); - nMinStack = nMaxStack = 0; - break; - case 'K': // "hintmask" or "cntrmask" - addHints( true); // implicit vstemhm - nMinStack = nMaxStack = 0; - break; - case 'e': // endchar - updateWidth( (size() >= 1) && (size() != 4)); - nMinStack = nMaxStack = 0; - if( size() == 4) - fprintf( stderr,"Deprecated SEAC-like endchar is not supported for CFF subsetting!\n"); // TODO: handle deprecated op - break; - case 'm': // hmoveto or vmoveto - updateWidth( size() > 1); - nMinStack = 1; - nMaxStack = nMinStack; - break; - case 'M': // rmoveto - updateWidth( size() > 2); - nMinStack = 2; - nMaxStack = nMinStack; - break; - } - - clear(); - return; - } - - if( (c >= 32) || (c == 28)) { -// --mpReadPtr; - read2push(); - } -} - -// -------------------------------------------------------------------- - void CffSubsetterContext::read2push() { ValType aVal = 0; diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx index a5b274bfd8e8..38402af626c2 100644 --- a/vcl/source/gdi/bitmapex.cxx +++ b/vcl/source/gdi/bitmapex.cxx @@ -811,7 +811,7 @@ sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const } else { - if(0x00 != aBitmapColor.GetIndex()) + if(0x00 == aBitmapColor.GetIndex()) { nTransparency = 0x00; } diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 895a98dfaf1a..630e58a1f2bf 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -68,6 +68,9 @@ #ifdef ENABLE_GRAPHITE #include <vcl/graphite_features.hxx> #endif +#ifdef USE_BUILTIN_RASTERIZER +#include <vcl/glyphcache.hxx> +#endif #include <vcl/unohelp.hxx> #include <pdfwriter_impl.hxx> @@ -995,21 +998,28 @@ ImplFontEntry::~ImplFontEntry() // ----------------------------------------------------------------------- -inline void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, const String& rFontName ) +size_t ImplFontEntry::GFBCacheKey_Hash::operator()( const GFBCacheKey& rData ) const +{ + std::hash<sal_UCS4> a; + std::hash<int > b; + return a(rData.first) ^ b(rData.second); +} + +inline void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const String& rFontName ) { if( !mpUnicodeFallbackList ) mpUnicodeFallbackList = new UnicodeFallbackList; - (*mpUnicodeFallbackList)[cChar] = rFontName; + (*mpUnicodeFallbackList)[ GFBCacheKey(cChar,eWeight) ] = rFontName; } // ----------------------------------------------------------------------- -inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, String* pFontName ) const +inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, String* pFontName ) const { if( !mpUnicodeFallbackList ) return false; - UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( cChar ); + UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) ); if( it == mpUnicodeFallbackList->end() ) return false; @@ -1019,10 +1029,10 @@ inline bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, String* pFontN // ----------------------------------------------------------------------- -inline void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, const String& rFontName ) +inline void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const String& rFontName ) { // DBG_ASSERT( mpUnicodeFallbackList, "ImplFontEntry::IgnoreFallbackForUnicode no list" ); - UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( cChar ); + UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) ); // DBG_ASSERT( it != mpUnicodeFallbackList->end(), "ImplFontEntry::IgnoreFallbackForUnicode no match" ); if( it == mpUnicodeFallbackList->end() ) return; @@ -1327,6 +1337,7 @@ void ImplDevFontList::InitGenericGlyphFallback( void ) const "muktinarrow", "", "phetsarathot", "", "padauk", "pinlonmyanmar", "", + "iskoolapota", "lklug", "", 0 }; @@ -1417,7 +1428,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& while( nStrIndex < rMissingCodes.getLength() ) { cChar = rMissingCodes.iterateCodePoints( &nStrIndex ); - bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &rFontSelData.maSearchName ); + bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ); // ignore entries which don't have a fallback if( !bCached || (rFontSelData.maSearchName.Len() != 0) ) break; @@ -1433,7 +1444,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& while( nStrIndex < rMissingCodes.getLength() ) { cChar = rMissingCodes.iterateCodePoints( &nStrIndex ); - bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &aFontName ); + bCached = rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &aFontName ); if( !bCached || (rFontSelData.maSearchName != aFontName) ) pRemainingCodes[ nRemainingLength++ ] = cChar; } @@ -1452,8 +1463,8 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& // cache the result even if there was no match for(;;) { - if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, &rFontSelData.maSearchName ) ) - rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.maSearchName ); + if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ) ) + rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName ); if( nStrIndex >= aOldMissingCodes.getLength() ) break; cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex ); @@ -1464,7 +1475,7 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData& for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); ) { cChar = rMissingCodes.iterateCodePoints( &nStrIndex ); - rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.maSearchName ); + rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName ); } } } @@ -2080,11 +2091,14 @@ ImplDevFontListData* ImplDevFontList::FindDefaultFont() const ImplDevFontList* ImplDevFontList::Clone( bool bScalable, bool bEmbeddable ) const { ImplDevFontList* pClonedList = new ImplDevFontList; - pClonedList->mbMatchData = mbMatchData; +// pClonedList->mbMatchData = mbMatchData; pClonedList->mbMapNames = mbMapNames; pClonedList->mpPreMatchHook = mpPreMatchHook; pClonedList->mpFallbackHook = mpFallbackHook; + // TODO: clone the config-font attributes too? + pClonedList->mbMatchData = false; + DevFontList::const_iterator it = maDevFontList.begin(); for(; it != maDevFontList.end(); ++it ) { @@ -2780,6 +2794,11 @@ void ImplFontCache::Invalidate() maFontInstanceList.clear(); DBG_ASSERT( (mnRef0Count==0), "ImplFontCache::Invalidate() - mnRef0Count non-zero" ); + +#ifdef USE_BUILTIN_RASTERIZER + // TODO: eventually move into SalGraphics layer + GlyphCache::GetInstance().InvalidateAllGlyphs(); +#endif } // ======================================================================= @@ -5893,15 +5912,16 @@ SalLayout* OutputDevice::ImplLayout( const String& rOrigStr, ImplInitFont(); // check string index and length - String aStr = rOrigStr; - if( (ULONG)nMinIndex + nLen >= aStr.Len() ) + if( (unsigned)nMinIndex + nLen > rOrigStr.Len() ) { - if( nMinIndex < aStr.Len() ) - nLen = aStr.Len() - nMinIndex; - else + const int nNewLen = (int)rOrigStr.Len() - nMinIndex; + if( nNewLen <= 0 ) return NULL; + nLen = static_cast<xub_StrLen>(nNewLen); } + String aStr = rOrigStr; + // filter out special markers if( bFilter ) { diff --git a/vcl/source/gdi/outmap.cxx b/vcl/source/gdi/outmap.cxx index 568e8d836045..189ba4c29e59 100644 --- a/vcl/source/gdi/outmap.cxx +++ b/vcl/source/gdi/outmap.cxx @@ -50,6 +50,7 @@ #include <vcl/outdev.h> #include <vcl/salgdi.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> #define USE_64BIT_INTS @@ -1097,6 +1098,41 @@ basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation() const // ----------------------------------------------------------------------- +// #i75163# +basegfx::B2DHomMatrix OutputDevice::GetViewTransformation( const MapMode& rMapMode ) const +{ + // #i82615# + ImplMapRes aMapRes; + ImplThresholdRes aThresRes; + ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes ); + + basegfx::B2DHomMatrix aTransform; + + const double fScaleFactorX((double)mnDPIX * (double)aMapRes.mnMapScNumX / (double)aMapRes.mnMapScDenomX); + const double fScaleFactorY((double)mnDPIY * (double)aMapRes.mnMapScNumY / (double)aMapRes.mnMapScDenomY); + const double fZeroPointX(((double)aMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX); + const double fZeroPointY(((double)aMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY); + + aTransform.set(0, 0, fScaleFactorX); + aTransform.set(1, 1, fScaleFactorY); + aTransform.set(0, 2, fZeroPointX); + aTransform.set(1, 2, fZeroPointY); + + return aTransform; +} + +// ----------------------------------------------------------------------- + +// #i75163# +basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation( const MapMode& rMapMode ) const +{ + basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) ); + aMatrix.invert(); + return aMatrix; +} + +// ----------------------------------------------------------------------- + basegfx::B2DHomMatrix OutputDevice::ImplGetDeviceTransformation() const { basegfx::B2DHomMatrix aTransformation = GetViewTransformation(); @@ -1218,6 +1254,26 @@ PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly ) cons // ----------------------------------------------------------------------- +basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly ) const +{ + basegfx::B2DPolygon aTransformedPoly = rLogicPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation(); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + +basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const +{ + basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation(); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + Region OutputDevice::LogicToPixel( const Region& rLogicRegion ) const { DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); @@ -1402,6 +1458,28 @@ PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly, // ----------------------------------------------------------------------- +basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly, + const MapMode& rMapMode ) const +{ + basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode ); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + +basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly, + const MapMode& rMapMode ) const +{ + basegfx::B2DPolygon aTransformedPoly = rLogicPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode ); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + Region OutputDevice::LogicToPixel( const Region& rLogicRegion, const MapMode& rMapMode ) const { @@ -1553,6 +1631,26 @@ PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly ) con // ----------------------------------------------------------------------- +basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly ) const +{ + basegfx::B2DPolygon aTransformedPoly = rPixelPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation(); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + +basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly ) const +{ + basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation(); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const { DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); @@ -1732,6 +1830,28 @@ PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly, // ----------------------------------------------------------------------- +basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly, + const MapMode& rMapMode ) const +{ + basegfx::B2DPolygon aTransformedPoly = rPixelPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode ); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + +basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly, + const MapMode& rMapMode ) const +{ + basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly; + const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode ); + aTransformedPoly.transform( rTransformationMatrix ); + return aTransformedPoly; +} + +// ----------------------------------------------------------------------- + Region OutputDevice::PixelToLogic( const Region& rDeviceRegion, const MapMode& rMapMode ) const { @@ -2159,6 +2279,96 @@ Size OutputDevice::LogicToLogic( const Size& rSzSource, // ----------------------------------------------------------------------- +basegfx::B2DPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolygon& rPolySource, + const MapMode& rMapModeSource, + const MapMode& rMapModeDest ) +{ + if ( rMapModeSource == rMapModeDest ) + return rPolySource; + + MapUnit eUnitSource = rMapModeSource.GetMapUnit(); + MapUnit eUnitDest = rMapModeDest.GetMapUnit(); + ENTER2( eUnitSource, eUnitDest ); + + basegfx::B2DHomMatrix aTransform; + + if ( rMapModeSource.mpImplMapMode->mbSimple && + rMapModeDest.mpImplMapMode->mbSimple ) + { + ENTER3( eUnitSource, eUnitDest ); + + const double fScaleFactor((double)nNumerator / (double)nDenominator); + aTransform.set(0, 0, fScaleFactor); + aTransform.set(1, 1, fScaleFactor); + } + else + { + ENTER4( rMapModeSource, rMapModeDest ); + + const double fScaleFactorX( (double(aMapResSource.mnMapScNumX) * double(aMapResDest.mnMapScDenomX)) + / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)) ); + const double fScaleFactorY( (double(aMapResSource.mnMapScNumY) * double(aMapResDest.mnMapScDenomY)) + / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)) ); + const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX)); + const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY)); + + aTransform.set(0, 0, fScaleFactorX); + aTransform.set(1, 1, fScaleFactorY); + aTransform.set(0, 2, fZeroPointX); + aTransform.set(1, 2, fZeroPointY); + } + basegfx::B2DPolygon aPoly( rPolySource ); + aPoly.transform( aTransform ); + return aPoly; +} + +// ----------------------------------------------------------------------- + +basegfx::B2DPolyPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolyPolygon& rPolySource, + const MapMode& rMapModeSource, + const MapMode& rMapModeDest ) +{ + if ( rMapModeSource == rMapModeDest ) + return rPolySource; + + MapUnit eUnitSource = rMapModeSource.GetMapUnit(); + MapUnit eUnitDest = rMapModeDest.GetMapUnit(); + ENTER2( eUnitSource, eUnitDest ); + + basegfx::B2DHomMatrix aTransform; + + if ( rMapModeSource.mpImplMapMode->mbSimple && + rMapModeDest.mpImplMapMode->mbSimple ) + { + ENTER3( eUnitSource, eUnitDest ); + + const double fScaleFactor((double)nNumerator / (double)nDenominator); + aTransform.set(0, 0, fScaleFactor); + aTransform.set(1, 1, fScaleFactor); + } + else + { + ENTER4( rMapModeSource, rMapModeDest ); + + const double fScaleFactorX( (double(aMapResSource.mnMapScNumX) * double(aMapResDest.mnMapScDenomX)) + / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)) ); + const double fScaleFactorY( (double(aMapResSource.mnMapScNumY) * double(aMapResDest.mnMapScDenomY)) + / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)) ); + const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX)); + const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY)); + + aTransform.set(0, 0, fScaleFactorX); + aTransform.set(1, 1, fScaleFactorY); + aTransform.set(0, 2, fZeroPointX); + aTransform.set(1, 2, fZeroPointY); + } + basegfx::B2DPolyPolygon aPoly( rPolySource ); + aPoly.transform( aTransform ); + return aPoly; +} + +// ----------------------------------------------------------------------- + Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource, const MapMode& rMapModeSource, const MapMode& rMapModeDest ) diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx index fefe904e371a..046bc4a8951d 100644 --- a/vcl/source/gdi/pdfextoutdevdata.cxx +++ b/vcl/source/gdi/pdfextoutdevdata.cxx @@ -27,10 +27,12 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include <vcl/pdfextoutdevdata.hxx> -#include <vcl/graph.hxx> -#include <vcl/outdev.hxx> -#include <vcl/gfxlink.hxx> +#include "vcl/pdfextoutdevdata.hxx" +#include "vcl/graph.hxx" +#include "vcl/outdev.hxx" +#include "vcl/gfxlink.hxx" +#include "basegfx/polygon/b2dpolygon.hxx" +#include "basegfx/polygon/b2dpolygontools.hxx" #include <boost/shared_ptr.hpp> @@ -430,7 +432,10 @@ sal_Bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIM if ( bClippingNeeded ) { rWriter.Push(); - rWriter.SetClipRegion( aVisibleOutputRect ); + basegfx::B2DPolyPolygon aRect( basegfx::tools::createPolygonFromRect( + basegfx::B2DRectangle( aVisibleOutputRect.Left(), aVisibleOutputRect.Top(), + aVisibleOutputRect.Right(), aVisibleOutputRect.Bottom() ) ) ); + rWriter.SetClipRegion( aRect); } Bitmap aMask; SvMemoryStream aTmp; diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 040d38f538c9..5dcce25a0315 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -346,7 +346,7 @@ void PDFWriter::SetClipRegion() ((PDFWriterImpl*)pImplementation)->clearClipRegion(); } -void PDFWriter::SetClipRegion( const Region& rRegion ) +void PDFWriter::SetClipRegion( const basegfx::B2DPolyPolygon& rRegion ) { ((PDFWriterImpl*)pImplementation)->setClipRegion( rRegion ); } @@ -356,7 +356,7 @@ void PDFWriter::MoveClipRegion( long nHorzMove, long nVertMove ) ((PDFWriterImpl*)pImplementation)->moveClipRegion( nHorzMove, nVertMove ); } -void PDFWriter::IntersectClipRegion( const Region& rRegion ) +void PDFWriter::IntersectClipRegion( const basegfx::B2DPolyPolygon& rRegion ) { ((PDFWriterImpl*)pImplementation)->intersectClipRegion( rRegion ); } diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 4371feb8ee37..6a24775219d9 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -37,6 +37,8 @@ #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> #include <rtl/ustrbuf.hxx> #include <tools/debug.hxx> #include <tools/zcodec.hxx> @@ -115,7 +117,7 @@ void doTestCode() aDocInfo.Title = OUString( RTL_CONSTASCII_USTRINGPARAM( "PDF export test document" ) ); aDocInfo.Producer = OUString( RTL_CONSTASCII_USTRINGPARAM( "VCL" ) ); aWriter.SetDocInfo( aDocInfo ); - aWriter.NewPage(); + aWriter.NewPage( 595, 842 ); aWriter.BeginStructureElement( PDFWriter::Document ); // set duration of 3 sec for first page aWriter.SetAutoAdvanceTime( 3 ); @@ -166,7 +168,7 @@ void doTestCode() TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); - aWriter.NewPage(); + aWriter.NewPage( 595, 842 ); // test AddStream interface aWriter.AddStream( String( RTL_CONSTASCII_USTRINGPARAM( "text/plain" ) ), new PDFTestOutputStream(), true ); // set transitional mode @@ -208,7 +210,25 @@ void doTestCode() aWriter.BeginStructureElement( PDFWriter::Caption ); aWriter.DrawText( Point( 4500, 9000 ), String( RTL_CONSTASCII_USTRINGPARAM( "Some drawing stuff inside the structure" ) ) ); aWriter.EndStructureElement(); + + // test clipping + basegfx::B2DPolyPolygon aClip; + basegfx::B2DPolygon aClipPoly; + aClipPoly.append( basegfx::B2DPoint( 8250, 9600 ) ); + aClipPoly.append( basegfx::B2DPoint( 16500, 11100 ) ); + aClipPoly.append( basegfx::B2DPoint( 8250, 12600 ) ); + aClipPoly.append( basegfx::B2DPoint( 4500, 11100 ) ); + aClipPoly.setClosed( true ); + //aClipPoly.flip(); + aClip.append( aClipPoly ); + + aWriter.Push( PUSH_CLIPREGION | PUSH_FILLCOLOR ); + aWriter.SetClipRegion( aClip ); + aWriter.DrawEllipse( Rectangle( Point( 4500, 9600 ), Size( 12000, 3000 ) ) ); + aWriter.MoveClipRegion( 1000, 500 ); + aWriter.SetFillColor( Color( COL_RED ) ); aWriter.DrawEllipse( Rectangle( Point( 4500, 9600 ), Size( 12000, 3000 ) ) ); + aWriter.Pop(); // test transparency // draw background Rectangle aTranspRect( Point( 7500, 13500 ), Size( 9000, 6000 ) ); @@ -288,7 +308,7 @@ void doTestCode() aLIPoly.Move( 1000, 1000 ); aWriter.DrawPolyLine( aLIPoly, aLI ); - aWriter.NewPage(); + aWriter.NewPage( 595, 842 ); aWriter.SetMapMode( MapMode( MAP_100TH_MM ) ); Wallpaper aWall( aTransMask ); aWall.SetStyle( WALLPAPER_TILE ); @@ -312,7 +332,7 @@ void doTestCode() aWriter.SetLineColor( Color( COL_LIGHTBLUE ) ); aWriter.DrawRect( aPolyRect ); - aWriter.NewPage(); + aWriter.NewPage( 595, 842 ); aWriter.SetMapMode( MapMode( MAP_100TH_MM ) ); aWriter.SetFont( Font( String( RTL_CONSTASCII_USTRINGPARAM( "Times" ) ), Size( 0, 500 ) ) ); aWriter.SetTextColor( Color( COL_BLACK ) ); @@ -632,30 +652,25 @@ static void appendUnicodeTextString( const rtl::OUString& rString, OStringBuffer } } -OString PDFWriterImpl::convertWidgetFieldName( const rtl::OUString& rString ) +void PDFWriterImpl::createWidgetFieldName( sal_Int32 i_nWidgetIndex, const PDFWriter::AnyWidget& i_rControl ) { - OStringBuffer aBuffer( rString.getLength()+64 ); - /* #i80258# previously we use appendName here however we need a slightly different coding scheme than the normal name encoding for field names - - also replace all '.' by '_' as '.' indicates a hierarchy level which - we do not have here */ - - OString aStr( OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ) ); + const OUString& rName = (m_aContext.Version > PDFWriter::PDF_1_2) ? i_rControl.Name : i_rControl.Text; + OString aStr( OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ) ); const sal_Char* pStr = aStr.getStr(); int nLen = aStr.getLength(); + + OStringBuffer aBuffer( rName.getLength()+64 ); for( int i = 0; i < nLen; i++ ) { /* #i16920# PDF recommendation: output UTF8, any byte - * outside the interval [33(=ASCII'!');126(=ASCII'~')] + * outside the interval [32(=ASCII' ');126(=ASCII'~')] * should be escaped hexadecimal */ - if( pStr[i] == '.' ) - aBuffer.append( '_' ); - else if( (pStr[i] >= 33 && pStr[i] <= 126 ) ) + if( (pStr[i] >= 32 && pStr[i] <= 126 ) ) aBuffer.append( pStr[i] ); else { @@ -664,31 +679,135 @@ OString PDFWriterImpl::convertWidgetFieldName( const rtl::OUString& rString ) } } - OString aRet = aBuffer.makeStringAndClear(); + OString aFullName( aBuffer.makeStringAndClear() ); + + /* #i82785# create hierarchical fields down to the for each dot in i_rName */ + sal_Int32 nTokenIndex = 0, nLastTokenIndex = 0; + OString aPartialName; + OString aDomain; + do + { + nLastTokenIndex = nTokenIndex; + aPartialName = aFullName.getToken( 0, '.', nTokenIndex ); + if( nTokenIndex != -1 ) + { + // find or create a hierarchical field + // first find the fully qualified name up to this field + aDomain = aFullName.copy( 0, nTokenIndex-1 ); + std::hash_map< rtl::OString, sal_Int32, rtl::OStringHash >::const_iterator it = m_aFieldNameMap.find( aDomain ); + if( it == m_aFieldNameMap.end() ) + { + // create new hierarchy field + sal_Int32 nNewWidget = m_aWidgets.size(); + m_aWidgets.push_back( PDFWidget() ); + m_aWidgets[nNewWidget].m_nObject = createObject(); + m_aWidgets[nNewWidget].m_eType = PDFWriter::Hierarchy; + m_aWidgets[nNewWidget].m_aName = aPartialName; + m_aWidgets[i_nWidgetIndex].m_nParent = m_aWidgets[nNewWidget].m_nObject; + m_aFieldNameMap[aDomain] = nNewWidget; + m_aWidgets[i_nWidgetIndex].m_nParent = m_aWidgets[nNewWidget].m_nObject; + if( nLastTokenIndex > 0 ) + { + // this field is not a root field and + // needs to be inserted to its parent + OString aParentDomain( aDomain.copy( 0, nLastTokenIndex-1 ) ); + it = m_aFieldNameMap.find( aParentDomain ); + OSL_ENSURE( it != m_aFieldNameMap.end(), "field name not found" ); + if( it != m_aFieldNameMap.end() ) + { + OSL_ENSURE( it->second < sal_Int32(m_aWidgets.size()), "invalid field number entry" ); + if( it->second < sal_Int32(m_aWidgets.size()) ) + { + PDFWidget& rParentField( m_aWidgets[it->second] ); + rParentField.m_aKids.push_back( m_aWidgets[nNewWidget].m_nObject ); + rParentField.m_aKidsIndex.push_back( nNewWidget ); + m_aWidgets[nNewWidget].m_nParent = rParentField.m_nObject; + } + } + } + } + else if( m_aWidgets[it->second].m_eType != PDFWriter::Hierarchy ) + { + // this is invalid, someone tries to have a terminal field as parent + // example: a button with the name foo.bar exists and + // another button is named foo.bar.no + // workaround: put the second terminal field as much up in the hierarchy as + // necessary to have a non-terminal field as parent (or none at all) + // since it->second already is terminal, we just need to use its parent + aDomain = OString(); + aPartialName = aFullName.copy( aFullName.lastIndexOf( '.' )+1 ); + if( nLastTokenIndex > 0 ) + { + aDomain = aFullName.copy( 0, nLastTokenIndex-1 ); + OStringBuffer aBuf( aDomain.getLength() + 1 + aPartialName.getLength() ); + aBuf.append( aDomain ); + aBuf.append( '.' ); + aBuf.append( aPartialName ); + aFullName = aBuf.makeStringAndClear(); + } + else + aFullName = aPartialName; + break; + } + } + } while( nTokenIndex != -1 ); + + // insert widget into its hierarchy field + if( aDomain.getLength() ) + { + std::hash_map< rtl::OString, sal_Int32, rtl::OStringHash >::const_iterator it = m_aFieldNameMap.find( aDomain ); + if( it != m_aFieldNameMap.end() ) + { + OSL_ENSURE( it->second >= 0 && it->second < sal_Int32( m_aWidgets.size() ), "invalid field index" ); + if( it->second >= 0 && it->second < sal_Int32(m_aWidgets.size()) ) + { + m_aWidgets[i_nWidgetIndex].m_nParent = m_aWidgets[it->second].m_nObject; + m_aWidgets[it->second].m_aKids.push_back( m_aWidgets[i_nWidgetIndex].m_nObject); + m_aWidgets[it->second].m_aKidsIndex.push_back( i_nWidgetIndex ); + } + } + } + + if( aPartialName.getLength() == 0 ) + { + // how funny, an empty field name + if( i_rControl.getType() == PDFWriter::RadioButton ) + { + aPartialName = "RadioGroup"; + aPartialName += OString::valueOf( static_cast<const PDFWriter::RadioButtonWidget&>(i_rControl).RadioGroup ); + } + else + aPartialName = OString( "Widget" ); + } + if( ! m_aContext.AllowDuplicateFieldNames ) { - std::hash_map<OString, sal_Int32, OStringHash>::iterator it = m_aFieldNameMap.find( aRet ); + std::hash_map<OString, sal_Int32, OStringHash>::iterator it = m_aFieldNameMap.find( aFullName ); if( it != m_aFieldNameMap.end() ) // not unique { std::hash_map< OString, sal_Int32, OStringHash >::const_iterator check_it; OString aTry; + sal_Int32 nTry = 2; do { - OStringBuffer aUnique( aRet.getLength() + 16 ); - aUnique.append( aRet ); + OStringBuffer aUnique( aFullName.getLength() + 16 ); + aUnique.append( aFullName ); aUnique.append( '_' ); - aUnique.append( it->second ); - it->second++; + aUnique.append( nTry++ ); aTry = aUnique.makeStringAndClear(); check_it = m_aFieldNameMap.find( aTry ); } while( check_it != m_aFieldNameMap.end() ); - aRet = aTry; + aFullName = aTry; + m_aFieldNameMap[ aFullName ] = i_nWidgetIndex; + aPartialName = aFullName.copy( aFullName.lastIndexOf( '.' )+1 ); } else - m_aFieldNameMap[ aRet ] = 2; + m_aFieldNameMap[ aFullName ] = i_nWidgetIndex; } - return aRet; + + // finally + m_aWidgets[i_nWidgetIndex].m_aName = aPartialName; } static void appendFixedInt( sal_Int32 nValue, OStringBuffer& rBuffer, sal_Int32 nPrecision = nLog10Divisor ) @@ -720,7 +839,7 @@ static void appendFixedInt( sal_Int32 nValue, OStringBuffer& rBuffer, sal_Int32 // appends a double. PDF does not accept exponential format, only fixed point -static void appendDouble( double fValue, OStringBuffer& rBuffer, int nPrecision = 5 ) +static void appendDouble( double fValue, OStringBuffer& rBuffer, sal_Int32 nPrecision = 5 ) { bool bNeg = false; if( fValue < 0.0 ) @@ -1273,6 +1392,19 @@ void PDFWriterImpl::PDFPage::appendPoint( const Point& rPoint, OStringBuffer& rB appendFixedInt( nValue, rBuffer ); } +void PDFWriterImpl::PDFPage::appendPixelPoint( const basegfx::B2DPoint& rPoint, OStringBuffer& rBuffer ) const +{ + double fValue = pixelToPoint(rPoint.getX()); + + appendDouble( fValue, rBuffer, nLog10Divisor ); + + rBuffer.append( ' ' ); + + fValue = double(getHeight()) - pixelToPoint(rPoint.getY()); + + appendDouble( fValue, rBuffer, nLog10Divisor ); +} + void PDFWriterImpl::PDFPage::appendRect( const Rectangle& rRect, OStringBuffer& rBuffer ) const { appendPoint( rRect.BottomLeft() + Point( 0, 1 ), rBuffer ); @@ -1345,6 +1477,82 @@ void PDFWriterImpl::PDFPage::appendPolygon( const Polygon& rPoly, OStringBuffer& } } +void PDFWriterImpl::PDFPage::appendPolygon( const basegfx::B2DPolygon& rPoly, OStringBuffer& rBuffer, bool bClose ) const +{ + basegfx::B2DPolygon aPoly( lcl_convert( m_pWriter->m_aGraphicsStack.front().m_aMapMode, + m_pWriter->m_aMapMode, + m_pWriter->getReferenceDevice(), + rPoly ) ); + + if( basegfx::tools::isRectangle( aPoly ) ) + { + basegfx::B2DRange aRange( aPoly.getB2DRange() ); + basegfx::B2DPoint aBL( aRange.getMinX(), aRange.getMaxY() ); + appendPixelPoint( aBL, rBuffer ); + rBuffer.append( ' ' ); + appendMappedLength( aRange.getWidth(), rBuffer, false, NULL, nLog10Divisor ); + rBuffer.append( ' ' ); + appendMappedLength( aRange.getHeight(), rBuffer, true, NULL, nLog10Divisor ); + rBuffer.append( " re\n" ); + return; + } + sal_uInt32 nPoints = aPoly.count(); + if( nPoints > 0 ) + { + sal_uInt32 nBufLen = rBuffer.getLength(); + basegfx::B2DPoint aLastPoint( aPoly.getB2DPoint( 0 ) ); + appendPixelPoint( aLastPoint, rBuffer ); + rBuffer.append( " m\n" ); + for( sal_uInt32 i = 1; i <= nPoints; i++ ) + { + if( i != nPoints || aPoly.isClosed() ) + { + sal_uInt32 nCurPoint = i % nPoints; + sal_uInt32 nLastPoint = i-1; + basegfx::B2DPoint aPoint( aPoly.getB2DPoint( nCurPoint ) ); + if( aPoly.isNextControlPointUsed( nLastPoint ) && + aPoly.isPrevControlPointUsed( nCurPoint ) ) + { + appendPixelPoint( aPoly.getNextControlPoint( nLastPoint ), rBuffer ); + rBuffer.append( ' ' ); + appendPixelPoint( aPoly.getPrevControlPoint( nCurPoint ), rBuffer ); + rBuffer.append( ' ' ); + appendPixelPoint( aPoint, rBuffer ); + rBuffer.append( " c" ); + } + else if( aPoly.isNextControlPointUsed( nLastPoint ) ) + { + appendPixelPoint( aPoly.getNextControlPoint( nLastPoint ), rBuffer ); + rBuffer.append( ' ' ); + appendPixelPoint( aPoint, rBuffer ); + rBuffer.append( " y" ); + } + else if( aPoly.isPrevControlPointUsed( nCurPoint ) ) + { + appendPixelPoint( aPoly.getPrevControlPoint( nCurPoint ), rBuffer ); + rBuffer.append( ' ' ); + appendPixelPoint( aPoint, rBuffer ); + rBuffer.append( " v" ); + } + else + { + appendPixelPoint( aPoint, rBuffer ); + rBuffer.append( " l" ); + } + if( (rBuffer.getLength() - nBufLen) > 65 ) + { + rBuffer.append( "\n" ); + nBufLen = rBuffer.getLength(); + } + else + rBuffer.append( " " ); + } + } + if( bClose ) + rBuffer.append( "h\n" ); + } +} + void PDFWriterImpl::PDFPage::appendPolyPolygon( const PolyPolygon& rPolyPoly, OStringBuffer& rBuffer, bool bClose ) const { USHORT nPolygons = rPolyPoly.Count(); @@ -1352,6 +1560,13 @@ void PDFWriterImpl::PDFPage::appendPolyPolygon( const PolyPolygon& rPolyPoly, OS appendPolygon( rPolyPoly[n], rBuffer, bClose ); } +void PDFWriterImpl::PDFPage::appendPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly, OStringBuffer& rBuffer, bool bClose ) const +{ + sal_uInt32 nPolygons = rPolyPoly.count(); + for( sal_uInt32 n = 0; n < nPolygons; n++ ) + appendPolygon( rPolyPoly.getB2DPolygon( n ), rBuffer, bClose ); +} + void PDFWriterImpl::PDFPage::appendMappedLength( sal_Int32 nLength, OStringBuffer& rBuffer, bool bVertical, sal_Int32* pOutLength ) const { sal_Int32 nValue = nLength; @@ -1371,7 +1586,7 @@ void PDFWriterImpl::PDFPage::appendMappedLength( sal_Int32 nLength, OStringBuffe appendFixedInt( nValue, rBuffer, 1 ); } -void PDFWriterImpl::PDFPage::appendMappedLength( double fLength, OStringBuffer& rBuffer, bool bVertical, sal_Int32* pOutLength ) const +void PDFWriterImpl::PDFPage::appendMappedLength( double fLength, OStringBuffer& rBuffer, bool bVertical, sal_Int32* pOutLength, sal_Int32 nPrecision ) const { Size aSize( lcl_convert( m_pWriter->m_aGraphicsStack.front().m_aMapMode, m_pWriter->m_aMapMode, @@ -1380,7 +1595,7 @@ void PDFWriterImpl::PDFPage::appendMappedLength( double fLength, OStringBuffer& if( pOutLength ) *pOutLength = (sal_Int32)(fLength*(double)(bVertical ? aSize.Height() : aSize.Width())/1000.0); fLength *= pixelToPoint((double)(bVertical ? aSize.Height() : aSize.Width()) / 1000.0); - appendDouble( fLength, rBuffer ); + appendDouble( fLength, rBuffer, nPrecision ); } bool PDFWriterImpl::PDFPage::appendLineInfo( const LineInfo& rInfo, OStringBuffer& rBuffer ) const @@ -5189,78 +5404,82 @@ bool PDFWriterImpl::emitWidgetAnnotations() aLine.append( rWidget.m_nObject ); aLine.append( " 0 obj\n" "<<" ); - // emit widget annotation only for terminal fields - if( rWidget.m_aKids.empty() ) - { - aLine.append( "/Type/Annot/Subtype/Widget/F 4\n" - "/Rect[" ); - appendFixedInt( rWidget.m_aRect.Left()-1, aLine ); - aLine.append( ' ' ); - appendFixedInt( rWidget.m_aRect.Top()+1, aLine ); - aLine.append( ' ' ); - appendFixedInt( rWidget.m_aRect.Right()+1, aLine ); - aLine.append( ' ' ); - appendFixedInt( rWidget.m_aRect.Bottom()-1, aLine ); - aLine.append( "]\n" ); - } - aLine.append( "/FT/" ); - switch( rWidget.m_eType ) + if( rWidget.m_eType != PDFWriter::Hierarchy ) { - case PDFWriter::RadioButton: - case PDFWriter::CheckBox: - // for radio buttons only the RadioButton field, not the - // CheckBox children should have a value, else acrobat reader - // does not always check the right button - // of course real check boxes (not belonging to a readio group) - // need their values, too - if( rWidget.m_eType == PDFWriter::RadioButton || rWidget.m_nRadioGroup < 0 ) - { - aValue.append( "/" ); - // check for radio group with all buttons unpressed - if( rWidget.m_aValue.getLength() == 0 ) - aValue.append( "Off" ); - else - appendName( rWidget.m_aValue, aValue ); - } - case PDFWriter::PushButton: - aLine.append( "Btn" ); - break; - case PDFWriter::ListBox: - if( rWidget.m_nFlags & 0x200000 ) // multiselect - { - aValue.append( "[" ); - for( unsigned int i = 0; i < rWidget.m_aSelectedEntries.size(); i++ ) + // emit widget annotation only for terminal fields + if( rWidget.m_aKids.empty() ) + { + aLine.append( "/Type/Annot/Subtype/Widget/F 4\n" + "/Rect[" ); + appendFixedInt( rWidget.m_aRect.Left()-1, aLine ); + aLine.append( ' ' ); + appendFixedInt( rWidget.m_aRect.Top()+1, aLine ); + aLine.append( ' ' ); + appendFixedInt( rWidget.m_aRect.Right()+1, aLine ); + aLine.append( ' ' ); + appendFixedInt( rWidget.m_aRect.Bottom()-1, aLine ); + aLine.append( "]\n" ); + } + aLine.append( "/FT/" ); + switch( rWidget.m_eType ) + { + case PDFWriter::RadioButton: + case PDFWriter::CheckBox: + // for radio buttons only the RadioButton field, not the + // CheckBox children should have a value, else acrobat reader + // does not always check the right button + // of course real check boxes (not belonging to a readio group) + // need their values, too + if( rWidget.m_eType == PDFWriter::RadioButton || rWidget.m_nRadioGroup < 0 ) { - sal_Int32 nEntry = rWidget.m_aSelectedEntries[i]; - if( nEntry >= 0 && nEntry < sal_Int32(rWidget.m_aListEntries.size()) ) - appendUnicodeTextStringEncrypt( rWidget.m_aListEntries[ nEntry ], rWidget.m_nObject, aValue ); + aValue.append( "/" ); + // check for radio group with all buttons unpressed + if( rWidget.m_aValue.getLength() == 0 ) + aValue.append( "Off" ); + else + appendName( rWidget.m_aValue, aValue ); } - aValue.append( "]" ); - } - else if( rWidget.m_aSelectedEntries.size() > 0 && - rWidget.m_aSelectedEntries[0] >= 0 && - rWidget.m_aSelectedEntries[0] < sal_Int32(rWidget.m_aListEntries.size()) ) - { - appendUnicodeTextStringEncrypt( rWidget.m_aListEntries[ rWidget.m_aSelectedEntries[0] ], rWidget.m_nObject, aValue ); - } - else - appendUnicodeTextStringEncrypt( rtl::OUString(), rWidget.m_nObject, aValue ); - aLine.append( "Ch" ); - break; - case PDFWriter::ComboBox: - appendUnicodeTextStringEncrypt( rWidget.m_aValue, rWidget.m_nObject, aValue ); - aLine.append( "Ch" ); - break; - case PDFWriter::Edit: - aLine.append( "Tx" ); - appendUnicodeTextStringEncrypt( rWidget.m_aValue, rWidget.m_nObject, aValue ); - break; + case PDFWriter::PushButton: + aLine.append( "Btn" ); + break; + case PDFWriter::ListBox: + if( rWidget.m_nFlags & 0x200000 ) // multiselect + { + aValue.append( "[" ); + for( unsigned int i = 0; i < rWidget.m_aSelectedEntries.size(); i++ ) + { + sal_Int32 nEntry = rWidget.m_aSelectedEntries[i]; + if( nEntry >= 0 && nEntry < sal_Int32(rWidget.m_aListEntries.size()) ) + appendUnicodeTextStringEncrypt( rWidget.m_aListEntries[ nEntry ], rWidget.m_nObject, aValue ); + } + aValue.append( "]" ); + } + else if( rWidget.m_aSelectedEntries.size() > 0 && + rWidget.m_aSelectedEntries[0] >= 0 && + rWidget.m_aSelectedEntries[0] < sal_Int32(rWidget.m_aListEntries.size()) ) + { + appendUnicodeTextStringEncrypt( rWidget.m_aListEntries[ rWidget.m_aSelectedEntries[0] ], rWidget.m_nObject, aValue ); + } + else + appendUnicodeTextStringEncrypt( rtl::OUString(), rWidget.m_nObject, aValue ); + aLine.append( "Ch" ); + break; + case PDFWriter::ComboBox: + appendUnicodeTextStringEncrypt( rWidget.m_aValue, rWidget.m_nObject, aValue ); + aLine.append( "Ch" ); + break; + case PDFWriter::Edit: + aLine.append( "Tx" ); + appendUnicodeTextStringEncrypt( rWidget.m_aValue, rWidget.m_nObject, aValue ); + break; + case PDFWriter::Hierarchy: // make the compiler happy + break; + } + aLine.append( "\n" ); + aLine.append( "/P " ); + aLine.append( m_aPages[ rWidget.m_nPage ].m_nPageObject ); + aLine.append( " 0 R\n" ); } - aLine.append( "\n" ); - aLine.append( "/P " ); - aLine.append( m_aPages[ rWidget.m_nPage ].m_nPageObject ); - aLine.append( " 0 R\n" ); - if( rWidget.m_nParent ) { aLine.append( "/Parent " ); @@ -5284,7 +5503,7 @@ bool PDFWriterImpl::emitWidgetAnnotations() appendLiteralStringEncrypt( rWidget.m_aName, rWidget.m_nObject, aLine ); aLine.append( "\n" ); } - if( m_aContext.Version > PDFWriter::PDF_1_2 ) + if( m_aContext.Version > PDFWriter::PDF_1_2 && rWidget.m_aDescription.getLength() ) { // the alternate field name should be unicode able since it is // supposed to be used in UI @@ -5346,7 +5565,7 @@ bool PDFWriterImpl::emitWidgetAnnotations() if(!m_bIsPDF_A1) { OStringBuffer aDest; - if( appendDest( rWidget.m_nDest, aDest ) ) + if( rWidget.m_nDest != -1 && appendDest( rWidget.m_nDest, aDest ) ) { aLine.append( "/AA<</D<</Type/Action/S/GoTo/D " ); aLine.append( aDest.makeStringAndClear() ); @@ -6379,16 +6598,19 @@ void PDFWriterImpl::sortWidgets() for( int nW = 0; nW < nWidgets; nW++ ) { const PDFWidget& rWidget = m_aWidgets[nW]; - AnnotSortContainer& rCont = sorted[ rWidget.m_nPage ]; - // optimize vector allocation - if( rCont.aSortedAnnots.empty() ) - rCont.aSortedAnnots.reserve( m_aPages[ rWidget.m_nPage ].m_aAnnotations.size() ); - // insert widget to tab sorter - // RadioButtons are not page annotations, only their individual check boxes are - if( rWidget.m_eType != PDFWriter::RadioButton ) - { - rCont.aObjects.insert( rWidget.m_nObject ); - rCont.aSortedAnnots.push_back( AnnotationSortEntry( rWidget.m_nTabOrder, rWidget.m_nObject, nW ) ); + if( rWidget.m_nPage >= 0 ) + { + AnnotSortContainer& rCont = sorted[ rWidget.m_nPage ]; + // optimize vector allocation + if( rCont.aSortedAnnots.empty() ) + rCont.aSortedAnnots.reserve( m_aPages[ rWidget.m_nPage ].m_aAnnotations.size() ); + // insert widget to tab sorter + // RadioButtons are not page annotations, only their individual check boxes are + if( rWidget.m_eType != PDFWriter::RadioButton ) + { + rCont.aObjects.insert( rWidget.m_nObject ); + rCont.aSortedAnnots.push_back( AnnotationSortEntry( rWidget.m_nTabOrder, rWidget.m_nObject, nW ) ); + } } } for( std::hash_map< sal_Int32, AnnotSortContainer >::iterator it = sorted.begin(); it != sorted.end(); ++it ) @@ -8278,7 +8500,7 @@ void PDFWriterImpl::beginRedirect( SvStream* pStream, const Rectangle& rTargetRe { push( PUSH_ALL ); - setClipRegion( Region() ); + clearClipRegion(); updateGraphicsState(); m_aOutputStreams.push_front( StreamRedirect() ); @@ -10214,25 +10436,17 @@ void PDFWriterImpl::updateGraphicsState() { rNewState.m_nUpdateFlags &= ~GraphicsState::updateClipRegion; - Region& rNewClip = rNewState.m_aClipRegion; - - /* #103137# equality operator is not implemented - * const as API promises but may change Region - * from Polygon to rectangles. Arrrgghh !!!! - */ - Region aLeft = m_aCurrentPDFState.m_aClipRegion; - Region aRight = rNewClip; - if( aLeft != aRight ) + if( m_aCurrentPDFState.m_bClipRegion != rNewState.m_bClipRegion || + ( rNewState.m_bClipRegion && m_aCurrentPDFState.m_aClipRegion != rNewState.m_aClipRegion ) ) { - if( ! m_aCurrentPDFState.m_aClipRegion.IsEmpty() && - ! m_aCurrentPDFState.m_aClipRegion.IsNull() ) + if( m_aCurrentPDFState.m_bClipRegion && m_aCurrentPDFState.m_aClipRegion.count() ) { aLine.append( "Q " ); // invalidate everything but the clip region m_aCurrentPDFState = GraphicsState(); rNewState.m_nUpdateFlags = sal::static_int_cast<sal_uInt16>(~GraphicsState::updateClipRegion); } - if( ! rNewClip.IsEmpty() && ! rNewClip.IsNull() ) + if( rNewState.m_bClipRegion && rNewState.m_aClipRegion.count() ) { // clip region is always stored in private PDF mapmode MapMode aNewMapMode = rNewState.m_aMapMode; @@ -10241,32 +10455,8 @@ void PDFWriterImpl::updateGraphicsState() m_aCurrentPDFState.m_aMapMode = rNewState.m_aMapMode; aLine.append( "q " ); - if( rNewClip.HasPolyPolygon() ) - { - m_aPages.back().appendPolyPolygon( rNewClip.GetPolyPolygon(), aLine ); - aLine.append( "W* n\n" ); - } - else - { - // need to clip all rectangles - RegionHandle aHandle = rNewClip.BeginEnumRects(); - Rectangle aRect; - while( rNewClip.GetNextEnumRect( aHandle, aRect ) ) - { - m_aPages.back().appendRect( aRect, aLine ); - if( aLine.getLength() > 80 ) - { - aLine.append( "\n" ); - writeBuffer( aLine.getStr(), aLine.getLength() ); - aLine.setLength( 0 ); - } - else - aLine.append( ' ' ); - } - rNewClip.EndEnumRects( aHandle ); - aLine.append( "W* n\n" ); - } - + m_aPages.back().appendPolyPolygon( rNewState.m_aClipRegion, aLine ); + aLine.append( "W* n\n" ); rNewState.m_aMapMode = aNewMapMode; getReferenceDevice()->SetMapMode( rNewState.m_aMapMode ); m_aCurrentPDFState.m_aMapMode = rNewState.m_aMapMode; @@ -10380,9 +10570,12 @@ void PDFWriterImpl::pop() if( ! (aState.m_nFlags & PUSH_MAPMODE) ) setMapMode( aState.m_aMapMode ); if( ! (aState.m_nFlags & PUSH_CLIPREGION) ) + { // do not use setClipRegion here // it would convert again assuming the current mapmode rOld.m_aClipRegion = aState.m_aClipRegion; + rOld.m_bClipRegion = aState.m_bClipRegion; + } if( ! (aState.m_nFlags & PUSH_TEXTLINECOLOR ) ) setTextLineColor( aState.m_aTextLineColor ); if( ! (aState.m_nFlags & PUSH_OVERLINECOLOR ) ) @@ -10406,45 +10599,59 @@ void PDFWriterImpl::setMapMode( const MapMode& rMapMode ) m_aCurrentPDFState.m_aMapMode = rMapMode; } -void PDFWriterImpl::setClipRegion( const Region& rRegion ) +void PDFWriterImpl::setClipRegion( const basegfx::B2DPolyPolygon& rRegion ) { - Region aRegion = getReferenceDevice()->LogicToPixel( rRegion, m_aGraphicsStack.front().m_aMapMode ); + basegfx::B2DPolyPolygon aRegion = getReferenceDevice()->LogicToPixel( rRegion, m_aGraphicsStack.front().m_aMapMode ); aRegion = getReferenceDevice()->PixelToLogic( aRegion, m_aMapMode ); m_aGraphicsStack.front().m_aClipRegion = aRegion; + m_aGraphicsStack.front().m_bClipRegion = true; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion; } void PDFWriterImpl::moveClipRegion( sal_Int32 nX, sal_Int32 nY ) { - Point aPoint( lcl_convert( m_aGraphicsStack.front().m_aMapMode, + if( m_aGraphicsStack.front().m_bClipRegion && m_aGraphicsStack.front().m_aClipRegion.count() ) + { + Point aPoint( lcl_convert( m_aGraphicsStack.front().m_aMapMode, + m_aMapMode, + getReferenceDevice(), + Point( nX, nY ) ) ); + aPoint -= lcl_convert( m_aGraphicsStack.front().m_aMapMode, m_aMapMode, getReferenceDevice(), - Point( nX, nY ) ) ); - aPoint -= lcl_convert( m_aGraphicsStack.front().m_aMapMode, - m_aMapMode, - getReferenceDevice(), - Point() ); - m_aGraphicsStack.front().m_aClipRegion.Move( aPoint.X(), aPoint.Y() ); - m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion; + Point() ); + basegfx::B2DHomMatrix aMat; + aMat.translate( aPoint.X(), aPoint.Y() ); + m_aGraphicsStack.front().m_aClipRegion.transform( aMat ); + m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion; + } } bool PDFWriterImpl::intersectClipRegion( const Rectangle& rRect ) { - Rectangle aRect( lcl_convert( m_aGraphicsStack.front().m_aMapMode, - m_aMapMode, - getReferenceDevice(), - rRect ) ); - m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion; - return m_aGraphicsStack.front().m_aClipRegion.Intersect( aRect ); + basegfx::B2DPolyPolygon aRect( basegfx::tools::createPolygonFromRect( + basegfx::B2DRectangle( rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() ) ) ); + return intersectClipRegion( aRect ); } -bool PDFWriterImpl::intersectClipRegion( const Region& rRegion ) +bool PDFWriterImpl::intersectClipRegion( const basegfx::B2DPolyPolygon& rRegion ) { - Region aRegion = getReferenceDevice()->LogicToPixel( rRegion, m_aGraphicsStack.front().m_aMapMode ); + basegfx::B2DPolyPolygon aRegion( getReferenceDevice()->LogicToPixel( rRegion, m_aGraphicsStack.front().m_aMapMode ) ); aRegion = getReferenceDevice()->PixelToLogic( aRegion, m_aMapMode ); m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion; - return m_aGraphicsStack.front().m_aClipRegion.Intersect( aRegion ); + if( m_aGraphicsStack.front().m_bClipRegion ) + { + basegfx::B2DPolyPolygon aOld( basegfx::tools::prepareForPolygonOperation( m_aGraphicsStack.front().m_aClipRegion ) ); + aRegion = basegfx::tools::prepareForPolygonOperation( aRegion ); + m_aGraphicsStack.front().m_aClipRegion = basegfx::tools::solvePolygonOperationAnd( aOld, aRegion ); + } + else + { + m_aGraphicsStack.front().m_aClipRegion = aRegion; + m_aGraphicsStack.front().m_bClipRegion = true; + } + return true; } void PDFWriterImpl::createNote( const Rectangle& rRect, const PDFNote& rNote, sal_Int32 nPageNr ) @@ -11528,18 +11735,7 @@ sal_Int32 PDFWriterImpl::findRadioGroupWidget( const PDFWriter::RadioButtonWidge m_aWidgets.back().m_nRadioGroup = rBtn.RadioGroup; m_aWidgets.back().m_nFlags |= 0x00008000; - // create radio button field name - const rtl::OUString& rName = (m_aContext.Version > PDFWriter::PDF_1_2) ? - rBtn.Name : rBtn.Text; - if( rName.getLength() ) - { - m_aWidgets.back().m_aName = convertWidgetFieldName( rName ); - } - else - { - m_aWidgets.back().m_aName = "RadioGroup"; - m_aWidgets.back().m_aName += OString::valueOf( rBtn.RadioGroup ); - } + createWidgetFieldName( sal_Int32(m_aWidgets.size()-1), rBtn ); } else nRadioGroupWidget = it->second; @@ -11555,44 +11751,27 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa if( nPageNr < 0 || nPageNr >= (sal_Int32)m_aPages.size() ) return -1; + sal_Int32 nNewWidget = m_aWidgets.size(); m_aWidgets.push_back( PDFWidget() ); - sal_Int32 nNewWidget = m_aWidgets.size()-1; - - // create eventual radio button before getting any references - // from m_aWidgets as the push_back operation potentially assigns new - // memory to the vector and thereby invalidates the reference - int nRadioGroupWidget = -1; - if( rControl.getType() == PDFWriter::RadioButton ) - nRadioGroupWidget = findRadioGroupWidget( static_cast<const PDFWriter::RadioButtonWidget&>(rControl) ); - PDFWidget& rNewWidget = m_aWidgets[nNewWidget]; - rNewWidget.m_nObject = createObject(); - rNewWidget.m_aRect = rControl.Location; - rNewWidget.m_nPage = nPageNr; - rNewWidget.m_eType = rControl.getType(); + m_aWidgets.back().m_nObject = createObject(); + m_aWidgets.back().m_aRect = rControl.Location; + m_aWidgets.back().m_nPage = nPageNr; + m_aWidgets.back().m_eType = rControl.getType(); + sal_Int32 nRadioGroupWidget = -1; // for unknown reasons the radio buttons of a radio group must not have a // field name, else the buttons are in fact check boxes - // that is multiple buttons of the radio group can be selected - if( rControl.getType() != PDFWriter::RadioButton ) + if( rControl.getType() == PDFWriter::RadioButton ) + nRadioGroupWidget = findRadioGroupWidget( static_cast<const PDFWriter::RadioButtonWidget&>(rControl) ); + else { - // acrobat reader since 3.0 does not support unicode text - // strings for the field name; so we need to encode unicodes - // larger than 255 - - rNewWidget.m_aName = - convertWidgetFieldName( (m_aContext.Version > PDFWriter::PDF_1_2) ? - rControl.Name : rControl.Text ); - // #i88040# acrobat reader crashes on empty field names, - // so always create one - if( rNewWidget.m_aName.getLength() == 0 ) - { - OUStringBuffer aBuf( 32 ); - aBuf.appendAscii( "Widget" ); - aBuf.append( nNewWidget ); - rNewWidget.m_aName = convertWidgetFieldName( aBuf.makeStringAndClear() ); - } + createWidgetFieldName( nNewWidget, rControl ); } + + // caution: m_aWidgets must not be changed after here or rNewWidget may be invalid + PDFWidget& rNewWidget = m_aWidgets[nNewWidget]; rNewWidget.m_aDescription = rControl.Description; rNewWidget.m_aText = rControl.Text; rNewWidget.m_nTextStyle = rControl.TextStyle & @@ -11823,6 +12002,7 @@ bool PDFWriterImpl::endControlAppearance( PDFWriter::WidgetState eState ) break; case PDFWriter::ListBox: case PDFWriter::ComboBox: + case PDFWriter::Hierarchy: break; } if( aState.getLength() && aStyle.getLength() ) diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 4adf54ea98a3..2eacdc215dd8 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -146,14 +146,20 @@ public: // if pOutPoint is set it will be updated to the emitted point // (in PDF map mode, that is 10th of point) void appendPoint( const Point& rPoint, rtl::OStringBuffer& rBuffer, bool bNeg = false, Point* pOutPoint = NULL ) const; + // appends a B2DPoint without further transformation + void appendPixelPoint( const basegfx::B2DPoint& rPoint, rtl::OStringBuffer& rBuffer ) const; // appends a rectangle void appendRect( const Rectangle& rRect, rtl::OStringBuffer& rBuffer ) const; // converts a rectangle to 10th points page space void convertRect( Rectangle& rRect ) const; // appends a polygon optionally closing it void appendPolygon( const Polygon& rPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; + // appends a polygon optionally closing it + void appendPolygon( const basegfx::B2DPolygon& rPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; // appends a polypolygon optionally closing the subpaths void appendPolyPolygon( const PolyPolygon& rPolyPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; + // appends a polypolygon optionally closing the subpaths + void appendPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; // converts a length (either vertical or horizontal; this // can be important if the source MapMode is not // symmetrical) to page length and appends it to the buffer @@ -161,7 +167,7 @@ public: // (in PDF map mode, that is 10th of point) void appendMappedLength( sal_Int32 nLength, rtl::OStringBuffer& rBuffer, bool bVertical = true, sal_Int32* pOutLength = NULL ) const; // the same for double values - void appendMappedLength( double fLength, rtl::OStringBuffer& rBuffer, bool bVertical = true, sal_Int32* pOutLength = NULL ) const; + void appendMappedLength( double fLength, rtl::OStringBuffer& rBuffer, bool bVertical = true, sal_Int32* pOutLength = NULL, sal_Int32 nPrecision = 5 ) const; // appends LineInfo // returns false if too many dash array entry were created for // the implementation limits of some PDF readers @@ -695,19 +701,20 @@ private: // graphics state struct GraphicsState { - Font m_aFont; - MapMode m_aMapMode; - Color m_aLineColor; - Color m_aFillColor; - Color m_aTextLineColor; - Color m_aOverlineColor; - Region m_aClipRegion; - sal_Int32 m_nAntiAlias; - sal_Int32 m_nLayoutMode; - LanguageType m_aDigitLanguage; - sal_Int32 m_nTransparentPercent; - sal_uInt16 m_nFlags; - sal_uInt16 m_nUpdateFlags; + Font m_aFont; + MapMode m_aMapMode; + Color m_aLineColor; + Color m_aFillColor; + Color m_aTextLineColor; + Color m_aOverlineColor; + basegfx::B2DPolyPolygon m_aClipRegion; + bool m_bClipRegion; + sal_Int32 m_nAntiAlias; + sal_Int32 m_nLayoutMode; + LanguageType m_aDigitLanguage; + sal_Int32 m_nTransparentPercent; + sal_uInt16 m_nFlags; + sal_uInt16 m_nUpdateFlags; static const sal_uInt16 updateFont = 0x0001; static const sal_uInt16 updateMapMode = 0x0002; @@ -726,6 +733,7 @@ private: m_aFillColor( COL_TRANSPARENT ), m_aTextLineColor( COL_TRANSPARENT ), m_aOverlineColor( COL_TRANSPARENT ), + m_bClipRegion( false ), m_nAntiAlias( 1 ), m_nLayoutMode( 0 ), m_aDigitLanguage( 0 ), @@ -741,6 +749,7 @@ private: m_aTextLineColor( rState.m_aTextLineColor ), m_aOverlineColor( rState.m_aOverlineColor ), m_aClipRegion( rState.m_aClipRegion ), + m_bClipRegion( rState.m_bClipRegion ), m_nAntiAlias( rState.m_nAntiAlias ), m_nLayoutMode( rState.m_nLayoutMode ), m_aDigitLanguage( rState.m_aDigitLanguage ), @@ -759,6 +768,7 @@ private: m_aTextLineColor = rState.m_aTextLineColor; m_aOverlineColor = rState.m_aOverlineColor; m_aClipRegion = rState.m_aClipRegion; + m_bClipRegion = rState.m_bClipRegion; m_nAntiAlias = rState.m_nAntiAlias; m_nLayoutMode = rState.m_nLayoutMode; m_aDigitLanguage = rState.m_aDigitLanguage; @@ -1049,7 +1059,7 @@ i12626 void createDefaultListBoxAppearance( PDFWidget&, const PDFWriter::ListBoxWidget& rWidget ); /* ensure proper escapement and uniqueness of field names */ - rtl::OString convertWidgetFieldName( const rtl::OUString& rString ); + void createWidgetFieldName( sal_Int32 i_nWidgetsIndex, const PDFWriter::AnyWidget& i_rInWidget ); /* adds an entry to m_aObjects and returns its index+1, * sets the offset to ~0 */ @@ -1209,17 +1219,18 @@ public: void clearClipRegion() { - m_aGraphicsStack.front().m_aClipRegion.SetNull(); + m_aGraphicsStack.front().m_aClipRegion.clear(); + m_aGraphicsStack.front().m_bClipRegion = false; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion; } - void setClipRegion( const Region& rRegion ); + void setClipRegion( const basegfx::B2DPolyPolygon& rRegion ); void moveClipRegion( sal_Int32 nX, sal_Int32 nY ); bool intersectClipRegion( const Rectangle& rRect ); - bool intersectClipRegion( const Region& rRegion ); + bool intersectClipRegion( const basegfx::B2DPolyPolygon& rRegion ); void setLayoutMode( sal_Int32 nLayoutMode ) { diff --git a/vcl/source/gdi/pngwrite.cxx b/vcl/source/gdi/pngwrite.cxx index bd28135ca498..47152ea6ac11 100644 --- a/vcl/source/gdi/pngwrite.cxx +++ b/vcl/source/gdi/pngwrite.cxx @@ -131,6 +131,7 @@ PNGWriterImpl::PNGWriterImpl( const BitmapEx& rBmpEx, mpAccess ( NULL ), mpMaskAccess ( NULL ), mpZCodec ( new ZCodec( DEFAULT_IN_BUFSIZE, DEFAULT_OUT_BUFSIZE, MAX_MEM_USAGE ) ), + mnCRC(0UL), mnLastPercent ( 0UL ) { if ( !rBmpEx.IsEmpty() ) diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx index de7cd2e139da..191f8f26dc75 100644 --- a/vcl/source/gdi/print3.cxx +++ b/vcl/source/gdi/print3.cxx @@ -36,6 +36,7 @@ #include "vcl/svids.hrc" #include "vcl/metaact.hxx" #include "vcl/msgbox.hxx" +#include "vcl/configsettings.hxx" #include "tools/urlobj.hxx" @@ -171,13 +172,15 @@ public: // set by user through printer config dialog // if set, pages are centered and trimmed onto the fixed page Size maFixedPageSize; + sal_Int32 mnDefaultPaperBin; ImplPrinterControllerData() : mbFirstPage( sal_True ), mbLastPage( sal_False ), mbReversePageOrder( sal_False ), meJobState( view::PrintableState_JOB_STARTED ), - mpProgress( NULL ) + mpProgress( NULL ), + mnDefaultPaperBin( -1 ) {} ~ImplPrinterControllerData() { delete mpProgress; } @@ -327,9 +330,25 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr // setup printer // if no specific printer is already set, create one + + // #i108686# + // in case of a UI (platform independent or system dialog) print job, make the printer persistent over jobs + // however if no printer was already set by the print job's originator, + // and this is an API job, then use the system default location (because + // this is the only sensible default available if the user has no means of changing + // the destination if( ! pController->getPrinter() ) { - boost::shared_ptr<Printer> pPrinter( new Printer( i_rInitSetup.GetPrinterName() ) ); + rtl::OUString aPrinterName( i_rInitSetup.GetPrinterName() ); + if( ! aPrinterName.getLength() && pController->isShowDialogs() && ! pController->isDirectPrint() ) + { + // get printer name from configuration + SettingsConfigItem* pItem = SettingsConfigItem::get(); + aPrinterName = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinterUsed" ) ) ); + } + + boost::shared_ptr<Printer> pPrinter( new Printer( aPrinterName ) ); pController->setPrinter( pPrinter ); } @@ -440,7 +459,12 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr return; } pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ), - makeAny( aFile ) ); + makeAny( aFile ) ); + } + else if( aDlg.isSingleJobs() ) + { + pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ), + makeAny( sal_True ) ); } } catch( std::bad_alloc& ) @@ -501,6 +525,13 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: if ( !mpPrinter ) return FALSE; + sal_Bool bSinglePrintJobs = sal_False; + beans::PropertyValue* pSingleValue = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) ); + if( pSingleValue ) + { + pSingleValue->Value >>= bSinglePrintJobs; + } + // remark: currently it is still possible to use EnablePrintFile and // SetPrintFileName to redirect printout into file // it can be argued that those methods should be removed in favor @@ -514,6 +545,7 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: { mbPrintFile = TRUE; maPrintFile = aFile; + bSinglePrintJobs = sal_False; } } @@ -561,49 +593,90 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: i_pController->setJobState( view::PrintableState_JOB_STARTED ); i_pController->jobStarted(); - if( mpPrinter->StartJob( pPrintFile, - i_rJobName, - Application::GetDisplayName(), - nCopies, - bCollateCopy, - i_pController->isDirectPrint(), - maJobSetup.ImplGetConstData() ) ) + int nJobs = 1; + int nRepeatCount = bUserCopy ? mnCopyCount : 1; + if( bSinglePrintJobs ) { - mbJobActive = TRUE; - i_pController->createProgressDialog(); - int nPages = i_pController->getFilteredPageCount(); - int nRepeatCount = bUserCopy ? mnCopyCount : 1; - for( int nIteration = 0; nIteration < nRepeatCount; nIteration++ ) + nJobs = mnCopyCount; + nCopies = 1; + nRepeatCount = 1; + } + + for( int nJobIteration = 0; nJobIteration < nJobs; nJobIteration++ ) + { + bool bError = false; + if( mpPrinter->StartJob( pPrintFile, + i_rJobName, + Application::GetDisplayName(), + nCopies, + bCollateCopy, + i_pController->isDirectPrint(), + maJobSetup.ImplGetConstData() ) ) { - for( int nPage = 0; nPage < nPages; nPage++ ) + mbJobActive = TRUE; + i_pController->createProgressDialog(); + int nPages = i_pController->getFilteredPageCount(); + for( int nIteration = 0; nIteration < nRepeatCount; nIteration++ ) { - if( nPage == nPages-1 && nIteration == nRepeatCount-1 ) - i_pController->setLastPage( sal_True ); - i_pController->printFilteredPage( nPage ); + for( int nPage = 0; nPage < nPages; nPage++ ) + { + if( nPage == nPages-1 && nIteration == nRepeatCount-1 && nJobIteration == nJobs-1 ) + i_pController->setLastPage( sal_True ); + i_pController->printFilteredPage( nPage ); + } + // FIXME: duplex ? + } + EndJob(); + + if( nJobIteration < nJobs-1 ) + { + mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter ); + + if ( mpPrinter ) + { + maJobName = i_rJobName; + mnCurPage = 1; + mnCurPrintPage = 1; + mbPrinting = TRUE; + } + else + bError = true; } - // FIXME: duplex ? } - EndJob(); + else + bError = true; - if( i_pController->getJobState() == view::PrintableState_JOB_STARTED ) - i_pController->setJobState( view::PrintableState_JOB_SPOOLED ); + if( bError ) + { + mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() ); + if ( !mnError ) + mnError = PRINTER_GENERALERROR; + i_pController->setJobState( mnError == PRINTER_ABORT + ? view::PrintableState_JOB_ABORTED + : view::PrintableState_JOB_FAILED ); + if( mpPrinter ) + pSVData->mpDefInst->DestroyPrinter( mpPrinter ); + mnCurPage = 0; + mnCurPrintPage = 0; + mbPrinting = FALSE; + mpPrinter = NULL; + + return false; + } } - else - { - mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() ); - if ( !mnError ) - mnError = PRINTER_GENERALERROR; - i_pController->setJobState( mnError == PRINTER_ABORT - ? view::PrintableState_JOB_ABORTED - : view::PrintableState_JOB_FAILED ); - pSVData->mpDefInst->DestroyPrinter( mpPrinter ); - mnCurPage = 0; - mnCurPrintPage = 0; - mbPrinting = FALSE; - mpPrinter = NULL; - return false; - } + if( i_pController->getJobState() == view::PrintableState_JOB_STARTED ) + i_pController->setJobState( view::PrintableState_JOB_SPOOLED ); + } + + // make last used printer persistent for UI jobs + if( i_pController->isShowDialogs() && ! i_pController->isDirectPrint() ) + { + SettingsConfigItem* pItem = SettingsConfigItem::get(); + pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinterUsed" ) ), + GetName() + ); } return true; @@ -634,6 +707,7 @@ void PrinterController::setPrinter( const boost::shared_ptr<Printer>& i_rPrinter mpImplData->mpPrinter = i_rPrinter; setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ), makeAny( rtl::OUString( i_rPrinter->GetName() ) ) ); + mpImplData->mnDefaultPaperBin = mpImplData->mpPrinter->GetPaperBin(); } bool PrinterController::setupPrinter( Window* i_pParent ) @@ -668,27 +742,55 @@ PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( cons { PrinterController::PageSize aPageSize; aPageSize.aSize = mpPrinter->GetPaperSize(); + awt::Size aSetSize, aIsSize; + sal_Int32 nPaperBin = mnDefaultPaperBin; for( sal_Int32 nProperty = 0, nPropertyCount = i_rProps.getLength(); nProperty < nPropertyCount; ++nProperty ) { - if( i_rProps[ nProperty ].Name.equalsAscii( "PageSize" ) ) + if( i_rProps[ nProperty ].Name.equalsAscii( "PreferredPageSize" ) ) { - awt::Size aSize; - i_rProps[ nProperty].Value >>= aSize; - aPageSize.aSize.Width() = aSize.Width; - aPageSize.aSize.Height() = aSize.Height; - - Size aCurSize( mpPrinter->GetPaperSize() ); - Size aRealPaperSize( getRealPaperSize( aPageSize.aSize ) ); - if( aRealPaperSize != aCurSize ) - mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() ); + i_rProps[ nProperty ].Value >>= aSetSize; } - if( i_rProps[ nProperty ].Name.equalsAscii( "PageIncludesNonprintableArea" ) ) + else if( i_rProps[ nProperty ].Name.equalsAscii( "PageSize" ) ) + { + i_rProps[ nProperty ].Value >>= aIsSize; + } + else if( i_rProps[ nProperty ].Name.equalsAscii( "PageIncludesNonprintableArea" ) ) { sal_Bool bVal = sal_False; - i_rProps[ nProperty].Value >>= bVal; + i_rProps[ nProperty ].Value >>= bVal; aPageSize.bFullPaper = static_cast<bool>(bVal); } + else if( i_rProps[ nProperty ].Name.equalsAscii( "PrinterPaperTray" ) ) + { + sal_Int32 nBin = -1; + i_rProps[ nProperty ].Value >>= nBin; + if( nBin >= 0 && nBin < mpPrinter->GetPaperBinCount() ) + nPaperBin = nBin; + } + } + + Size aCurSize( mpPrinter->GetPaperSize() ); + if( aSetSize.Width && aSetSize.Height ) + { + Size aSetPaperSize( aSetSize.Width, aSetSize.Height ); + Size aRealPaperSize( getRealPaperSize( aSetPaperSize ) ); + if( aRealPaperSize != aCurSize ) + aIsSize = aSetSize; } + + if( aIsSize.Width && aIsSize.Height ) + { + aPageSize.aSize.Width() = aIsSize.Width; + aPageSize.aSize.Height() = aIsSize.Height; + + Size aRealPaperSize( getRealPaperSize( aPageSize.aSize ) ); + if( aRealPaperSize != aCurSize ) + mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() ); + } + + if( nPaperBin != -1 && nPaperBin != mpPrinter->GetPaperBin() ) + mpPrinter->SetPaperBin( nPaperBin ); + return aPageSize; } @@ -1393,6 +1495,8 @@ void PrinterController::createProgressDialog() mpImplData->mpProgress->Show(); } } + else + mpImplData->mpProgress->reset(); } void PrinterController::setMultipage( const MultiPageSetup& i_rMPS ) diff --git a/vcl/source/gdi/region.cxx b/vcl/source/gdi/region.cxx index 07351e1c0fce..4931ee66e93f 100644 --- a/vcl/source/gdi/region.cxx +++ b/vcl/source/gdi/region.cxx @@ -45,6 +45,7 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/range/b2drange.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> @@ -2004,6 +2005,32 @@ const basegfx::B2DPolyPolygon Region::GetB2DPolyPolygon() const // ----------------------------------------------------------------------- +basegfx::B2DPolyPolygon Region::ConvertToB2DPolyPolygon() +{ + DBG_CHKTHIS( Region, ImplDbgTestRegion ); + + basegfx::B2DPolyPolygon aRet; + + if( HasPolyPolygon() ) + aRet = GetB2DPolyPolygon(); + else + { + RegionHandle aHdl = BeginEnumRects(); + Rectangle aSubRect; + while( GetNextEnumRect( aHdl, aSubRect ) ) + { + basegfx::B2DPolygon aPoly( basegfx::tools::createPolygonFromRect( + basegfx::B2DRectangle( aSubRect.Left(), aSubRect.Top(), aSubRect.Right(), aSubRect.Bottom() ) ) ); + aRet.append( aPoly ); + } + EndEnumRects( aHdl ); + } + + return aRet; +} + +// ----------------------------------------------------------------------- + BOOL Region::ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo, long& rX, long& rY, long& rWidth, long& rHeight ) const diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 9354b0f72130..55d6f7bdd892 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -689,6 +689,12 @@ void SalGraphics::mirror( ControlType nType, const ImplControlValue& rVal, const { switch( nType ) { + case CTRL_SLIDER: + { + SliderValue* pSlVal = reinterpret_cast<SliderValue*>(rVal.getOptionalVal()); + mirror(pSlVal->maThumbRect,pOutDev,bBack); + } + break; case CTRL_SCROLLBAR: { ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(rVal.getOptionalVal()); diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index 344867ebb0b0..bf462d1d8add 100755 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -133,13 +133,13 @@ int GetVerticalFlags( sal_UCS4 nChar ) /* #i52932# remember: nChar == 0x2010 || nChar == 0x2015 nChar == 0x2016 || nChar == 0x2026 - are GF_NONE also, but already handled in the first if */ if((nChar >= 0x3008 && nChar <= 0x301C && nChar != 0x3012) - || nChar == 0xFF3B || nChar == 0xFF3D + || (nChar == 0xFF3B || nChar == 0xFF3D) || (nChar >= 0xFF5B && nChar <= 0xFF9F) // halfwidth forms - || nChar == 0xFFE3 ) + || (nChar == 0xFFE3) + || (nChar >= 0x02F800 && nChar <= 0x02FFFF) ) return GF_NONE; // not rotated else if( nChar == 0x30fc ) return GF_ROTR; // right diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx index a337f2553ff7..ebdd59f517af 100644 --- a/vcl/source/glyphs/gcach_ftyp.cxx +++ b/vcl/source/glyphs/gcach_ftyp.cxx @@ -38,8 +38,6 @@ #include "vcl/svapp.hxx" #include "vcl/outfont.hxx" #include "vcl/impfont.hxx" -#include "vcl/bitmap.hxx" -#include "vcl/bmpacc.hxx" #include "tools/poly.hxx" #include "basegfx/matrix/b2dhommatrix.hxx" @@ -80,7 +78,7 @@ typedef FT_Vector* FT_Vector_CPtr; // TODO: move file mapping stuff to OSL #if defined(UNX) #if !defined(HPUX) - // PORTERS: dlfcn is used for code dependend on FT version + // PORTERS: dlfcn is used for getting symbols from FT versions newer than baseline #include <dlfcn.h> #endif #include <unistd.h> @@ -93,10 +91,6 @@ typedef FT_Vector* FT_Vector_CPtr; #define strncasecmp strnicmp #endif -#include "vcl/svapp.hxx" -#include "vcl/settings.hxx" -#include "i18npool/lang.h" - typedef const unsigned char* CPU8; inline sal_uInt16 NEXT_U16( CPU8& p ) { p+=2; return (p[-2]<<8)|p[-1]; } inline sal_Int16 NEXT_S16( CPU8& p ) { return (sal_Int16)NEXT_U16(p); } @@ -623,9 +617,6 @@ long FreetypeManager::AddFontDir( const String& rUrlName ) aDFA.mbSubsettable= false; aDFA.mbEmbeddable = false; - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - FT_Done_Face( aFaceFT ); AddFontFile( aCFileName, nFaceNum, ++mnNextFontId, aDFA, NULL ); ++nCount; @@ -705,6 +696,7 @@ FreetypeServerFont::FreetypeServerFont( const ImplFontSelectData& rFSD, FtFontIn : ServerFont( rFSD ), mnPrioEmbedded(nDefaultPrioEmbedded), mnPrioAntiAlias(nDefaultPrioAntiAlias), + mnPrioAutoHint(nDefaultPrioAutoHint), mpFontInfo( pFI ), maFaceFT( NULL ), maSizeFT( NULL ), @@ -838,46 +830,71 @@ FreetypeServerFont::FreetypeServerFont( const ImplFontSelectData& rFSD, FtFontIn mbArtItalic = (rFSD.meItalic != ITALIC_NONE && pFI->GetFontAttributes().GetSlant() == ITALIC_NONE); mbArtBold = (rFSD.meWeight > WEIGHT_MEDIUM && pFI->GetFontAttributes().GetWeight() <= WEIGHT_MEDIUM); - - //static const int TT_CODEPAGE_RANGE_874 = (1L << 16); // Thai - //static const int TT_CODEPAGE_RANGE_932 = (1L << 17); // JIS/Japan - //static const int TT_CODEPAGE_RANGE_936 = (1L << 18); // Chinese: Simplified - //static const int TT_CODEPAGE_RANGE_949 = (1L << 19); // Korean Wansung - //static const int TT_CODEPAGE_RANGE_950 = (1L << 20); // Chinese: Traditional - //static const int TT_CODEPAGE_RANGE_1361 = (1L << 21); // Korean Johab - static const int TT_CODEPAGE_RANGES1_CJKT = 0x3F0000; // all of the above - const TT_OS2* pOs2 = (const TT_OS2*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_os2 ); - if ((pOs2) && (pOs2->ulCodePageRange1 & TT_CODEPAGE_RANGES1_CJKT ) + mbUseGamma = false; + if( mbArtBold ) + { + //static const int TT_CODEPAGE_RANGE_874 = (1L << 16); // Thai + //static const int TT_CODEPAGE_RANGE_932 = (1L << 17); // JIS/Japan + //static const int TT_CODEPAGE_RANGE_936 = (1L << 18); // Chinese: Simplified + //static const int TT_CODEPAGE_RANGE_949 = (1L << 19); // Korean Wansung + //static const int TT_CODEPAGE_RANGE_950 = (1L << 20); // Chinese: Traditional + //static const int TT_CODEPAGE_RANGE_1361 = (1L << 21); // Korean Johab + static const int TT_CODEPAGE_RANGES1_CJKT = 0x3F0000; // all of the above + const TT_OS2* pOs2 = (const TT_OS2*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_os2 ); + if ((pOs2) && (pOs2->ulCodePageRange1 & TT_CODEPAGE_RANGES1_CJKT ) && rFSD.mnHeight < 20) mbUseGamma = true; - else - mbUseGamma = false; + } + + if( ((mnCos != 0) && (mnSin != 0)) || (mnPrioEmbedded <= 0) ) + mnLoadFlags |= FT_LOAD_NO_BITMAP; +} + +void FreetypeServerFont::SetFontOptions( const ImplFontOptions& rFontOptions) +{ + FontAutoHint eHint = rFontOptions.GetUseAutoHint(); + if( eHint == AUTOHINT_DONTKNOW ) + eHint = mbUseGamma ? AUTOHINT_TRUE : AUTOHINT_FALSE; - if (mbUseGamma) + if( eHint == AUTOHINT_TRUE ) mnLoadFlags |= FT_LOAD_FORCE_AUTOHINT; if( (mnSin != 0) && (mnCos != 0) ) // hinting for 0/90/180/270 degrees only mnLoadFlags |= FT_LOAD_NO_HINTING; mnLoadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; //#88334# - if (mpFontInfo->DontUseAntiAlias()) - mnPrioAntiAlias = 0; - if (mpFontInfo->DontUseEmbeddedBitmaps()) - mnPrioEmbedded = 0; + if( rFontOptions.DontUseAntiAlias() ) + mnPrioAntiAlias = 0; + if( rFontOptions.DontUseEmbeddedBitmaps() ) + mnPrioEmbedded = 0; + if( rFontOptions.DontUseHinting() ) + mnPrioAutoHint = 0; #if (FTVERSION >= 2005) || defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER) - if( nDefaultPrioAutoHint <= 0 ) + if( mnPrioAutoHint <= 0 ) #endif mnLoadFlags |= FT_LOAD_NO_HINTING; -#ifdef FT_LOAD_TARGET_LIGHT - // enable "light hinting" if available +#if defined(FT_LOAD_TARGET_LIGHT) && defined(FT_LOAD_TARGET_NORMAL) if( !(mnLoadFlags & FT_LOAD_NO_HINTING) && (nFTVERSION >= 2103)) - mnLoadFlags |= FT_LOAD_TARGET_LIGHT; + { + mnLoadFlags |= FT_LOAD_TARGET_NORMAL; + switch( rFontOptions.GetHintStyle() ) + { + case HINT_NONE: + mnLoadFlags |= FT_LOAD_NO_HINTING; + break; + case HINT_SLIGHT: + mnLoadFlags |= FT_LOAD_TARGET_LIGHT; + break; + case HINT_MEDIUM: + break; + case HINT_FULL: + default: + break; + } + } #endif - - if( ((mnCos != 0) && (mnSin != 0)) || (mnPrioEmbedded <= 0) ) - mnLoadFlags |= FT_LOAD_NO_BITMAP; } // ----------------------------------------------------------------------- @@ -1231,13 +1248,15 @@ int FreetypeServerFont::FixupGlyphIndex( int nGlyphIndex, sal_UCS4 aChar ) const } } -#if !defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER) +#if 0 // #95556# autohinting not yet optimized for non-western glyph styles if( !(mnLoadFlags & (FT_LOAD_NO_HINTING | FT_LOAD_FORCE_AUTOHINT) ) && ( (aChar >= 0x0600 && aChar < 0x1E00) // south-east asian + arabic ||(aChar >= 0x2900 && aChar < 0xD800) // CJKV ||(aChar >= 0xF800) ) ) // presentation + symbols + { nGlyphFlags |= GF_UNHINTED; + } #endif if( nGlyphIndex != 0 ) @@ -1377,13 +1396,13 @@ bool FreetypeServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap nLoadFlags |= FT_LOAD_NO_BITMAP; #if (FTVERSION >= 2002) - // for 0/90/180/270 degree fonts enable autohinting even if not advisable + // for 0/90/180/270 degree fonts enable hinting even if not advisable // non-hinted and non-antialiased bitmaps just look too ugly - if( (mnCos==0 || mnSin==0) && (nDefaultPrioAutoHint > 0) ) + if( (mnCos==0 || mnSin==0) && (mnPrioAutoHint > 0) ) nLoadFlags &= ~FT_LOAD_NO_HINTING; #endif - if( mnPrioEmbedded <= nDefaultPrioAutoHint ) + if( mnPrioEmbedded <= mnPrioAutoHint ) nLoadFlags |= FT_LOAD_NO_BITMAP; FT_Error rc = -1; @@ -1548,7 +1567,7 @@ bool FreetypeServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap // autohinting in FT<=2.0.4 makes antialiased glyphs look worse nLoadFlags |= FT_LOAD_NO_HINTING; #else - if( (nGlyphFlags & GF_UNHINTED) || (nDefaultPrioAutoHint < mnPrioAntiAlias) ) + if( (nGlyphFlags & GF_UNHINTED) || (mnPrioAutoHint < mnPrioAntiAlias) ) nLoadFlags |= FT_LOAD_NO_HINTING; #endif diff --git a/vcl/source/glyphs/gcach_ftyp.hxx b/vcl/source/glyphs/gcach_ftyp.hxx index 2a181b494c9f..5ebe70bcbdf9 100644 --- a/vcl/source/glyphs/gcach_ftyp.hxx +++ b/vcl/source/glyphs/gcach_ftyp.hxx @@ -33,6 +33,7 @@ #include <ft2build.h> #include FT_FREETYPE_H + class FreetypeServerFont; struct FT_GlyphRec_; @@ -85,10 +86,6 @@ public: int GetFaceNum() const { return mnFaceNum; } int GetSynthetic() const { return mnSynthetic; } sal_IntPtr GetFontId() const { return mnFontId; } - bool DontUseAntiAlias() const - { return maDevFontAttributes.UseAntiAlias() == ANTIALIAS_FALSE; } - bool DontUseEmbeddedBitmaps() const - { return maDevFontAttributes.UseEmbeddedBitmap() == EMBEDDEDBITMAP_FALSE; } bool IsSymbolFont() const { return maDevFontAttributes.IsSymbolFont(); } const ImplFontAttributes& GetFontAttributes() const { return maDevFontAttributes; } @@ -178,6 +175,7 @@ public: virtual int GetFontFaceNum() const { return mpFontInfo->GetFaceNum(); } virtual bool TestFont() const; virtual void* GetFtFace() const; + virtual void SetFontOptions( const ImplFontOptions&); virtual int GetLoadFlags() const { return (mnLoadFlags & ~FT_LOAD_IGNORE_TRANSFORM); } virtual bool NeedsArtificialBold() const { return mbArtBold; } virtual bool NeedsArtificialItalic() const { return mbArtItalic; } @@ -213,6 +211,7 @@ private: int mnWidth; int mnPrioEmbedded; int mnPrioAntiAlias; + int mnPrioAutoHint; FtFontInfo* mpFontInfo; FT_Int mnLoadFlags; double mfStretch; diff --git a/vcl/source/glyphs/glyphcache.cxx b/vcl/source/glyphs/glyphcache.cxx index 34133a39ac95..ea0f18896b7a 100644 --- a/vcl/source/glyphs/glyphcache.cxx +++ b/vcl/source/glyphs/glyphcache.cxx @@ -69,13 +69,22 @@ GlyphCache::GlyphCache( GlyphCachePeer& rPeer ) GlyphCache::~GlyphCache() { -// TODO: -// for( FontList::iterator it = maFontList.begin(); it != maFontList.end(); ++it ) -// delete const_cast<ServerFont*>( it->second ); + InvalidateAllGlyphs(); if( mpFtManager ) delete mpFtManager; } +// ----------------------------------------------------------------------- + +void GlyphCache::InvalidateAllGlyphs() +{ +#if 0 // TODO: implement uncaching of all glyph shapes and metrics + for( FontList::iterator it = maFontList.begin(); it != maFontList.end(); ++it ) + delete const_cast<ServerFont*>( it->second ); + maFontList.clear(); + mpCurrentGCFont = NULL; +#endif +} // ----------------------------------------------------------------------- @@ -582,3 +591,4 @@ int ExtraKernInfo::GetUnscaledKernValue( sal_Unicode cLeft, sal_Unicode cRight ) } // ======================================================================= + diff --git a/vcl/source/glyphs/graphite_adaptors.cxx b/vcl/source/glyphs/graphite_adaptors.cxx index 4afced765612..f66f5b48e39e 100644 --- a/vcl/source/glyphs/graphite_adaptors.cxx +++ b/vcl/source/glyphs/graphite_adaptors.cxx @@ -168,7 +168,7 @@ GraphiteFontAdaptor::~GraphiteFontAdaptor() throw() mpFeatures = NULL; } -void GraphiteFontAdaptor::UniqueCacheInfo(sil_std::wstring & face_name_out, bool & bold_out, bool & italic_out) +void GraphiteFontAdaptor::UniqueCacheInfo(ext_std::wstring & face_name_out, bool & bold_out, bool & italic_out) { face_name_out = maFontProperties.szFaceName; bold_out = maFontProperties.fBold; diff --git a/vcl/source/glyphs/graphite_cache.cxx b/vcl/source/glyphs/graphite_cache.cxx index 713f3c1ed088..64bbb0a38d60 100644 --- a/vcl/source/glyphs/graphite_cache.cxx +++ b/vcl/source/glyphs/graphite_cache.cxx @@ -36,10 +36,10 @@ #include <tools/debug.hxx> #include <vcl/sallayout.hxx> -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Segment.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> #include <rtl/ustring.hxx> #include <vcl/graphite_layout.hxx> diff --git a/vcl/source/glyphs/graphite_features.cxx b/vcl/source/glyphs/graphite_features.cxx index bae96642da30..1cb25306c4ee 100644 --- a/vcl/source/glyphs/graphite_features.cxx +++ b/vcl/source/glyphs/graphite_features.cxx @@ -88,7 +88,7 @@ GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string features, co gr::isocode aLang = maLang; for (size_t i = pos; i < nFeatEnd; i++) aLang.rgch[i-pos] = features[i]; - sil_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported + ext_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported = font.getSupportedLanguages(); gr::LanguageIterator iL = aSupported.first; while (iL != aSupported.second) @@ -139,7 +139,7 @@ void GrFeatureParser::setLang(gr::Font & font, const std::string & lang) if (lang[i] == '-') break; aLang.rgch[i] = lang[i]; } - sil_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported + ext_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported = font.getSupportedLanguages(); gr::LanguageIterator iL = aSupported.first; while (iL != aSupported.second) @@ -186,7 +186,7 @@ bool GrFeatureParser::isValid(gr::Font & font, gr::FeatureSetting & setting) { return false; } - sil_std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator > + ext_std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator > validValues = font.getFeatureSettings(i); gr::FeatureSettingIterator j = validValues.first; while (j != validValues.second) diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx index 25ea77dd07a3..6e75d1fde868 100644 --- a/vcl/source/glyphs/graphite_layout.cxx +++ b/vcl/source/glyphs/graphite_layout.cxx @@ -63,13 +63,13 @@ #include <unicode/uscript.h> // Graphite Libraries (must be after vcl headers on windows) -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> #include <graphite/Segment.h> #include <graphite/SegmentPainter.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> #include <vcl/graphite_layout.hxx> #include <vcl/graphite_features.hxx> @@ -104,8 +104,8 @@ FILE * grLog() namespace { - typedef sil_std::pair<gr::GlyphIterator, gr::GlyphIterator> glyph_range_t; - typedef sil_std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t; + typedef ext_std::pair<gr::GlyphIterator, gr::GlyphIterator> glyph_range_t; + typedef ext_std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t; inline long round(const float n) { return long(n + (n < 0 ? -0.5 : 0.5)); @@ -170,7 +170,7 @@ GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs, bool bRtl, long &rWidth, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs) { // Create a glyph item for each of the glyph and append it to the base class glyph list. - typedef sil_std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet; + typedef ext_std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet; int nChar = rArgs.mnEndCharPos - rArgs.mnMinCharPos; glyph_range_t iGlyphs = rSegment.glyphs(); int nGlyphs = iGlyphs.second - iGlyphs.first; @@ -585,7 +585,7 @@ public: sal_Int32 hashCode(const grutils::GrFeatureParser * mpFeatures) { // is this sufficient? - sil_std::wstring aFace; + ext_std::wstring aFace; bool bBold; bool bItalic; UniqueCacheInfo(aFace, bBold, bItalic); diff --git a/vcl/source/glyphs/graphite_textsrc.cxx b/vcl/source/glyphs/graphite_textsrc.cxx index d7547662e065..5764ba9454c9 100644 --- a/vcl/source/glyphs/graphite_textsrc.cxx +++ b/vcl/source/glyphs/graphite_textsrc.cxx @@ -135,16 +135,16 @@ gr::isocode TextSourceAdaptor::getLanguage(gr::toffset) return unknown; } -sil_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx) +ext_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx) { if (nCharIdx < unsigned(maLayoutArgs.mnMinCharPos)) - return sil_std::make_pair(0, maLayoutArgs.mnMinCharPos); + return ext_std::make_pair(0, maLayoutArgs.mnMinCharPos); if (nCharIdx < mnEnd) - return sil_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd); + return ext_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd); - return sil_std::make_pair(mnEnd, maLayoutArgs.mnLength); + return ext_std::make_pair(mnEnd, maLayoutArgs.mnLength); } size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * settings) @@ -156,7 +156,7 @@ size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * sett bool TextSourceAdaptor::sameSegment(gr::toffset char_idx1, gr::toffset char_idx2) { - const sil_std::pair<gr::toffset, gr::toffset> + const ext_std::pair<gr::toffset, gr::toffset> range1 = propertyRange(char_idx1), range2 = propertyRange(char_idx2); diff --git a/vcl/source/glyphs/graphite_textsrc.hxx b/vcl/source/glyphs/graphite_textsrc.hxx index 2397d6a5f701..2b9c705a5ea7 100644 --- a/vcl/source/glyphs/graphite_textsrc.hxx +++ b/vcl/source/glyphs/graphite_textsrc.hxx @@ -59,11 +59,11 @@ #include "vcl/dllapi.h" // Libraries -#include "pregraphitestl.h" +#include <tools/preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> -#include "postgraphitestl.h" +#include <tools/postextstl.h> // Module type definitions and forward declarations. // @@ -90,7 +90,7 @@ public: virtual float getVerticalOffset(gr::toffset ich); virtual gr::isocode getLanguage(gr::toffset ich); - virtual sil_std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich); + virtual ext_std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich); virtual size_t getFontFeatures(gr::toffset ich, gr::FeatureSetting * prgfset); virtual bool sameSegment(gr::toffset ich1, gr::toffset ich2); diff --git a/vcl/source/helper/xconnection.cxx b/vcl/source/helper/xconnection.cxx index 19ac9103bf96..caf7ee237d67 100644 --- a/vcl/source/helper/xconnection.cxx +++ b/vcl/source/helper/xconnection.cxx @@ -141,12 +141,16 @@ bool DisplayConnection::dispatchEvent( void* pThis, void* pData, int nBytes ) SolarMutexReleaser aRel; DisplayConnection* This = (DisplayConnection*)pThis; - MutexGuard aGuard( This->m_aMutex ); Sequence< sal_Int8 > aSeq( (sal_Int8*)pData, nBytes ); Any aEvent; aEvent <<= aSeq; - for( ::std::list< Reference< XEventHandler > >::const_iterator it = This->m_aHandlers.begin(); it != This->m_aHandlers.end(); ++it ) + ::std::list< Reference< XEventHandler > > handlers; + { + MutexGuard aGuard( This->m_aMutex ); + handlers = This->m_aHandlers; + } + for( ::std::list< Reference< XEventHandler > >::const_iterator it = handlers.begin(); it != handlers.end(); ++it ) if( (*it)->handleEvent( aEvent ) ) return true; return false; @@ -157,12 +161,16 @@ bool DisplayConnection::dispatchErrorEvent( void* pThis, void* pData, int nBytes SolarMutexReleaser aRel; DisplayConnection* This = (DisplayConnection*)pThis; - MutexGuard aGuard( This->m_aMutex ); Sequence< sal_Int8 > aSeq( (sal_Int8*)pData, nBytes ); Any aEvent; aEvent <<= aSeq; - for( ::std::list< Reference< XEventHandler > >::const_iterator it = This->m_aErrorHandlers.begin(); it != This->m_aErrorHandlers.end(); ++it ) + ::std::list< Reference< XEventHandler > > handlers; + { + MutexGuard aGuard( This->m_aMutex ); + handlers = This->m_aErrorHandlers; + } + for( ::std::list< Reference< XEventHandler > >::const_iterator it = handlers.begin(); it != handlers.end(); ++it ) if( (*it)->handleEvent( aEvent ) ) return true; diff --git a/vcl/source/window/decoview.cxx b/vcl/source/window/decoview.cxx index 03675ccf69ca..a32790cfb0d4 100644 --- a/vcl/source/window/decoview.cxx +++ b/vcl/source/window/decoview.cxx @@ -1353,3 +1353,36 @@ Rectangle DecorationView::DrawButton( const Rectangle& rRect, USHORT nStyle ) return aRect; } + +// ----------------------------------------------------------------------- + +void DecorationView::DrawSeparator( const Point& rStart, const Point& rStop, bool bVertical ) +{ + Point aStart( rStart ), aStop( rStop ); + const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings(); + + mpOutDev->Push( PUSH_LINECOLOR ); + if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) + mpOutDev->SetLineColor( Color( COL_BLACK ) ); + else + mpOutDev->SetLineColor( rStyleSettings.GetShadowColor() ); + + mpOutDev->DrawLine( aStart, aStop ); + if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ) + { + mpOutDev->SetLineColor( rStyleSettings.GetLightColor() ); + if( bVertical ) + { + aStart.X()++; + aStop.X()++; + } + else + { + aStart.Y()++; + aStop.Y()++; + } + mpOutDev->DrawLine( aStart, aStop ); + } + mpOutDev->Pop(); +} + diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx index daa26e2c7782..64f2b7e0d2a1 100644 --- a/vcl/source/window/dlgctrl.cxx +++ b/vcl/source/window/dlgctrl.cxx @@ -886,20 +886,6 @@ BOOL Window::ImplDlgCtrl( const KeyEvent& rKEvt, BOOL bKeyInput ) return TRUE; } - // if we have come here (and therefore the strange "formular" logic above - // turned up no result, then let's try to find a customer for Ctrl-TAB - if ( nKeyCode == KEY_TAB && aKeyCode.IsMod1() && ! aKeyCode.IsMod2() ) - { - TabDialog* pDlg = dynamic_cast<TabDialog*>(this); - if( pDlg ) - { - TabControl* pTabCtrl = pDlg->ImplGetFirstTabControl(); - NotifyEvent aEvt( bKeyInput ? EVENT_KEYINPUT : EVENT_KEYUP, - pTabCtrl, &rKEvt ); - return pTabCtrl->ImplHandleNotifyEvent( aEvt ); - } - } - return FALSE; } @@ -1093,10 +1079,15 @@ Window* Window::GetLabelFor() const return pWindow; sal_Unicode nAccel = getAccel( GetText() ); - if( GetType() == WINDOW_FIXEDTEXT || - GetType() == WINDOW_FIXEDLINE || - GetType() == WINDOW_GROUPBOX ) + + WindowType nMyType = GetType(); + if( nMyType == WINDOW_FIXEDTEXT || + nMyType == WINDOW_FIXEDLINE || + nMyType == WINDOW_GROUPBOX ) { + // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text. + // See tools/options/print for example. + BOOL bThisIsAGroupControl = (nMyType == WINDOW_GROUPBOX) || (nMyType == WINDOW_FIXEDLINE); Window* pSWindow = NULL; // get index, form start and form end USHORT nIndex=0, nFormStart=0, nFormEnd=0; @@ -1128,9 +1119,14 @@ Window* Window::GetLabelFor() const FALSE ); if( pSWindow && pSWindow->IsVisible() && ! (pSWindow->GetStyle() & WB_NOLABEL) ) { - if( pSWindow->GetType() != WINDOW_FIXEDTEXT && - pSWindow->GetType() != WINDOW_FIXEDLINE && - pSWindow->GetType() != WINDOW_GROUPBOX ) + WindowType nType = pSWindow->GetType(); + if( nType != WINDOW_FIXEDTEXT && + nType != WINDOW_FIXEDLINE && + nType != WINDOW_GROUPBOX ) + { + pWindow = pSWindow; + } + else if( bThisIsAGroupControl && ( nType == WINDOW_FIXEDTEXT ) ) { pWindow = pSWindow; } @@ -1163,9 +1159,13 @@ Window* Window::GetLabeledBy() const if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON ) return NULL; - if( ! ( GetType() == WINDOW_FIXEDTEXT || - GetType() == WINDOW_FIXEDLINE || - GetType() == WINDOW_GROUPBOX ) ) +// if( ! ( GetType() == WINDOW_FIXEDTEXT || +// GetType() == WINDOW_FIXEDLINE || +// GetType() == WINDOW_GROUPBOX ) ) + // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text. + // See tools/options/print for example. + WindowType nMyType = GetType(); + if ( (nMyType != WINDOW_GROUPBOX) && (nMyType != WINDOW_FIXEDLINE) ) { // search for a control that labels this window // a label is considered the last fixed text, fixed line or group box @@ -1196,14 +1196,18 @@ Window* Window::GetLabeledBy() const nSearchIndex, nFoundIndex, FALSE ); - if( pSWindow && pSWindow->IsVisible() && - ! (pSWindow->GetStyle() & WB_NOLABEL) && - ( pSWindow->GetType() == WINDOW_FIXEDTEXT || - pSWindow->GetType() == WINDOW_FIXEDLINE || - pSWindow->GetType() == WINDOW_GROUPBOX ) ) + if( pSWindow && pSWindow->IsVisible() && !(pSWindow->GetStyle() & WB_NOLABEL) ) { - pWindow = pSWindow; - break; + WindowType nType = pSWindow->GetType(); + if ( ( nType == WINDOW_FIXEDTEXT || + nType == WINDOW_FIXEDLINE || + nType == WINDOW_GROUPBOX ) ) + { + // a fixed text can't be labeld by a fixed text. + if ( ( nMyType != WINDOW_FIXEDTEXT ) || ( nType != WINDOW_FIXEDTEXT ) ) + pWindow = pSWindow; + break; + } } if( nFoundIndex > nSearchIndex || nSearchIndex == 0 ) break; diff --git a/vcl/source/window/introwin.cxx b/vcl/source/window/introwin.cxx index 02ccc2282a42..03f88adc3566 100644 --- a/vcl/source/window/introwin.cxx +++ b/vcl/source/window/introwin.cxx @@ -77,3 +77,12 @@ void IntroWindow::SetBackgroundBitmap( const Bitmap& rBitmap ) ImplGetFrame()->SetBackgroundBitmap( pBmp ); } } + +void IntroWindow::SetBackgroundBitmap( const BitmapEx& rBitmapEx ) +{ + if( ! rBitmapEx.IsEmpty() ) + { + SalBitmap* pBmp = rBitmapEx.ImplGetBitmapImpBitmap()->ImplGetSalBitmap(); + ImplGetFrame()->SetBackgroundBitmap( pBmp ); + } +} diff --git a/vcl/source/window/mnemonic.cxx b/vcl/source/window/mnemonic.cxx index 74926ad3de4b..c2c6c18135f2 100644 --- a/vcl/source/window/mnemonic.cxx +++ b/vcl/source/window/mnemonic.cxx @@ -332,39 +332,41 @@ BOOL MnemonicGenerator::CreateMnemonic( XubString& rKey ) } } - if( ! bChanged ) - { - /* - * #97809# if all else fails use the first character of a word - * anyway and live with duplicate mnemonics - */ - nIndex = 0; - do - { - c = aKey.GetChar( nIndex ); - - nMnemonicIndex = ImplGetMnemonicIndex( c ); - if ( nMnemonicIndex != MNEMONIC_INDEX_NOTFOUND ) - { - maMnemonics[nMnemonicIndex] = 0; - rKey.Insert( MNEMONIC_CHAR, nIndex ); - bChanged = TRUE; - break; - } - - // Search for next word - do - { - nIndex++; - c = aKey.GetChar( nIndex ); - if ( c == ' ' ) - break; - } - while ( nIndex < nLen ); - nIndex++; - } - while ( nIndex < nLen ); - } +// #i87415# Duplicates mnemonics are bad for consistent keyboard accessibility +// It's probably better to not have mnemonics for some widgets, than to have ambiguous ones. +// if( ! bChanged ) +// { +// /* +// * #97809# if all else fails use the first character of a word +// * anyway and live with duplicate mnemonics +// */ +// nIndex = 0; +// do +// { +// c = aKey.GetChar( nIndex ); +// +// nMnemonicIndex = ImplGetMnemonicIndex( c ); +// if ( nMnemonicIndex != MNEMONIC_INDEX_NOTFOUND ) +// { +// maMnemonics[nMnemonicIndex] = 0; +// rKey.Insert( MNEMONIC_CHAR, nIndex ); +// bChanged = TRUE; +// break; +// } +// +// // Search for next word +// do +// { +// nIndex++; +// c = aKey.GetChar( nIndex ); +// if ( c == ' ' ) +// break; +// } +// while ( nIndex < nLen ); +// nIndex++; +// } +// while ( nIndex < nLen ); +// } return bChanged; } diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index caf5705cbcd9..33e58b51d6d0 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -42,16 +42,22 @@ #include "vcl/help.hxx" #include "vcl/decoview.hxx" #include "vcl/svapp.hxx" +#include "vcl/unohelp.hxx" #include "unotools/localedatawrapper.hxx" #include "rtl/ustrbuf.hxx" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/container/XNameAccess.hpp" +#include "com/sun/star/beans/PropertyValue.hpp" #include "com/sun/star/awt/Size.hpp" using namespace vcl; using namespace com::sun::star; using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; using namespace com::sun::star::beans; #define HELPID_PREFIX ".HelpId:vcl:PrintDialog" @@ -66,7 +72,7 @@ PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const Re { SetPaintTransparent( TRUE ); SetBackground(); - if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + if( useHCColorReplacement() ) maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); else maPageVDev.SetBackground( Color( COL_WHITE ) ); @@ -76,12 +82,76 @@ PrintDialog::PrintPreviewWindow::~PrintPreviewWindow() { } +bool PrintDialog::PrintPreviewWindow::useHCColorReplacement() const +{ + bool bRet = false; + if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + { + try + { + // get service provider + Reference< XMultiServiceFactory > xSMgr( unohelper::GetMultiServiceFactory() ); + // create configuration hierachical access name + if( xSMgr.is() ) + { + try + { + Reference< XMultiServiceFactory > xConfigProvider( + Reference< XMultiServiceFactory >( + xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationProvider" ))), + UNO_QUERY ) + ); + if( xConfigProvider.is() ) + { + Sequence< Any > aArgs(1); + PropertyValue aVal; + aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); + aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Accessibility" ) ); + aArgs.getArray()[0] <<= aVal; + Reference< XNameAccess > xConfigAccess( + Reference< XNameAccess >( + xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationAccess" )), + aArgs ), + UNO_QUERY ) + ); + if( xConfigAccess.is() ) + { + try + { + sal_Bool bValue = sal_False; + Any aAny = xConfigAccess->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsForPagePreviews" ) ) ); + if( aAny >>= bValue ) + bRet = bool(bValue); + } + catch( NoSuchElementException& ) + { + } + catch( WrappedTargetException& ) + { + } + } + } + } + catch( Exception& ) + { + } + } + } + catch( WrappedTargetException& ) + { + } + } + return bRet; +} + void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDCEvt ) { // react on settings changed if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS ) { - if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + if( useHCColorReplacement() ) maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); else maPageVDev.SetBackground( Color( COL_WHITE ) ); @@ -118,6 +188,23 @@ void PrintDialog::PrintPreviewWindow::Resize() } aScaledSize.Width() = long(aScaledSize.Width()*fScale); aScaledSize.Height() = long(aScaledSize.Height()*fScale); + + maPreviewSize = aScaledSize; + + // #i104784# if we render the page too small then rounding issues result in + // layout artifacts looking really bad. So scale the page unto a device that is not + // full page size but not too small either. This also results in much better visual + // quality of the preview, e.g. when its height approaches the number of text lines + // find a good scaling factor + Size aPreviewMMSize( maPageVDev.PixelToLogic( aScaledSize, MapMode( MAP_100TH_MM ) ) ); + double fZoom = double(maOrigSize.Height())/double(aPreviewMMSize.Height()); + while( fZoom > 10 ) + { + aScaledSize.Width() *= 2; + aScaledSize.Height() *= 2; + fZoom /= 2.0; + } + maPageVDev.SetOutputSizePixel( aScaledSize, FALSE ); } @@ -129,9 +216,14 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) // replacement is active Push(); Rectangle aTextRect( Point( 0, 0 ), aSize ); - Font aFont( GetSettings().GetStyleSettings().GetFieldFont() ); - aFont.SetSize( Size( 0, aSize.Height()/12 ) ); - SetFont( aFont ); + DecorationView aVw( this ); + aVw.DrawFrame( aTextRect, FRAME_DRAW_GROUP ); + aTextRect.Left() += 2; + aTextRect.Top() += 2; + aTextRect.Right() -= 2; + aTextRect.Bottom() -= 2; + Font aFont( GetSettings().GetStyleSettings().GetLabelFont() ); + SetZoomedPointFont( aFont ); DrawText( aTextRect, maReplacementString, TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE ); @@ -141,11 +233,11 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) { GDIMetaFile aMtf( maMtf ); - Size aPreviewSize = maPageVDev.GetOutputSizePixel(); - Point aOffset( (aSize.Width() - aPreviewSize.Width()) / 2, - (aSize.Height() - aPreviewSize.Height()) / 2 ); + Point aOffset( (aSize.Width() - maPreviewSize.Width()) / 2, + (aSize.Height() - maPreviewSize.Height()) / 2 ); - const Size aLogicSize( maPageVDev.PixelToLogic( aPreviewSize, MapMode( MAP_100TH_MM ) ) ); + Size aVDevSize( maPageVDev.GetOutputSizePixel() ); + const Size aLogicSize( maPageVDev.PixelToLogic( aVDevSize, MapMode( MAP_100TH_MM ) ) ); Size aOrigSize( maOrigSize ); if( aOrigSize.Width() < 1 ) aOrigSize.Width() = aLogicSize.Width(); @@ -165,11 +257,11 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) SetMapMode( MAP_PIXEL ); maPageVDev.SetMapMode( MAP_PIXEL ); - DrawOutDev( aOffset, aPreviewSize, Point( 0, 0 ), aPreviewSize, maPageVDev ); + DrawOutDev( aOffset, maPreviewSize, Point( 0, 0 ), aVDevSize, maPageVDev ); DecorationView aVw( this ); - aOffset.X() -= 1; aOffset.Y() -=1; aPreviewSize.Width() += 2; aPreviewSize.Height() += 2; - aVw.DrawFrame( Rectangle( aOffset, aPreviewSize ), FRAME_DRAW_GROUP ); + Rectangle aFrame( aOffset + Point( -1, -1 ), Size( maPreviewSize.Width() + 2, maPreviewSize.Height() + 2 ) ); + aVw.DrawFrame( aFrame, FRAME_DRAW_GROUP ); } } @@ -211,9 +303,7 @@ void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPrevi #endif SetQuickHelpText( aBuf.makeStringAndClear() ); maMtf = i_rNewPreview; - if( GetSettings().GetStyleSettings().GetHighContrastMode() && - GetSettings().GetStyleSettings().GetWindowColor().IsDark() - ) + if( useHCColorReplacement() ) { maMtf.ReplaceColors( Color( COL_BLACK ), Color( COL_WHITE ), 30 ); } @@ -834,6 +924,7 @@ PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterCont maNUpPage.maBorderCB.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); maOptionsPage.maToFileBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); maOptionsPage.maReverseOrderBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + maOptionsPage.maCollateSingleJobsBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); maNUpPage.maPagesBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); // setup modify hdl @@ -1027,6 +1118,11 @@ bool PrintDialog::isCollate() return maJobPage.maCopyCountField.GetValue() > 1 ? maJobPage.maCollateBox.IsChecked() : FALSE; } +bool PrintDialog::isSingleJobs() +{ + return maOptionsPage.maCollateSingleJobsBox.IsChecked(); +} + static void setSmartId( Window* i_pWindow, const char* i_pType, sal_Int32 i_nId = -1, const rtl::OUString& i_rPropName = rtl::OUString() ) { rtl::OUStringBuffer aBuf( 256 ); @@ -1049,10 +1145,17 @@ static void setSmartId( Window* i_pWindow, const char* i_pType, sal_Int32 i_nId i_pWindow->SetSmartHelpId( SmartId( aBuf.makeStringAndClear(), HID_PRINTDLG ) ); } -static void setHelpText( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpTexts, sal_Int32 i_nIndex ) +static void setHelpText( Window* /*i_pWindow*/, const Sequence< rtl::OUString >& /*i_rHelpTexts*/, sal_Int32 /*i_nIndex*/ ) { + // without a help text set and the correct smartID, + // help texts will be retrieved from the online help system + + // passed help texts for optional UI is used only for native dialogs which currently + // cannot access the same (rather implicit) mechanism + #if 0 if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() ) i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] ); + #endif } void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) @@ -1572,6 +1675,12 @@ void PrintDialog::setupOptionalUI() maJobPage.maLayout.setBorders( nIndex-1, 0, 0, 0, aBorder.Width() ); #endif + // create auto mnemomnics now so they can be calculated in layout + ImplWindowAutoMnemonic( &maJobPage ); + ImplWindowAutoMnemonic( &maNUpPage ); + ImplWindowAutoMnemonic( &maOptionsPage ); + ImplWindowAutoMnemonic( this ); + // calculate job page Size aMaxSize = maJobPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ); // and layout page @@ -1654,6 +1763,7 @@ void PrintDialog::checkControlDependencies() maJobPage.maCollateImage.SetSizePixel( aImgSize ); maJobPage.maCollateImage.SetImage( bHC ? aHCImg : aImg ); maJobPage.maCollateImage.SetModeImage( aHCImg, BMP_COLOR_HIGHCONTRAST ); + maJobPage.maLayout.resize(); // enable setup button only for printers that can be setup bool bHaveSetup = maPController->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG ); @@ -2444,6 +2554,11 @@ void PrintProgressDialog::tick() setProgress( ++mnCur ); } +void PrintProgressDialog::reset() +{ + setProgress( 0 ); +} + void PrintProgressDialog::Paint( const Rectangle& ) { if( maProgressRect.IsEmpty() ) diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx index 9987dae32dbb..c139ae1ffb30 100644 --- a/vcl/source/window/status.cxx +++ b/vcl/source/window/status.cxx @@ -61,13 +61,17 @@ public: ~ImplData(); VirtualDevice* mpVirDev; - BOOL mbTopBorder:1; + long mnItemBorderWidth; + bool mbTopBorder:1; + bool mbDrawItemFrames:1; }; StatusBar::ImplData::ImplData() { mpVirDev = NULL; - mbTopBorder = FALSE; + mbTopBorder = false; + mbDrawItemFrames = false; + mnItemBorderWidth = 0; } StatusBar::ImplData::~ImplData() @@ -351,9 +355,7 @@ Rectangle StatusBar::ImplGetItemRectPos( USHORT nPos ) const { Rectangle aRect; ImplStatusItem* pItem; - pItem = mpItemList->GetObject( nPos ); - if ( pItem ) { if ( pItem->mbVisible ) @@ -372,6 +374,25 @@ Rectangle StatusBar::ImplGetItemRectPos( USHORT nPos ) const // ----------------------------------------------------------------------- +USHORT StatusBar::ImplGetFirstVisiblePos() const +{ + ImplStatusItem* pItem; + + for( USHORT nPos = 0; nPos < mpItemList->Count(); nPos++ ) + { + pItem = mpItemList->GetObject( nPos ); + if ( pItem ) + { + if ( pItem->mbVisible ) + return nPos; + } + } + + return ~0; +} + +// ----------------------------------------------------------------------- + void StatusBar::ImplDrawText( BOOL bOffScreen, long nOldTextWidth ) { // Das ueberschreiben der Item-Box verhindern @@ -418,8 +439,9 @@ void StatusBar::ImplDrawItem( BOOL bOffScreen, USHORT nPos, BOOL bDrawText, BOOL // Ausgabebereich berechnen ImplStatusItem* pItem = mpItemList->GetObject( nPos ); - Rectangle aTextRect( aRect.Left()+1, aRect.Top()+1, - aRect.Right()-1, aRect.Bottom()-1 ); + long nW = mpImplData->mnItemBorderWidth + 1; + Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW, + aRect.Right()-nW, aRect.Bottom()-nW ); Size aTextRectSize( aTextRect.GetSize() ); if ( bOffScreen ) @@ -470,17 +492,36 @@ void StatusBar::ImplDrawItem( BOOL bOffScreen, USHORT nPos, BOOL bDrawText, BOOL SetClipRegion(); // Frame ausgeben - if ( bDrawFrame && !(pItem->mnBits & SIB_FLAT) ) + if ( bDrawFrame ) { - USHORT nStyle; + if( mpImplData->mbDrawItemFrames ) + { + if( !(pItem->mnBits & SIB_FLAT) ) + { + USHORT nStyle; - if ( pItem->mnBits & SIB_IN ) - nStyle = FRAME_DRAW_IN; - else - nStyle = FRAME_DRAW_OUT; + if ( pItem->mnBits & SIB_IN ) + nStyle = FRAME_DRAW_IN; + else + nStyle = FRAME_DRAW_OUT; + + DecorationView aDecoView( this ); + aDecoView.DrawFrame( aRect, nStyle ); + } + } + else if( nPos != ImplGetFirstVisiblePos() ) + { + // draw separator + Point aFrom( aRect.TopLeft() ); + aFrom.X()--; + aFrom.Y()++; + Point aTo( aRect.BottomLeft() ); + aTo.X()--; + aTo.Y()--; - DecorationView aDecoView( this ); - aDecoView.DrawFrame( aRect, nStyle ); + DecorationView aDecoView( this ); + aDecoView.DrawSeparator( aFrom, aTo ); + } } if ( !ImplIsRecordLayout() ) @@ -688,8 +729,6 @@ void StatusBar::ImplCalcProgressRect() } if( ! bNativeOK ) maPrgsTxtPos.Y() = mnTextY; - - } // ----------------------------------------------------------------------- @@ -1227,8 +1266,11 @@ Rectangle StatusBar::GetItemRect( USHORT nItemId ) const { // Rechteck holen und Rahmen abziehen aRect = ImplGetItemRectPos( nPos ); - aRect.Left()++; - aRect.Right()--; + long nW = mpImplData->mnItemBorderWidth+1; + aRect.Top() += nW-1; + aRect.Bottom() -= nW-1; + aRect.Left() += nW; + aRect.Right() -= nW; return aRect; } } @@ -1248,8 +1290,9 @@ Point StatusBar::GetItemTextPos( USHORT nItemId ) const // Rechteck holen ImplStatusItem* pItem = mpItemList->GetObject( nPos ); Rectangle aRect = ImplGetItemRectPos( nPos ); - Rectangle aTextRect( aRect.Left()+1, aRect.Top()+1, - aRect.Right()-1, aRect.Bottom()-1 ); + long nW = mpImplData->mnItemBorderWidth + 1; + Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW, + aRect.Right()-nW, aRect.Bottom()-nW ); Point aPos = ImplGetItemTextPos( aTextRect.GetSize(), Size( GetTextWidth( pItem->maText ), GetTextHeight() ), pItem->mnBits ); @@ -1524,9 +1567,9 @@ void StatusBar::SetBottomBorder( BOOL bBottomBorder ) void StatusBar::SetTopBorder( BOOL bTopBorder ) { - if ( mpImplData->mbTopBorder != bTopBorder ) + if ( mpImplData->mbTopBorder != static_cast<bool>(bTopBorder) ) { - mpImplData->mbTopBorder = bTopBorder; + mpImplData->mbTopBorder = static_cast<bool>(bTopBorder); ImplCalcBorder(); } } @@ -1690,7 +1733,22 @@ Size StatusBar::CalcWindowSizePixel() const } } - nCalcHeight = nMinHeight+nBarTextOffset; + if( mpImplData->mbDrawItemFrames && + pThis->IsNativeControlSupported( CTRL_FRAME, PART_BORDER ) ) + { + ImplControlValue aControlValue( FRAME_DRAW_NODRAW ); + Region aBound, aContent; + Region aNatRgn( Rectangle( Point( 0, 0 ), Size( 150, 50 ) ) ); + if( pThis->GetNativeControlRegion(CTRL_FRAME, PART_BORDER, + aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) ) + { + mpImplData->mnItemBorderWidth = + ( aBound.GetBoundRect().GetHeight() - + aContent.GetBoundRect().GetHeight() ) / 2; + } + } + + nCalcHeight = nMinHeight+nBarTextOffset + 2*mpImplData->mnItemBorderWidth; if( nCalcHeight < nProgressHeight+2 ) nCalcHeight = nProgressHeight+2; diff --git a/vcl/source/window/tabdlg.cxx b/vcl/source/window/tabdlg.cxx index 02a8b6a5b717..874881c0c5ef 100644 --- a/vcl/source/window/tabdlg.cxx +++ b/vcl/source/window/tabdlg.cxx @@ -274,20 +274,3 @@ void TabDialog::AdjustLayout() ImplPosControls(); } -// ----------------------------------------------------------------------- - -TabControl* TabDialog::ImplGetFirstTabControl() const -{ - Window* pChild = GetWindow( WINDOW_FIRSTCHILD ); - while ( pChild ) - { - if ( pChild->IsVisible() && (pChild != mpViewWindow) ) - { - if ( pChild->GetType() == WINDOW_TABCONTROL ) - return (TabControl*)pChild; - } - pChild = pChild->GetWindow( WINDOW_NEXT ); - } - return NULL; -} - diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 516bc53d8920..b47aa50a2e72 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -502,6 +502,13 @@ void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, BOOL bCallHdl ) } } + static const char* pEnvHC = getenv( "SAL_FORCE_HC" ); + if( pEnvHC && *pEnvHC ) + { + aStyleSettings.SetHighContrastMode( TRUE ); + rSettings.SetStyleSettings( aStyleSettings ); + } + #ifdef DBG_UTIL // Evt. AppFont auf Fett schalten, damit man feststellen kann, // ob fuer die Texte auf anderen Systemen genuegend Platz @@ -8147,7 +8154,7 @@ const XubString& Window::GetHelpText() const { rtl::OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() ); aTxt.append( mpWindowImpl->maHelpText ); - aTxt.appendAscii( "\n+++++++++++++++\n" ); + aTxt.appendAscii( "\n------------------\n" ); if( bStrHelpId ) aTxt.append( rtl::OUString( aStrHelpId ) ); else diff --git a/vcl/source/window/window3.cxx b/vcl/source/window/window3.cxx index 9c10c5f131bf..aecbc9c3ef0c 100644 --- a/vcl/source/window/window3.cxx +++ b/vcl/source/window/window3.cxx @@ -104,6 +104,12 @@ void Window::ImplMoveControlValue( ControlType nType, const ImplControlValue& aV { switch( nType ) { + case CTRL_SLIDER: + { + SliderValue* pSlVal = reinterpret_cast<SliderValue*>(aValue.getOptionalVal()); + pSlVal->maThumbRect.Move( rDelta.X(), rDelta.Y() ); + } + break; case CTRL_SCROLLBAR: { ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(aValue.getOptionalVal()); diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index 93e1b0837429..95ac5940b6d2 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -295,7 +295,7 @@ static BOOL ImplCallCommand( Window* pChild, USHORT nEvt, void* pData = NULL, else { // simulate mouseposition at center of window - Size aSize = pChild->GetOutputSize(); + Size aSize( pChild->GetOutputSizePixel() ); aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 ); } } diff --git a/vcl/unx/gtk/a11y/atkbridge.cxx b/vcl/unx/gtk/a11y/atkbridge.cxx index 9498c4570ae0..47efde7d3dfd 100644 --- a/vcl/unx/gtk/a11y/atkbridge.cxx +++ b/vcl/unx/gtk/a11y/atkbridge.cxx @@ -41,7 +41,7 @@ bool InitAtkBridge(void) const char* pVersion = atk_get_toolkit_version(); if( ! pVersion ) { - g_warning( "unable to get gail version number" ); + // g_warning( "unable to get gail version number" ); return false; } @@ -50,7 +50,7 @@ bool InitAtkBridge(void) /* check gail minimum version requirements */ if( sscanf( pVersion, "%u.%u.%u", &major, &minor, µ) < 3 ) { - g_warning( "unable to parse gail version number" ); + // g_warning( "unable to parse gail version number" ); return false; } diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx index 6ed99d0cf3a3..13492f3d4a5c 100644 --- a/vcl/unx/gtk/a11y/atkutil.cxx +++ b/vcl/unx/gtk/a11y/atkutil.cxx @@ -500,6 +500,7 @@ static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent) /*****************************************************************************/ +/* currently not needed anymore... static void create_wrapper_for_children(Window *pWindow) { if( pWindow && pWindow->IsReallyVisible() ) @@ -517,6 +518,7 @@ static void create_wrapper_for_children(Window *pWindow) } } } +*/ /*****************************************************************************/ @@ -695,7 +697,11 @@ long WindowEventHandler(void *, ::VclSimpleEvent const * pEvent) break; case VCLEVENT_COMBOBOX_SETTEXT: - create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); + // MT 2010/02: This looks quite strange to me. Stumbled over this when fixing #i104290#. + // This kicked in when leaving the combobox in the toolbar, after that the events worked. + // I guess this was a try to work around missing combobox events, which didn't do the full job, and shouldn't be necessary anymore. + // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general. + // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); break; default: diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx index b1529e060270..d1e5c5954352 100644 --- a/vcl/unx/gtk/app/gtkdata.cxx +++ b/vcl/unx/gtk/app/gtkdata.cxx @@ -221,8 +221,7 @@ void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen ) { GdkRectangle dest; gdk_screen_get_monitor_geometry(pScreen, i, &dest); - m_aXineramaScreens.push_back( Rectangle( Point(dest.x, - dest.y ), Size( dest.width, dest.height ) ) ); + addXineramaScreenUnique( dest.x, dest.y, dest.width, dest.height ); } m_bXinerama = m_aXineramaScreens.size() > 1; if( ! m_aFrames.empty() ) @@ -663,7 +662,8 @@ void GtkXLib::Init() if( pScreen ) { g_signal_connect( G_OBJECT(pScreen), "size-changed", G_CALLBACK(signalScreenSizeChanged), m_pGtkSalDisplay ); - g_signal_connect( G_OBJECT(pScreen), "monitors-changed", G_CALLBACK(signalMonitorsChanged), m_pGtkSalDisplay ); + if( ! gtk_check_version( 2, 14, 0 ) ) // monitors-changed came in with 2.14, avoid an assertion + g_signal_connect( G_OBJECT(pScreen), "monitors-changed", G_CALLBACK(signalMonitorsChanged), m_pGtkSalDisplay ); } } } diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 372d10fa5aaf..de4d55b0230a 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -45,6 +45,8 @@ #include "saldisp.hxx" #include "vcl/svapp.hxx" +typedef struct _cairo_font_options cairo_font_options_t; + // initialize statics BOOL GtkSalGraphics::bThemeChanged = TRUE; BOOL GtkSalGraphics::bNeedPixmapPaint = FALSE; @@ -97,6 +99,8 @@ struct NWFWidgetData GtkWidget * gTooltipPopup; GtkWidget * gProgressBar; GtkWidget * gTreeView; + GtkWidget * gHScale; + GtkWidget * gVScale; NWPixmapCacheList* gNWPixmapCacheList; NWPixmapCache* gCacheTabItems; @@ -129,10 +133,12 @@ struct NWFWidgetData gMenuItemMenuWidget( NULL ), gMenuItemCheckMenuWidget( NULL ), gMenuItemRadioMenuWidget( NULL ), - gImageMenuItem( NULL ), + gImageMenuItem( NULL ), gTooltipPopup( NULL ), gProgressBar( NULL ), gTreeView( NULL ), + gHScale( NULL ), + gVScale( NULL ), gNWPixmapCacheList( NULL ), gCacheTabItems( NULL ), gCacheTabPages( NULL ) @@ -170,6 +176,7 @@ static void NWEnsureGTKMenu ( int nScreen ); static void NWEnsureGTKTooltip ( int nScreen ); static void NWEnsureGTKProgressBar ( int nScreen ); static void NWEnsureGTKTreeView ( int nScreen ); +static void NWEnsureGTKSlider ( int nScreen ); static void NWConvertVCLStateToGTKState( ControlState nVCLState, GtkStateType* nGTKState, GtkShadowType* nGTKShadow ); static void NWAddWidgetToCacheWindow( GtkWidget* widget, int nScreen ); @@ -587,8 +594,13 @@ BOOL GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP ) || ((nType == CTRL_LISTNODE || nType == CTRL_LISTNET) && ( (nPart == PART_ENTIRE_CONTROL) ) + ) || + ((nType == CTRL_SLIDER) && + ( (nPart == PART_TRACK_HORZ_AREA) + || (nPart == PART_TRACK_VERT_AREA) ) ) + ) return( TRUE ); return( FALSE ); @@ -873,6 +885,10 @@ BOOL GtkSalGraphics::drawNativeControl( ControlType nType, // don't actually draw anything; gtk treeviews do not draw lines returnVal = true; } + else if( (nType == CTRL_SLIDER) ) + { + returnVal = NWPaintGTKSlider( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rControlHandle, rCaption ); + } if( pixmap ) { @@ -1101,6 +1117,30 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, rNativeContentRegion = rNativeBoundingRegion; returnVal = TRUE; } + if( (nType == CTRL_SLIDER) && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) ) + { + NWEnsureGTKSlider( m_nScreen ); + GtkWidget* widget = (nPart == PART_THUMB_HORZ) ? gWidgetData[m_nScreen].gHScale : gWidgetData[m_nScreen].gVScale; + gint slider_length = 10; + gint slider_width = 10; + gtk_widget_style_get( widget, + "slider-width", &slider_width, + "slider-length", &slider_length, + (char *)NULL); + Rectangle aRect( rControlRegion.GetBoundRect() ); + if( nPart == PART_THUMB_HORZ ) + { + aRect.Right() = aRect.Left() + slider_length - 1; + aRect.Bottom() = aRect.Top() + slider_width - 1; + } + else + { + aRect.Bottom() = aRect.Top() + slider_length - 1; + aRect.Right() = aRect.Left() + slider_width - 1; + } + rNativeBoundingRegion = rNativeContentRegion = Region( aRect ); + returnVal = TRUE; + } return( returnVal ); } @@ -3010,6 +3050,133 @@ BOOL GtkSalGraphics::NWPaintGTKProgress( return bRet; } +BOOL GtkSalGraphics::NWPaintGTKSlider( + GdkDrawable*, + ControlType, ControlPart nPart, + const Rectangle& rControlRectangle, + const clipList&, + ControlState nState, const ImplControlValue& rValue, + SalControlHandle&, const OUString& ) +{ + NWEnsureGTKSlider( m_nScreen ); + + gint w, h; + w = rControlRectangle.GetWidth(); + h = rControlRectangle.GetHeight(); + + SliderValue* pVal = (SliderValue*)rValue.getOptionalVal(); + + GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle ); + if( ! pixmap ) + return FALSE; + + (void)pVal; + + GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap ); + GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA) + ? GTK_WIDGET(gWidgetData[m_nScreen].gHScale) + : GTK_WIDGET(gWidgetData[m_nScreen].gVScale); + const gchar* pDetail = (nPart == PART_TRACK_HORZ_AREA) ? "hscale" : "vscale"; + GtkOrientation eOri = (nPart == PART_TRACK_HORZ_AREA) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; + GtkStateType eState = (nState & CTRL_STATE_ENABLED) ? GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE; + gint slider_width = 10; + gint slider_length = 10; + gint trough_border = 0; + gtk_widget_style_get( pWidget, + "slider-width", &slider_width, + "slider-length", &slider_length, + "trough-border", &trough_border, + NULL); + + eState = (nState & CTRL_STATE_ENABLED) ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE; + if( nPart == PART_TRACK_HORZ_AREA ) + { + gtk_paint_box( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_IN, + NULL, + pWidget, + "trough", + 0, (h-slider_width-2*trough_border)/2, w, slider_width + 2*trough_border); + gint x = (w - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin); + gtk_paint_slider( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_OUT, + NULL, + pWidget, + pDetail, + x, (h-slider_width)/2, + slider_length, slider_width, + eOri ); + } + else + { + gtk_paint_box( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_IN, + NULL, + pWidget, + "trough", + (w-slider_width-2*trough_border)/2, 0, slider_width + 2*trough_border, h); + gint y = (h - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin); + gtk_paint_slider( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_OUT, + NULL, + pWidget, + pDetail, + (w-slider_width)/2, y, + slider_width, slider_length, + eOri ); + } + #if 0 + // paint background + gtk_paint_flat_box( gWidgetData[m_nScreen].gProgressBar->style, + pixDrawable, + GTK_STATE_NORMAL, + GTK_SHADOW_NONE, + NULL, + gWidgetData[m_nScreen].gProgressBar, + "trough", + 0, 0, w, h ); + if( nProgressWidth > 0 ) + { + // paint progress + if( Application::GetSettings().GetLayoutRTL() ) + { + gtk_paint_box( gWidgetData[m_nScreen].gProgressBar->style, + pixDrawable, + GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, + NULL, + gWidgetData[m_nScreen].gProgressBar, + "bar", + w-nProgressWidth, 0, nProgressWidth, h + ); + } + else + { + gtk_paint_box( gWidgetData[m_nScreen].gProgressBar->style, + pixDrawable, + GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, + NULL, + gWidgetData[m_nScreen].gProgressBar, + "bar", + 0, 0, nProgressWidth, h + ); + } + } + #endif + + BOOL bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle ); + g_object_unref( pixmap ); + + return bRet; +} + //---- static Rectangle NWGetListBoxButtonRect( int nScreen, @@ -3269,20 +3436,23 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) aStyleSet.SetHighlightColor( aHighlightColor ); aStyleSet.SetHighlightTextColor( aHighlightTextColor ); - // hyperlink colors - GdkColor *link_color = NULL; - gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL); - if (link_color) - { - aStyleSet.SetLinkColor(getColor(*link_color)); - gdk_color_free (link_color); - link_color = NULL; - } - gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL); - if (link_color) + if( ! gtk_check_version( 2, 10, 0 ) ) // link colors came in with 2.10, avoid an assertion { - aStyleSet.SetVisitedLinkColor(getColor(*link_color)); - gdk_color_free (link_color); + // hyperlink colors + GdkColor *link_color = NULL; + gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL); + if (link_color) + { + aStyleSet.SetLinkColor(getColor(*link_color)); + gdk_color_free (link_color); + link_color = NULL; + } + gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL); + if (link_color) + { + aStyleSet.SetVisitedLinkColor(getColor(*link_color)); + gdk_color_free (link_color); + } } // Tab colors @@ -3469,12 +3639,25 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) // preferred icon style gchar* pIconThemeName = NULL; g_object_get( gtk_settings_get_default(), "gtk-icon-theme-name", &pIconThemeName, (char *)NULL ); - aStyleSet.SetPreferredSymbolsStyleName( OUString::createFromAscii(pIconThemeName) ); - g_free (pIconThemeName); + aStyleSet.SetPreferredSymbolsStyleName( OUString::createFromAscii( pIconThemeName ) ); + g_free( pIconThemeName ); // FIXME: need some way of fetching toolbar icon size. // aStyleSet.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_SMALL ); + const cairo_font_options_t* pNewOptions = NULL; + if( GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(), m_nScreen ) ) + { +//#if !GTK_CHECK_VERSION(2,8,1) +#if !GTK_CHECK_VERSION(2,9,0) + static cairo_font_options_t* (*gdk_screen_get_font_options)(GdkScreen*) = + (cairo_font_options_t*(*)(GdkScreen*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_screen_get_font_options" ); + if( gdk_screen_get_font_options != NULL ) +#endif + pNewOptions = gdk_screen_get_font_options( pScreen ); + } + aStyleSet.SetCairoFontOptions( pNewOptions ); + // finally update the collected settings rSettings.SetStyleSettings( aStyleSet ); @@ -3947,3 +4130,17 @@ static void NWEnsureGTKTreeView( int nScreen ) NWAddWidgetToCacheWindow( gWidgetData[nScreen].gTreeView, nScreen ); } } + +static void NWEnsureGTKSlider( int nScreen ) +{ + if( !gWidgetData[nScreen].gHScale ) + { + gWidgetData[nScreen].gHScale = gtk_hscale_new_with_range(0, 10, 1); + NWAddWidgetToCacheWindow( gWidgetData[nScreen].gHScale, nScreen ); + } + if( !gWidgetData[nScreen].gVScale ) + { + gWidgetData[nScreen].gVScale = gtk_vscale_new_with_range(0, 10, 1); + NWAddWidgetToCacheWindow( gWidgetData[nScreen].gVScale, nScreen ); + } +} diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index 5d7fcabb7c8f..ef356eb57aa9 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -806,8 +806,15 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle ) /* #i100116# metacity has a peculiar behavior regarding WM_HINT accept focus and _NET_WM_USER_TIME at some point that may be fixed in metacity and we will have to revisit this */ - bool bMetaCityToolWindowHack = getDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("Metacity") && - (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ); + + // MT/PL 2010/02: #i102694# and #i102803# have been introduced by this hack + // Nowadays the original issue referenced above doesn't seem to exist anymore, tested different szenarious described in the issues + // If some older versions of MetaCity are still in use somewhere, they need to be updated, instead of using strange hacks in OOo. + // As a work around for such old systems, people might consider to not use the GTK plugin. + + bool bMetaCityToolWindowHack = false; + // bMetaCityToolWindowHack = getDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("Metacity") && (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ); + if( bDecoHandling ) { bool bNoDecor = ! (nStyle & (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE ) ); @@ -2081,7 +2088,14 @@ void GtkSalFrame::ToTop( USHORT nFlags ) * is set to false. */ if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ) + { + // sad but true: this can cause an XError, we need to catch that + // to do this we need to synchronize with the XServer + getDisplay()->GetXLib()->PushXErrorLevel( true ); XSetInputFocus( getDisplay()->GetDisplay(), GDK_WINDOW_XWINDOW( m_pWindow->window ), RevertToParent, CurrentTime ); + XSync( getDisplay()->GetDisplay(), False ); + getDisplay()->GetXLib()->PopXErrorLevel(); + } } else { @@ -3124,10 +3138,13 @@ void GtkSalFrame::signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer fram // redraw itself to adjust to the new style // where there IS no new style resulting in tremendous unnecessary flickering if( pPrevious != NULL ) + { // signalStyleSet does NOT usually have the gdk lock // so post user event to safely dispatch the SALEVENT_SETTINGSCHANGED // note: settings changed for multiple frames is avoided in winproc.cxx ImplHandleSettings pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_SETTINGSCHANGED ); + pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_FONTCHANGED ); + } /* #i64117# gtk sets a nice background pixmap * but we actually don't really want that, so save diff --git a/vcl/unx/headless/svpframe.cxx b/vcl/unx/headless/svpframe.cxx index 37c5eeb846a4..1adf9a51cce4 100644 --- a/vcl/unx/headless/svpframe.cxx +++ b/vcl/unx/headless/svpframe.cxx @@ -82,6 +82,33 @@ SvpSalFrame::~SvpSalFrame() (*it)->SetParent( m_pParent ); if( m_pParent ) m_pParent->m_aChildren.remove( this ); + + if( s_pFocusFrame == this ) + { + s_pFocusFrame = NULL; + // call directly here, else an event for a destroyed frame would be dispatched + CallCallback( SALEVENT_LOSEFOCUS, NULL ); + // if the handler has not set a new focus frame + // pass focus to another frame, preferably a document style window + if( s_pFocusFrame == NULL ) + { + const std::list< SalFrame* >& rFrames( m_pInstance->getFrames() ); + for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it ) + { + SvpSalFrame* pFrame = const_cast<SvpSalFrame*>(static_cast<const SvpSalFrame*>(*it)); + if( pFrame->m_bVisible && + pFrame->m_pParent == NULL && + (pFrame->m_nStyle & (SAL_FRAME_STYLE_MOVEABLE | + SAL_FRAME_STYLE_SIZEABLE | + SAL_FRAME_STYLE_CLOSEABLE) ) != 0 + ) + { + pFrame->GetFocus(); + break; + } + } + } + } } void SvpSalFrame::GetFocus() diff --git a/vcl/unx/headless/svpgdi.cxx b/vcl/unx/headless/svpgdi.cxx index 114bd4c8a5bc..e65c9faf1432 100644 --- a/vcl/unx/headless/svpgdi.cxx +++ b/vcl/unx/headless/svpgdi.cxx @@ -584,3 +584,4 @@ bool SvpSalGraphics::supportsOperation( OutDevSupportType ) const { return false; } + diff --git a/vcl/unx/headless/svpgdi.hxx b/vcl/unx/headless/svpgdi.hxx index 9e25b67394e7..132dafaa9adf 100644 --- a/vcl/unx/headless/svpgdi.hxx +++ b/vcl/unx/headless/svpgdi.hxx @@ -170,3 +170,4 @@ public: }; #endif + diff --git a/vcl/unx/headless/svpinst.cxx b/vcl/unx/headless/svpinst.cxx index 485062bf0617..466b56868900 100644 --- a/vcl/unx/headless/svpinst.cxx +++ b/vcl/unx/headless/svpinst.cxx @@ -55,6 +55,19 @@ extern "C" } } +bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const +{ + for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin(); + it != m_aFrames.end(); ++it ) + { + if( *it == pFrame ) + { + return true; + } + } + return false; +} + SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL; SvpSalInstance::SvpSalInstance() @@ -346,12 +359,15 @@ void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) { for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it ) { - it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); - if( it->m_nEvent == SALEVENT_RESIZE ) + if ( isFrameAlive( it->m_pFrame ) ) { - // this would be a good time to post a paint - const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); - pSvpFrame->PostPaint(); + it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); + if( it->m_nEvent == SALEVENT_RESIZE ) + { + // this would be a good time to post a paint + const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); + pSvpFrame->PostPaint(); + } } } } diff --git a/vcl/unx/headless/svpinst.hxx b/vcl/unx/headless/svpinst.hxx index d37c1c7e126e..284a2d11cd82 100644 --- a/vcl/unx/headless/svpinst.hxx +++ b/vcl/unx/headless/svpinst.hxx @@ -108,6 +108,9 @@ class SvpSalInstance : public SalInstance std::list< SalUserEvent > m_aUserEvents; std::list< SalFrame* > m_aFrames; + + bool isFrameAlive( const SalFrame* pFrame ) const; + public: static SvpSalInstance* s_pDefaultInstance; diff --git a/vcl/unx/headless/svppspgraphics.cxx b/vcl/unx/headless/svppspgraphics.cxx index 353b10467d40..7f551051c1a7 100644 --- a/vcl/unx/headless/svppspgraphics.cxx +++ b/vcl/unx/headless/svppspgraphics.cxx @@ -1160,32 +1160,6 @@ ImplDevFontAttributes PspGraphics::Info2DevFontAttributes( const psp::FastPrintF aDFA.mePitch = ToFontPitch (rInfo.m_ePitch); aDFA.mbSymbolFlag = (rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL); - switch (rInfo.m_eEmbeddedbitmap) - { - default: - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - break; - case psp::fcstatus::istrue: - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_TRUE; - break; - case psp::fcstatus::isfalse: - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_FALSE; - break; - } - - switch (rInfo.m_eAntialias) - { - default: - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - break; - case psp::fcstatus::istrue: - aDFA.meAntiAlias = ANTIALIAS_TRUE; - break; - case psp::fcstatus::isfalse: - aDFA.meAntiAlias = ANTIALIAS_FALSE; - break; - } - switch( rInfo.m_eType ) { case psp::fonttype::Builtin: diff --git a/vcl/unx/headless/svppspgraphics.hxx b/vcl/unx/headless/svppspgraphics.hxx index 8addbc3de5f7..82ba613615cb 100644 --- a/vcl/unx/headless/svppspgraphics.hxx +++ b/vcl/unx/headless/svppspgraphics.hxx @@ -190,3 +190,4 @@ public: }; #endif // _SVP_PSPGRAPHICS_HXX + diff --git a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx index 9db81aa30a4d..ed3f782c8576 100644 --- a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx @@ -168,6 +168,11 @@ protected: const clipList& rClipList, ControlState nState, const ImplControlValue& aValue, SalControlHandle& rControlHandle, const OUString& rCaption ); + BOOL NWPaintGTKSlider( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart, + const Rectangle& rControlRectangle, + const clipList& rClipList, + ControlState nState, const ImplControlValue& aValue, + SalControlHandle& rControlHandle, const OUString& rCaption ); BOOL NWPaintGTKListNode( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart, const Rectangle& rControlRectangle, const clipList& rClipList, diff --git a/vcl/unx/inc/pspgraphics.h b/vcl/unx/inc/pspgraphics.h index 4dce4ee8b06c..2eae73cdaa86 100644 --- a/vcl/unx/inc/pspgraphics.h +++ b/vcl/unx/inc/pspgraphics.h @@ -103,7 +103,7 @@ public: virtual void SetTextColor( SalColor nSalColor ); virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); virtual void GetFontMetric( ImplFontMetricData* ); - virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); + virtual ULONG GetKernPairs( ULONG nMaxPairs, ImplKernPairData* ); virtual ImplFontCharMap* GetImplFontCharMap() const; virtual void GetDevFontList( ImplDevFontList* ); virtual void GetDevFontSubstList( OutputDevice* ); diff --git a/vcl/unx/inc/saldisp.hxx b/vcl/unx/inc/saldisp.hxx index 368e554794ad..e54d6e828911 100644 --- a/vcl/unx/inc/saldisp.hxx +++ b/vcl/unx/inc/saldisp.hxx @@ -404,6 +404,7 @@ protected: int processRandREvent( XEvent* ); void doDestruct(); + void addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ); public: static SalDisplay *GetSalDisplay( Display* display ); static BOOL BestVisual( Display *pDisp, diff --git a/vcl/unx/inc/salgdi.h b/vcl/unx/inc/salgdi.h index 09e85c6840b8..da69f04b6f8f 100644 --- a/vcl/unx/inc/salgdi.h +++ b/vcl/unx/inc/salgdi.h @@ -250,7 +250,7 @@ public: virtual void SetTextColor( SalColor nSalColor ); virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); virtual void GetFontMetric( ImplFontMetricData* ); - virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); + virtual ULONG GetKernPairs( ULONG nMaxPairs, ImplKernPairData* ); virtual ImplFontCharMap* GetImplFontCharMap() const; virtual void GetDevFontList( ImplDevFontList* ); virtual void GetDevFontSubstList( OutputDevice* ); diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx index 79de48302649..25dd50ce3958 100644 --- a/vcl/unx/kde4/KDESalGraphics.cxx +++ b/vcl/unx/kde4/KDESalGraphics.cxx @@ -88,8 +88,18 @@ QRect region2QRect( const Region& rControlRegion ) { Rectangle aRect = rControlRegion.GetBoundRect(); - return QRect( QPoint( aRect.Left(), aRect.Top() ), - QPoint( aRect.Right(), aRect.Bottom() ) ); + return QRect(aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight()); +} + +KDESalGraphics::KDESalGraphics() : + m_image(0) +{ +} + +KDESalGraphics::~KDESalGraphics() +{ + if (m_image) + delete m_image; } BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart part ) @@ -133,6 +143,9 @@ BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart par if (type == CTRL_RADIOBUTTON) return true; + if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA) ) + return true; + return false; if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true; @@ -143,7 +156,6 @@ BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart par return false; } - BOOL KDESalGraphics::hitTestNativeControl( ControlType, ControlPart, const Region&, const Point&, SalControlHandle&, BOOL& ) @@ -151,28 +163,59 @@ BOOL KDESalGraphics::hitTestNativeControl( ControlType, ControlPart, return FALSE; } -void lcl_drawFrame( QRect& i_rRect, QPainter& i_rPainter, QStyle::PrimitiveElement i_nElement, - ControlState i_nState, const ImplControlValue& i_rValue ) +/// helper drawing methods +namespace { + void draw( QStyle::ControlElement element, QStyleOption* option, QImage* image, QStyle::State state ) + { + option->state |= state; + option->rect = image->rect(); + + QPainter painter(image); + kapp->style()->drawControl(element, option, &painter); + } + + void draw( QStyle::PrimitiveElement element, QStyleOption* option, QImage* image, QStyle::State state, int nAdjust = 0 ) + { + option->state |= state; + option->rect = image->rect(); + if( nAdjust ) + option->rect.adjust( nAdjust, nAdjust, -nAdjust, -nAdjust ); + + QPainter painter(image); + kapp->style()->drawPrimitive(element, option, &painter); + } + + void draw( QStyle::ComplexControl element, QStyleOptionComplex* option, QImage* image, QStyle::State state ) + { + option->state |= state; + option->rect = image->rect(); + + QPainter painter(image); + kapp->style()->drawComplexControl(element, option, &painter); + } + + void lcl_drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State state) + { #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QStyleOptionFrameV3 styleOption; - styleOption.frameShape = QFrame::StyledPanel; + QStyleOptionFrameV3 option; + option.frameShape = QFrame::StyledPanel; + option.state = QStyle::State_Sunken; #else - QStyleOptionFrame styleOption; - QFrame aFrame( NULL ); - aFrame.setFrameRect( QRect(0, 0, i_rRect.width(), i_rRect.height()) ); - aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); - aFrame.ensurePolished(); - styleOption.initFrom( &aFrame ); - styleOption.lineWidth = aFrame.lineWidth(); - styleOption.midLineWidth = aFrame.midLineWidth(); - #endif - styleOption.rect = QRect(0, 0, i_rRect.width(), i_rRect.height()); - styleOption.state = vclStateValue2StateFlag( i_nState, i_rValue ); - #if ( QT_VERSION < QT_VERSION_CHECK( 4, 5, 0 ) ) - styleOption.state |= QStyle::State_Sunken; + QStyleOptionFrame option; + + QFrame aFrame( NULL ); + aFrame.setFrameRect( QRect(0, 0, image->width(), image->height()) ); + aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + aFrame.ensurePolished(); + + option.initFrom( &aFrame ); + option.lineWidth = aFrame.lineWidth(); + option.midLineWidth = aFrame.midLineWidth(); #endif - kapp->style()->drawPrimitive(i_nElement, &styleOption, &i_rPainter); + + draw(element, &option, image, state); + } } BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, @@ -188,10 +231,6 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, BOOL returnVal = true; - Display* dpy = GetXDisplay(); - XLIB_Window drawable = GetDrawable(); - GC gc = SelectPen(); - QRect widgetRect = region2QRect(rControlRegion); if( type == CTRL_SPINBOX && part == PART_ALL_BUTTONS ) type = CTRL_SPINBUTTONS; @@ -204,337 +243,287 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, aButtonRect.Right(), aButtonRect.Bottom() ); } - //draw right onto the window - QPixmap pixmap(widgetRect.width(), widgetRect.height()); - - if (pixmap.isNull()) + //if no image, or resized, make a new image + if (!m_image || m_image->size() != widgetRect.size()) { - return false; + if (m_image) + delete m_image; + + m_image = new QImage( widgetRect.width(), + widgetRect.height(), + QImage::Format_ARGB32 ); } + m_image->fill(KApplication::palette().color(QPalette::Window).rgb()); - QPainter painter(&pixmap); - // painter.setBackgroundMode(Qt::OpaqueMode); - //copy previous screen contents for proper blending - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QPixmap screen = QPixmap::fromX11Pixmap(drawable); - painter.drawPixmap(0,0, screen, widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height()); - #else - const QX11Info& rX11Info( pixmap.x11Info() ); - X11SalGraphics::CopyScreenArea( dpy, - drawable, GetScreenNumber(), GetBitCount(), - pixmap.handle(), rX11Info.screen(), rX11Info.depth(), - GetDisplay()->GetCopyGC( GetScreenNumber() ), - widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height(), - 0, 0 ); - #endif + XLIB_Region pTempClipRegion = 0; if (type == CTRL_PUSHBUTTON) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state =vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl( QStyle::CE_PushButton, &styleOption, &painter); + QStyleOptionButton option; + draw( QStyle::CE_PushButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if ( (type == CTRL_MENUBAR)) { if (part == PART_MENU_ITEM) { - QStyleOptionMenuItem styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl( QStyle::CE_MenuBarItem, &styleOption, &painter); + QStyleOptionMenuItem option; + draw( QStyle::CE_MenuBarItem, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); + } + else if (part == PART_ENTIRE_CONTROL) + { } else { - pixmap.fill(KApplication::palette().color(QPalette::Window)); + returnVal = false; } } else if (type == CTRL_MENU_POPUP) { if (part == PART_MENU_ITEM) { - QStyleOptionMenuItem styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl( QStyle::CE_MenuItem, &styleOption, &painter); + QStyleOptionMenuItem option; + draw( QStyle::CE_MenuItem, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } - else if (part == PART_MENU_ITEM_CHECK_MARK) + else if (part == PART_MENU_ITEM_CHECK_MARK && (nControlState & CTRL_STATE_PRESSED) ) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - if (nControlState & CTRL_STATE_PRESSED) - { - kapp->style()->drawPrimitive( QStyle::PE_IndicatorMenuCheckMark, &styleOption, &painter); - } + QStyleOptionButton option; + draw( QStyle::PE_IndicatorMenuCheckMark, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } - else if (part == PART_MENU_ITEM_RADIO_MARK) + else if (part == PART_MENU_ITEM_RADIO_MARK && (nControlState & CTRL_STATE_PRESSED) ) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - if (nControlState & CTRL_STATE_PRESSED) - { - kapp->style()->drawPrimitive( QStyle::PE_IndicatorRadioButton, &styleOption, &painter); - } + QStyleOptionButton option; + draw( QStyle::PE_IndicatorRadioButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QStyleOptionFrameV3 styleOption; + QStyleOptionFrameV3 option; + option.frameShape = QFrame::StyledPanel; #else - QStyleOptionFrameV2 styleOption; - #endif - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - styleOption.frameShape = QFrame::StyledPanel; + QStyleOptionFrameV2 option; #endif - - kapp->style()->drawPrimitive( QStyle::PE_FrameMenu, &styleOption, &painter); + draw( QStyle::PE_FrameMenu, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } } else if ( (type == CTRL_TOOLBAR) && (part == PART_BUTTON) ) { - QStyleOptionToolButton styleOption; + QStyleOptionToolButton option; - styleOption.arrowType = Qt::NoArrow; - styleOption.subControls = QStyle::SC_ToolButton; + option.arrowType = Qt::NoArrow; + option.subControls = QStyle::SC_ToolButton; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - styleOption.state |= QStyle::State_Raised | QStyle::State_Enabled | QStyle::State_AutoRaise; + option.state = vclStateValue2StateFlag( nControlState, value ); + option.state |= QStyle::State_Raised | QStyle::State_Enabled | QStyle::State_AutoRaise; - kapp->style()->drawComplexControl( QStyle::CC_ToolButton, &styleOption, &painter); + draw( QStyle::CC_ToolButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if ( (type == CTRL_TOOLBAR) && (part == PART_ENTIRE_CONTROL) ) { - QStyleOptionToolBar styleOption; + QStyleOptionToolBar option; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); + option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + option.state = vclStateValue2StateFlag( nControlState, value ); - kapp->style()->drawControl( QStyle::CE_ToolBar, &styleOption, &painter); + draw( QStyle::CE_ToolBar, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if ( (type == CTRL_TOOLBAR) && (part == PART_THUMB_VERT) ) { - QStyleOption styleOption; + const int tw = widgetRect.width(); + widgetRect.setWidth(kapp->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent)); - int width = kapp->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent); + QStyleOption option; + option.state = QStyle::State_Horizontal; - styleOption.rect = QRect(0, 0, width, widgetRect.height()); - styleOption.state = QStyle::State_Horizontal; + draw( QStyle::PE_IndicatorToolBarHandle, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); - kapp->style()->drawPrimitive( QStyle::PE_IndicatorToolBarHandle, &styleOption, &painter); + widgetRect.setWidth(tw); } else if (type == CTRL_EDITBOX) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - - //TODO hover?? OO does not seem to do this for line edits + QStyleOptionFrameV2 option; + draw( QStyle::PE_PanelLineEdit, &option, m_image, + vclStateValue2StateFlag(nControlState, value), 2 ); - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QStyleOptionFrameV3 styleOption; - #else - QStyleOptionFrameV2 styleOption; - #endif - - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - //TODO...how does the line edit draw itself internally?? - styleOption.rect = QRect(2, 2, widgetRect.width()-4, widgetRect.height()-4); - kapp->style()->drawPrimitive( QStyle::PE_PanelLineEdit, &styleOption, &painter); - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - kapp->style()->drawPrimitive( QStyle::PE_FrameLineEdit, &styleOption, &painter); + draw( QStyle::PE_FrameLineEdit, &option, m_image, + vclStateValue2StateFlag(nControlState, value), 0 ); } else if (type == CTRL_COMBOBOX) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - - QStyleOptionComboBox styleOption; + QStyleOptionComboBox option; + option.editable = true; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - styleOption.editable = true; - - kapp->style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, &painter); + draw( QStyle::CC_ComboBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_LISTBOX) { if( part == PART_WINDOW ) { - lcl_drawFrame( widgetRect, painter, QStyle::PE_Frame, nControlState, value ); + lcl_drawFrame( QStyle::PE_Frame, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else { - QStyleOptionComboBox styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - + QStyleOptionComboBox option; if (part == PART_SUB_EDIT) { - kapp->style()->drawControl(QStyle::CE_ComboBoxLabel, &styleOption, &painter); + draw( QStyle::CE_ComboBoxLabel, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else { - kapp->style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, &painter); + draw( QStyle::CC_ComboBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } } } else if (type == CTRL_LISTNODE) { - QStyleOption styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - styleOption.state |= QStyle::State_Item; - styleOption.state |= QStyle::State_Children; + QStyleOption option; + option.state = QStyle::State_Item | QStyle::State_Children; if (nControlState & CTRL_STATE_PRESSED) - { - styleOption.state |= QStyle::State_Open; - } + option.state |= QStyle::State_Open; - kapp->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &styleOption, &painter); + draw( QStyle::PE_IndicatorBranch, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_CHECKBOX) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl(QStyle::CE_CheckBox, &styleOption, &painter); + QStyleOptionButton option; + draw( QStyle::CE_CheckBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_SCROLLBAR) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - if ((part == PART_DRAW_BACKGROUND_VERT) || (part == PART_DRAW_BACKGROUND_HORZ)) { + QStyleOptionSlider option; ScrollbarValue* sbVal = static_cast<ScrollbarValue *> ( value.getOptionalVal() ); - QStyleOptionSlider styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - //if the scroll bar is active (aka not degenrate...allow for hover events if (sbVal->mnVisibleSize < sbVal->mnMax) - { - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - styleOption.state |= QStyle::State_MouseOver; - } + option.state = QStyle::State_MouseOver; //horizontal or vertical if (part == PART_DRAW_BACKGROUND_VERT) - { - styleOption.orientation = Qt::Vertical; - } + option.orientation = Qt::Vertical; else - { - styleOption.state |= QStyle::State_Horizontal; - } + option.state |= QStyle::State_Horizontal; //setup parameters from the OO values - styleOption.minimum = sbVal->mnMin; - styleOption.maximum = sbVal->mnMax - sbVal->mnVisibleSize; - styleOption.sliderValue = sbVal->mnCur; - styleOption.sliderPosition = sbVal->mnCur; - styleOption.pageStep = sbVal->mnVisibleSize; + option.minimum = sbVal->mnMin; + option.maximum = sbVal->mnMax - sbVal->mnVisibleSize; + option.sliderValue = sbVal->mnCur; + option.sliderPosition = sbVal->mnCur; + option.pageStep = sbVal->mnVisibleSize; //setup the active control...always the slider if (sbVal->mnThumbState & CTRL_STATE_ROLLOVER) - { - styleOption.activeSubControls = QStyle::SC_ScrollBarSlider; - } + option.activeSubControls = QStyle::SC_ScrollBarSlider; - kapp->style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, &painter); + draw( QStyle::CC_ScrollBar, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); + } + else + { + returnVal = false; } } else if (type == CTRL_SPINBOX) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); + QStyleOptionSpinBox option; - QStyleOptionSpinBox styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); // determine active control SpinbuttonValue* pSpinVal = (SpinbuttonValue *)(value.getOptionalVal()); if( pSpinVal ) { if( (pSpinVal->mnUpperState & CTRL_STATE_PRESSED) ) - styleOption.activeSubControls |= QStyle::SC_SpinBoxUp; + option.activeSubControls |= QStyle::SC_SpinBoxUp; if( (pSpinVal->mnLowerState & CTRL_STATE_PRESSED) ) - styleOption.activeSubControls |= QStyle::SC_SpinBoxDown; + option.activeSubControls |= QStyle::SC_SpinBoxDown; } - kapp->style()->drawComplexControl(QStyle::CC_SpinBox, &styleOption, &painter); + draw( QStyle::CC_SpinBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_GROUPBOX) { - QStyleOptionGroupBox styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawComplexControl(QStyle::CC_GroupBox, &styleOption, &painter); + QStyleOptionGroupBox option; + draw( QStyle::CC_GroupBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_RADIOBUTTON) { - QStyleOptionButton styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl(QStyle::CE_RadioButton, &styleOption, &painter); + QStyleOptionButton option; + draw( QStyle::CE_RadioButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_TOOLTIP) { - QStyleOption styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawPrimitive(QStyle::PE_PanelTipLabel, &styleOption, &painter); + QStyleOption option; + draw( QStyle::PE_PanelTipLabel, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_FRAME) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - lcl_drawFrame( widgetRect, painter, QStyle::PE_Frame, nControlState, value ); + lcl_drawFrame( QStyle::PE_Frame, m_image, + vclStateValue2StateFlag(nControlState, value) ); + + int size = kapp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + pTempClipRegion = XCreateRegion(); + XRectangle xRect = { widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height() }; + XUnionRectWithRegion( &xRect, pTempClipRegion, pTempClipRegion ); + XLIB_Region pSubtract = XCreateRegion(); + xRect.x += size; + xRect.y += size; + xRect.width -= 2* size; + xRect.height -= 2*size; + XUnionRectWithRegion( &xRect, pSubtract, pSubtract ); + XSubtractRegion( pTempClipRegion, pSubtract, pTempClipRegion ); + XDestroyRegion( pSubtract ); } else if (type == CTRL_FIXEDBORDER) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - lcl_drawFrame( widgetRect, painter, QStyle::PE_FrameWindow, nControlState, value ); + lcl_drawFrame( QStyle::PE_FrameWindow, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_WINDOW_BACKGROUND) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); + m_image->fill(KApplication::palette().color(QPalette::Window).rgb()); } else if (type == CTRL_FIXEDLINE) { - QStyleOptionMenuItem styleOption; + QStyleOptionMenuItem option; + option.menuItemType = QStyleOptionMenuItem::Separator; + option.state |= QStyle::State_Item; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - styleOption.menuItemType = QStyleOptionMenuItem::Separator; - styleOption.state |= QStyle::State_Item; + draw( QStyle::CE_MenuItem, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); + } + else if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA)) + { + SliderValue* slVal = static_cast<SliderValue *> ( value.getOptionalVal() ); + QStyleOptionSlider option; - kapp->style()->drawControl( QStyle::CE_MenuItem, &styleOption, &painter); + option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + option.state = vclStateValue2StateFlag( nControlState, value ); + option.maximum = slVal->mnMax; + option.minimum = slVal->mnMin; + option.sliderPosition = option.sliderValue = slVal->mnCur; + option.orientation = (part == PART_TRACK_HORZ_AREA) ? Qt::Horizontal : Qt::Vertical; + + draw( QStyle::CC_Slider, &option, m_image, vclStateValue2StateFlag(nControlState, value) ); } else { @@ -543,11 +532,35 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, if (returnVal) { - X11SalGraphics::CopyScreenArea( dpy, - pixmap.handle(), pixmap.x11Info().screen(), pixmap.x11Info().depth(), - drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, - 0, 0, widgetRect.width(), widgetRect.height(), widgetRect.left(), widgetRect.top() ); + GC gc = SelectFont(); + + if( gc ) + { + if( pTempClipRegion ) + { + if( pClipRegion_ ) + XIntersectRegion( pTempClipRegion, pClipRegion_, pTempClipRegion ); + XSetRegion( GetXDisplay(), gc, pTempClipRegion ); + } + QPixmap pixmap = QPixmap::fromImage(*m_image, Qt::ColorOnly | Qt::OrderedDither | Qt::OrderedAlphaDither); + X11SalGraphics::CopyScreenArea( GetXDisplay(), + pixmap.handle(), pixmap.x11Info().screen(), pixmap.x11Info().depth(), + GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(), + gc, 0, 0, widgetRect.width(), widgetRect.height(), widgetRect.left(), widgetRect.top()); + + if( pTempClipRegion ) + { + if( pClipRegion_ ) + XSetRegion( GetXDisplay(), gc, pClipRegion_ ); + else + XSetClipMask( GetXDisplay(), gc, None ); + } + } + else + returnVal = false; } + if( pTempClipRegion ) + XDestroyRegion( pTempClipRegion ); return returnVal; } @@ -759,6 +772,24 @@ BOOL KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part, boundingRect = contentRect; retVal = true; + break; + } + case CTRL_SLIDER: + { + const int w = kapp->style()->pixelMetric(QStyle::PM_SliderLength); + if( part == PART_THUMB_HORZ ) + { + contentRect = QRect(boundingRect.left(), boundingRect.top(), w, boundingRect.height()); + boundingRect = contentRect; + retVal = true; + } + else if( part == PART_THUMB_VERT ) + { + contentRect = QRect(boundingRect.left(), boundingRect.top(), boundingRect.width(), w); + boundingRect = contentRect; + retVal = true; + } + break; } default: break; diff --git a/vcl/unx/kde4/KDESalGraphics.hxx b/vcl/unx/kde4/KDESalGraphics.hxx index 3e9ac44e4981..b5328f462a16 100644 --- a/vcl/unx/kde4/KDESalGraphics.hxx +++ b/vcl/unx/kde4/KDESalGraphics.hxx @@ -31,12 +31,18 @@ #include <saldisp.hxx> #include <salgdi.h> +#define Region QtXRegion +#include <QImage> +#undef Region + /** handles graphics drawings requests and performs the needed drawing operations */ class KDESalGraphics : public X11SalGraphics { + QImage* m_image; + public: - KDESalGraphics() {} - virtual ~KDESalGraphics() {} + KDESalGraphics(); + virtual ~KDESalGraphics(); /** What widgets can be drawn the native way. diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx index 97116626894e..2ed699ad0eb5 100644 --- a/vcl/unx/source/app/saldisp.cxx +++ b/vcl/unx/source/app/saldisp.cxx @@ -2594,6 +2594,28 @@ void SalDisplay::PrintInfo() const sal::static_int_cast< unsigned int >(GetVisual(m_nDefaultScreen).GetVisualId()) ); } +void SalDisplay::addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ) +{ + // see if any frame buffers are at the same coordinates + // this can happen with weird configuration e.g. on + // XFree86 and Clone displays + const size_t nScreens = m_aXineramaScreens.size(); + for( size_t n = 0; n < nScreens; n++ ) + { + if( m_aXineramaScreens[n].Left() == i_nX && + m_aXineramaScreens[n].Top() == i_nY ) + { + if( m_aXineramaScreens[n].GetWidth() < i_nWidth || + m_aXineramaScreens[n].GetHeight() < i_nHeight ) + { + m_aXineramaScreens[n].SetSize( Size( i_nWidth, i_nHeight ) ); + } + return; + } + } + m_aXineramaScreens.push_back( Rectangle( Point( i_nX, i_nY ), Size( i_nWidth, i_nHeight ) ) ); +} + void SalDisplay::InitXinerama() { if( m_aScreens.size() > 1 ) @@ -2618,10 +2640,10 @@ void SalDisplay::InitXinerama() m_bXinerama = true; m_aXineramaScreens = std::vector<Rectangle>( nFramebuffers ); for( int i = 0; i < nFramebuffers; i++ ) - m_aXineramaScreens[i] = Rectangle( Point( pFramebuffers[i].x, - pFramebuffers[i].y ), - Size( pFramebuffers[i].width, - pFramebuffers[i].height ) ); + addXineramaScreenUnique( pFramebuffers[i].x, + pFramebuffers[i].y, + pFramebuffers[i].width, + pFramebuffers[i].height ); } } #elif defined(USE_XINERAMA_XORG) @@ -2637,30 +2659,10 @@ if( XineramaIsActive( pDisp_ ) ) m_aXineramaScreens = std::vector<Rectangle>(); for( int i = 0; i < nFramebuffers; i++ ) { - // see if any frame buffers are at the same coordinates - // this can happen with weird configuration e.g. on - // XFree86 and Clone displays - bool bDuplicate = false; - for( int n = 0; n < i; n++ ) - { - if( m_aXineramaScreens[n].Left() == pScreens[i].x_org && - m_aXineramaScreens[n].Top() == pScreens[i].y_org ) - { - bDuplicate = true; - if( m_aXineramaScreens[n].GetWidth() < pScreens[i].width || - m_aXineramaScreens[n].GetHeight() < pScreens[i].height ) - { - m_aXineramaScreens[n].SetSize( Size( pScreens[i].width, - pScreens[i].height ) ); - } - break; - } - } - if( ! bDuplicate ) - m_aXineramaScreens.push_back( Rectangle( Point( pScreens[i].x_org, - pScreens[i].y_org ), - Size( pScreens[i].width, - pScreens[i].height ) ) ); + addXineramaScreenUnique( pScreens[i].x_org, + pScreens[i].y_org, + pScreens[i].width, + pScreens[i].height ); } m_bXinerama = m_aXineramaScreens.size() > 1; } diff --git a/vcl/unx/source/fontmanager/fontcache.cxx b/vcl/unx/source/fontmanager/fontcache.cxx index 803e92d3cb14..db4a7d05e5fc 100644 --- a/vcl/unx/source/fontmanager/fontcache.cxx +++ b/vcl/unx/source/fontmanager/fontcache.cxx @@ -212,9 +212,9 @@ void FontCache::flush() aLine.Append( ';' ); aLine.Append( (*it)->m_bUserOverride ? "1" : "0" ); aLine.Append( ';' ); - aLine.Append( ByteString::CreateFromInt32( (*it)->m_eEmbeddedbitmap ) ); + aLine.Append( ByteString::CreateFromInt32( 0 ) ); aLine.Append( ';' ); - aLine.Append( ByteString::CreateFromInt32( (*it)->m_eAntialias ) ); + aLine.Append( ByteString::CreateFromInt32( 0 ) ); switch( (*it)->m_eType ) { @@ -424,9 +424,6 @@ void FontCache::read() = atoi( pLine + nTokenPos[14] ); pFont->m_bUserOverride = (atoi( pLine + nTokenPos[15] ) != 0); - pFont->m_eEmbeddedbitmap - = (fcstatus::type)atoi(pLine+nTokenPos[16]); - pFont->m_eAntialias = (fcstatus::type)atoi(pLine+nTokenPos[17]); int nStyleTokenNr = 18; switch( eType ) { @@ -558,8 +555,6 @@ void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFo pTo->m_nYMax = pFrom->m_nYMax; pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs; pTo->m_bUserOverride = pFrom->m_bUserOverride; - pTo->m_eEmbeddedbitmap = pFrom->m_eEmbeddedbitmap; - pTo->m_eAntialias = pFrom->m_eAntialias; } /* @@ -621,9 +616,7 @@ bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont* pLeft, Print pRight->m_nXMax != pLeft->m_nXMax || pRight->m_nYMax != pLeft->m_nYMax || pRight->m_bHaveVerticalSubstitutedGlyphs != pLeft->m_bHaveVerticalSubstitutedGlyphs || - pRight->m_bUserOverride != pLeft->m_bUserOverride || - pRight->m_eEmbeddedbitmap != pLeft->m_eEmbeddedbitmap || - pRight->m_eAntialias != pLeft->m_eAntialias + pRight->m_bUserOverride != pLeft->m_bUserOverride ) return false; std::list< int >::const_iterator lit, rit; diff --git a/vcl/unx/source/fontmanager/fontconfig.cxx b/vcl/unx/source/fontmanager/fontconfig.cxx index 1d4573518879..bc6de4fbc94a 100644 --- a/vcl/unx/source/fontmanager/fontconfig.cxx +++ b/vcl/unx/source/fontmanager/fontconfig.cxx @@ -30,37 +30,45 @@ #include "vcl/fontmanager.hxx" #include "vcl/fontcache.hxx" +#include "vcl/impfont.hxx" using namespace psp; #ifdef ENABLE_FONTCONFIG -#include <fontconfig/fontconfig.h> -#include <ft2build.h> -#include <fontconfig/fcfreetype.h> -// be compatible with fontconfig 2.2.0 release -#ifndef FC_WEIGHT_BOOK - #define FC_WEIGHT_BOOK 75 -#endif -#ifndef FC_EMBEDDED_BITMAP - #define FC_EMBEDDED_BITMAP "embeddedbitmap" -#endif -#ifndef FC_FAMILYLANG - #define FC_FAMILYLANG "familylang" -#endif + #include <fontconfig/fontconfig.h> + #include <ft2build.h> + #include <fontconfig/fcfreetype.h> + // allow compile on baseline (currently with fontconfig 2.2.0) + #ifndef FC_WEIGHT_BOOK // TODO: remove when baseline moves to fc>=2.2.1 + #define FC_WEIGHT_BOOK 75 + #endif + #ifndef FC_EMBEDDED_BITMAP // TODO: remove when baseline moves to fc>=2.3.92 + #define FC_EMBEDDED_BITMAP "embeddedbitmap" + #endif + #ifndef FC_FAMILYLANG // TODO: remove when baseline moves to fc>=2.2.97 + #define FC_FAMILYLANG "familylang" + #endif + #ifndef FC_HINT_STYLE // TODO: remove when baseline moves to fc>=2.2.91 + #define FC_HINT_STYLE "hintstyle" + #define FC_HINT_NONE 0 + #define FC_HINT_SLIGHT 1 + #define FC_HINT_MEDIUM 2 + #define FC_HINT_FULL 3 + #endif #else -typedef void FcConfig; -typedef void FcObjectSet; -typedef void FcPattern; -typedef void FcFontSet; -typedef void FcCharSet; -typedef int FcResult; -typedef int FcBool; -typedef int FcMatchKind; -typedef char FcChar8; -typedef int FcChar32; -typedef unsigned int FT_UInt; -typedef void* FT_Face; -typedef int FcSetName; + typedef void FcConfig; + typedef void FcObjectSet; + typedef void FcPattern; + typedef void FcFontSet; + typedef void FcCharSet; + typedef int FcResult; + typedef int FcBool; + typedef int FcMatchKind; + typedef char FcChar8; + typedef int FcChar32; + typedef unsigned int FT_UInt; + typedef void* FT_Face; + typedef int FcSetName; #endif #include <cstdio> @@ -117,6 +125,7 @@ class FontCfgWrapper FcBool (*m_pFcConfigAppFontAddDir)(FcConfig*, const FcChar8*); FcBool (*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind); FcBool (*m_pFcPatternAddInteger)(FcPattern*,const char*,int); + FcBool (*m_pFcPatternAddDouble)(FcPattern*,const char*,double); FcBool (*m_pFcPatternAddBool)(FcPattern*,const char*,FcBool); FcBool (*m_pFcPatternAddCharSet)(FcPattern*,const char*,const FcCharSet*); FcBool (*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*); @@ -220,6 +229,8 @@ public: { return m_pFcConfigSubstitute( pConfig, pPattern, eKind ); } FcBool FcPatternAddInteger( FcPattern* pPattern, const char* pObject, int nValue ) { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); } + FcBool FcPatternAddDouble( FcPattern* pPattern, const char* pObject, double nValue ) + { return m_pFcPatternAddDouble( pPattern, pObject, nValue ); } FcBool FcPatternAddString( FcPattern* pPattern, const char* pObject, const FcChar8* pString ) { return m_pFcPatternAddString( pPattern, pObject, pString ); } FcBool FcPatternAddBool( FcPattern* pPattern, const char* pObject, bool nValue ) @@ -231,7 +242,9 @@ public: { return m_pFcFreeTypeCharIndex ? m_pFcFreeTypeCharIndex( face, ucs4 ) : 0; } public: // TODO: cleanup - std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aFontconfigNameToLocalized; + FcResult FamilyFromPattern(FcPattern* pPattern, FcChar8 **family); + std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aFontNameToLocalized; + std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aLocalizedToCanonical; }; oslGenericFunction FontCfgWrapper::loadSymbol( const char* pSymbol ) @@ -321,6 +334,8 @@ FontCfgWrapper::FontCfgWrapper() loadSymbol( "FcConfigSubstitute" ); m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int)) loadSymbol( "FcPatternAddInteger" ); + m_pFcPatternAddDouble = (FcBool(*)(FcPattern*,const char*,double)) + loadSymbol( "FcPatternAddDouble" ); m_pFcPatternAddBool = (FcBool(*)(FcPattern*,const char*,FcBool)) loadSymbol( "FcPatternAddBool" ); m_pFcPatternAddCharSet = (FcBool(*)(FcPattern*,const char*,const FcCharSet *)) @@ -371,6 +386,7 @@ FontCfgWrapper::FontCfgWrapper() m_pFcDefaultSubstitute && m_pFcConfigSubstitute && m_pFcPatternAddInteger && + m_pFcPatternAddDouble && m_pFcPatternAddCharSet && m_pFcPatternAddBool && m_pFcPatternAddString @@ -503,53 +519,52 @@ namespace return candidate; } +} +FcResult FontCfgWrapper::FamilyFromPattern(FcPattern* pPattern, FcChar8 **family) +{ + FcChar8 *origfamily; + FcResult eFamilyRes = FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily ); + *family = origfamily; - FcResult lcl_FamilyFromPattern(FontCfgWrapper& rWrapper, FcPattern* pPattern, FcChar8 **family, - std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > &aFontconfigNameToLocalized) + if( eFamilyRes == FcResultMatch) { - FcChar8 *origfamily; - FcResult eFamilyRes = rWrapper.FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily ); - *family = origfamily; - - if( eFamilyRes == FcResultMatch) + FcChar8* familylang = NULL; + if (FcPatternGetString( pPattern, FC_FAMILYLANG, 0, &familylang ) == FcResultMatch) { - FcChar8* familylang = NULL; - if (rWrapper.FcPatternGetString( pPattern, FC_FAMILYLANG, 0, &familylang ) == FcResultMatch) + std::vector< lang_and_family > lang_and_families; + lang_and_families.push_back(lang_and_family(familylang, *family)); + int k = 1; + while (1) { - std::vector< lang_and_family > lang_and_families; + if (FcPatternGetString( pPattern, FC_FAMILYLANG, k, &familylang ) != FcResultMatch) + break; + if (FcPatternGetString( pPattern, FC_FAMILY, k, family ) != FcResultMatch) + break; lang_and_families.push_back(lang_and_family(familylang, *family)); - int k = 1; - while (1) - { - if (rWrapper.FcPatternGetString( pPattern, FC_FAMILYLANG, k, &familylang ) != FcResultMatch) - break; - if (rWrapper.FcPatternGetString( pPattern, FC_FAMILY, k, family ) != FcResultMatch) - break; - lang_and_families.push_back(lang_and_family(familylang, *family)); - ++k; - } + ++k; + } - //possible to-do, sort by UILocale instead of process locale - rtl_Locale* pLoc; - osl_getProcessLocale(&pLoc); - localizedsorter aSorter(pLoc); - *family = aSorter.bestname(lang_and_families); + //possible to-do, sort by UILocale instead of process locale + rtl_Locale* pLoc; + osl_getProcessLocale(&pLoc); + localizedsorter aSorter(pLoc); + *family = aSorter.bestname(lang_and_families); - std::vector<lang_and_family>::const_iterator aEnd = lang_and_families.end(); - for (std::vector<lang_and_family>::const_iterator aIter = lang_and_families.begin(); aIter != aEnd; ++aIter) - { - const char *candidate = (const char*)(aIter->second); - if (rtl_str_compare(candidate, (const char*)(*family)) != 0) - aFontconfigNameToLocalized[OString(candidate)] = OString((const char*)(*family)); - } + std::vector<lang_and_family>::const_iterator aEnd = lang_and_families.end(); + for (std::vector<lang_and_family>::const_iterator aIter = lang_and_families.begin(); aIter != aEnd; ++aIter) + { + const char *candidate = (const char*)(aIter->second); + if (rtl_str_compare(candidate, (const char*)(*family)) != 0) + m_aFontNameToLocalized[OString(candidate)] = OString((const char*)(*family)); } + if (rtl_str_compare((const char*)origfamily, (const char*)(*family)) != 0) + m_aLocalizedToCanonical[OString((const char*)(*family))] = OString((const char*)origfamily); } - - return eFamilyRes; } -} + return eFamilyRes; +} /* * PrintFontManager::initFontconfig @@ -562,7 +577,73 @@ bool PrintFontManager::initFontconfig() return true; } -int PrintFontManager::countFontconfigFonts() +namespace +{ + weight::type convertWeight(int weight) + { + // set weight + if( weight <= FC_WEIGHT_THIN ) + return weight::Thin; + else if( weight <= FC_WEIGHT_ULTRALIGHT ) + return weight::UltraLight; + else if( weight <= FC_WEIGHT_LIGHT ) + return weight::Light; + else if( weight <= FC_WEIGHT_BOOK ) + return weight::SemiLight; + else if( weight <= FC_WEIGHT_NORMAL ) + return weight::Normal; + else if( weight <= FC_WEIGHT_MEDIUM ) + return weight::Medium; + else if( weight <= FC_WEIGHT_SEMIBOLD ) + return weight::SemiBold; + else if( weight <= FC_WEIGHT_BOLD ) + return weight::Bold; + else if( weight <= FC_WEIGHT_ULTRABOLD ) + return weight::UltraBold; + return weight::Black; + } + + italic::type convertSlant(int slant) + { + // set italic + if( slant == FC_SLANT_ITALIC ) + return italic::Italic; + else if( slant == FC_SLANT_OBLIQUE ) + return italic::Oblique; + return italic::Upright; + } + + pitch::type convertSpacing(int spacing) + { + // set pitch + if( spacing == FC_MONO || spacing == FC_CHARCELL ) + return pitch::Fixed; + return pitch::Variable; + } + + width::type convertWidth(int width) + { + if (width == FC_WIDTH_ULTRACONDENSED) + return width::UltraCondensed; + else if (width == FC_WIDTH_EXTRACONDENSED) + return width::ExtraCondensed; + else if (width == FC_WIDTH_CONDENSED) + return width::Condensed; + else if (width == FC_WIDTH_SEMICONDENSED) + return width::SemiCondensed; + else if (width == FC_WIDTH_SEMIEXPANDED) + return width::SemiExpanded; + else if (width == FC_WIDTH_EXPANDED) + return width::Expanded; + else if (width == FC_WIDTH_EXTRAEXPANDED) + return width::ExtraExpanded; + else if (width == FC_WIDTH_ULTRAEXPANDED) + return width::UltraExpanded; + return width::Normal; + } +} + +int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl::OStringHash>& o_rVisitedPaths ) { int nFonts = 0; @@ -585,18 +666,16 @@ int PrintFontManager::countFontconfigFonts() int weight = 0; int spacing = 0; int nCollectionEntry = -1; - FcBool outline = false, embitmap = true, antialias = true; + FcBool outline = false; FcResult eFileRes = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_FILE, 0, &file ); - FcResult eFamilyRes = lcl_FamilyFromPattern(rWrapper, pFSet->fonts[i], &family, rWrapper.m_aFontconfigNameToLocalized ); + FcResult eFamilyRes = rWrapper.FamilyFromPattern( pFSet->fonts[i], &family ); FcResult eStyleRes = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_STYLE, 0, &style ); FcResult eSlantRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SLANT, 0, &slant ); FcResult eWeightRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_WEIGHT, 0, &weight ); FcResult eSpacRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SPACING, 0, &spacing ); FcResult eOutRes = rWrapper.FcPatternGetBool( pFSet->fonts[i], FC_OUTLINE, 0, &outline ); FcResult eIndexRes = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_INDEX, 0, &nCollectionEntry ); - FcResult eEmbeddedBitmap = rWrapper.FcPatternGetBool( pFSet->fonts[i], FC_EMBEDDED_BITMAP, 0, &embitmap ); - FcResult eAntialias = rWrapper.FcPatternGetBool( pFSet->fonts[i], FC_ANTIALIAS, 0, &antialias ); if( eFileRes != FcResultMatch || eFamilyRes != FcResultMatch || eOutRes != FcResultMatch ) continue; @@ -625,6 +704,9 @@ int PrintFontManager::countFontconfigFonts() std::list< PrintFont* > aFonts; OString aDir, aBase, aOrgPath( (sal_Char*)file ); splitPath( aOrgPath, aDir, aBase ); + + o_rVisitedPaths[aDir] = 1; + int nDirID = getDirectoryAtom( aDir, true ); if( ! m_pFontCache->getFontCacheFile( nDirID, aBase, aFonts ) ) { @@ -691,60 +773,15 @@ int PrintFontManager::countFontconfigFonts() pUpdate->m_nFamilyName = nFamilyName; } if( eWeightRes == FcResultMatch ) - { - // set weight - if( weight <= FC_WEIGHT_THIN ) - pUpdate->m_eWeight = weight::Thin; - else if( weight <= FC_WEIGHT_ULTRALIGHT ) - pUpdate->m_eWeight = weight::UltraLight; - else if( weight <= FC_WEIGHT_LIGHT ) - pUpdate->m_eWeight = weight::Light; - else if( weight <= FC_WEIGHT_BOOK ) - pUpdate->m_eWeight = weight::SemiLight; - else if( weight <= FC_WEIGHT_NORMAL ) - pUpdate->m_eWeight = weight::Normal; - else if( weight <= FC_WEIGHT_MEDIUM ) - pUpdate->m_eWeight = weight::Medium; - else if( weight <= FC_WEIGHT_SEMIBOLD ) - pUpdate->m_eWeight = weight::SemiBold; - else if( weight <= FC_WEIGHT_BOLD ) - pUpdate->m_eWeight = weight::Bold; - else if( weight <= FC_WEIGHT_ULTRABOLD ) - pUpdate->m_eWeight = weight::UltraBold; - else - pUpdate->m_eWeight = weight::Black; - } + pUpdate->m_eWeight = convertWeight(weight); if( eSpacRes == FcResultMatch ) - { - // set pitch - if( spacing == FC_PROPORTIONAL ) - pUpdate->m_ePitch = pitch::Variable; - else if( spacing == FC_MONO || spacing == FC_CHARCELL ) - pUpdate->m_ePitch = pitch::Fixed; - } + pUpdate->m_ePitch = convertSpacing(spacing); if( eSlantRes == FcResultMatch ) - { - // set italic - if( slant == FC_SLANT_ROMAN ) - pUpdate->m_eItalic = italic::Upright; - else if( slant == FC_SLANT_ITALIC ) - pUpdate->m_eItalic = italic::Italic; - else if( slant == FC_SLANT_OBLIQUE ) - pUpdate->m_eItalic = italic::Oblique; - } + pUpdate->m_eItalic = convertSlant(slant); if( eStyleRes == FcResultMatch ) { pUpdate->m_aStyleName = OStringToOUString( OString( (sal_Char*)style ), RTL_TEXTENCODING_UTF8 ); } - if( eEmbeddedBitmap == FcResultMatch ) - { - pUpdate->m_eEmbeddedbitmap = embitmap ? fcstatus::istrue : fcstatus::isfalse; - } - if( eAntialias == FcResultMatch ) - { - pUpdate->m_eAntialias = antialias ? fcstatus::istrue : fcstatus::isfalse; - } - // update font cache m_pFontCache->updateFontCacheEntry( pUpdate, false ); @@ -880,8 +917,8 @@ static void addtopattern(FontCfgWrapper& rWrapper, FcPattern *pPattern, rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, rtl::OUString& rMissingCodes, const rtl::OString &rLangAttrib, - italic::type eItalic, weight::type eWeight, - width::type eWidth, pitch::type ePitch) const + italic::type &rItalic, weight::type &rWeight, + width::type &rWidth, pitch::type &rPitch) const { rtl::OUString aName; FontCfgWrapper& rWrapper = FontCfgWrapper::get(); @@ -916,7 +953,7 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, rWrapper.FcCharSetDestroy( unicodes ); } - addtopattern(rWrapper, pPattern, eItalic, eWeight, eWidth, ePitch); + addtopattern(rWrapper, pPattern, rItalic, rWeight, rWidth, rPitch); // query fontconfig for a substitute rWrapper.FcConfigSubstitute( rWrapper.FcConfigGetCurrent(), pPattern, FcMatchPattern ); @@ -949,10 +986,21 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, if( eFileRes == FcResultMatch ) { OString sFamily((sal_Char*)family); - std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aFontconfigNameToLocalized.find(sFamily); - if (aI != rWrapper.m_aFontconfigNameToLocalized.end()) + std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aFontNameToLocalized.find(sFamily); + if (aI != rWrapper.m_aFontNameToLocalized.end()) sFamily = aI->second; aName = rtl::OStringToOUString( sFamily, RTL_TEXTENCODING_UTF8 ); + + + int val = 0; + if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WEIGHT, 0, &val)) + rWeight = convertWeight(val); + if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SLANT, 0, &val)) + rItalic = convertSlant(val); + if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SPACING, 0, &val)) + rPitch = convertSpacing(val); + if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WIDTH, 0, &val)) + rWidth = convertWidth(val); } // update rMissingCodes by removing resolved unicodes @@ -981,6 +1029,89 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName, return aName; } +bool PrintFontManager::getFontOptions( + const FastPrintFontInfo& rInfo, int nSize, void (*subcallback)(void*), + ImplFontOptions& rOptions) const +{ +#ifndef ENABLE_FONTCONFIG + return false; +#else // ENABLE_FONTCONFIG + FontCfgWrapper& rWrapper = FontCfgWrapper::get(); + if( ! rWrapper.isValid() ) + return false; + + FcConfig* pConfig = rWrapper.FcConfigGetCurrent(); + FcPattern* pPattern = rWrapper.FcPatternCreate(); + + OString sFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 ); + + std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = rWrapper.m_aLocalizedToCanonical.find(sFamily); + if (aI != rWrapper.m_aLocalizedToCanonical.end()) + sFamily = aI->second; + if( sFamily.getLength() ) + rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)sFamily.getStr() ); + + addtopattern(rWrapper, pPattern, rInfo.m_eItalic, rInfo.m_eWeight, rInfo.m_eWidth, rInfo.m_ePitch); + rWrapper.FcPatternAddDouble( pPattern, FC_PIXEL_SIZE, nSize); + + FcBool embitmap = true, antialias = true, autohint = true, hinting = true; + int hintstyle = FC_HINT_FULL; + + rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern ); + if (subcallback) subcallback(pPattern); + rWrapper.FcDefaultSubstitute( pPattern ); + + FcResult eResult = FcResultNoMatch; + FcFontSet* pFontSet = rWrapper.getFontSet(); + FcPattern* pResult = rWrapper.FcFontSetMatch( pConfig, &pFontSet, 1, pPattern, &eResult ); + if( pResult ) + { + FcFontSet* pSet = rWrapper.FcFontSetCreate(); + rWrapper.FcFontSetAdd( pSet, pResult ); + if( pSet->nfont > 0 ) + { + FcResult eEmbeddedBitmap = rWrapper.FcPatternGetBool(pSet->fonts[0], + FC_EMBEDDED_BITMAP, 0, &embitmap); + FcResult eAntialias = rWrapper.FcPatternGetBool(pSet->fonts[0], + FC_ANTIALIAS, 0, &antialias); + FcResult eAutoHint = rWrapper.FcPatternGetBool(pSet->fonts[0], + FC_AUTOHINT, 0, &autohint); + FcResult eHinting = rWrapper.FcPatternGetBool(pSet->fonts[0], + FC_HINTING, 0, &hinting); + /*FcResult eHintStyle =*/ rWrapper.FcPatternGetInteger( pSet->fonts[0], + FC_HINT_STYLE, 0, &hintstyle); + + if( eEmbeddedBitmap == FcResultMatch ) + rOptions.meEmbeddedBitmap = embitmap ? EMBEDDEDBITMAP_TRUE : EMBEDDEDBITMAP_FALSE; + if( eAntialias == FcResultMatch ) + rOptions.meAntiAlias = antialias ? ANTIALIAS_TRUE : ANTIALIAS_FALSE; + if( eAutoHint == FcResultMatch ) + rOptions.meAutoHint = autohint ? AUTOHINT_TRUE : AUTOHINT_FALSE; + if( eHinting == FcResultMatch ) + rOptions.meHinting = hinting ? HINTING_TRUE : HINTING_FALSE; + switch (hintstyle) + { + case FC_HINT_NONE: rOptions.meHintStyle = HINT_NONE; break; + case FC_HINT_SLIGHT: rOptions.meHintStyle = HINT_SLIGHT; break; + case FC_HINT_MEDIUM: rOptions.meHintStyle = HINT_MEDIUM; break; + default: // fall through + case FC_HINT_FULL: rOptions.meHintStyle = HINT_FULL; break; + } + } + // info: destroying the pSet destroys pResult implicitly + // since pResult was "added" to pSet + rWrapper.FcFontSetDestroy( pSet ); + } + + // cleanup + rWrapper.FcPatternDestroy( pPattern ); + + // TODO: return true only if non-default font options are set + const bool bOK = (pResult != NULL); + return bOK; +#endif +} + bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale ) { FontCfgWrapper& rWrapper = FontCfgWrapper::get(); @@ -1055,7 +1186,7 @@ bool PrintFontManager::initFontconfig() return false; } -int PrintFontManager::countFontconfigFonts() +int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl::OStringHash>& ) { return 0; } diff --git a/vcl/unx/source/fontmanager/fontmanager.cxx b/vcl/unx/source/fontmanager/fontmanager.cxx index aad53549f1ea..93e3eef53ab3 100644 --- a/vcl/unx/source/fontmanager/fontmanager.cxx +++ b/vcl/unx/source/fontmanager/fontmanager.cxx @@ -353,9 +353,7 @@ PrintFontManager::PrintFont::PrintFont( fonttype::type eType ) : m_nXMax( 0 ), m_nYMax( 0 ), m_bHaveVerticalSubstitutedGlyphs( false ), - m_bUserOverride( false ), - m_eEmbeddedbitmap( fcstatus::isunset ), - m_eAntialias( fcstatus::isunset ) + m_bUserOverride( false ) { } @@ -2151,10 +2149,14 @@ void PrintFontManager::initialize() } while( nIndex >= 0 ); } + // protect against duplicate paths + std::hash_map< OString, int, OStringHash > visited_dirs; + // now that all global and local font dirs are known to fontconfig // check that there are fonts actually managed by fontconfig + // also don't search directories that fontconfig already did if( m_bFontconfigSuccess ) - m_bFontconfigSuccess = (countFontconfigFonts() > 0); + m_bFontconfigSuccess = (countFontconfigFonts( visited_dirs ) > 0); // don't search through many directories fontconfig already told us about if( ! m_bFontconfigSuccess ) @@ -2165,8 +2167,6 @@ void PrintFontManager::initialize() // search for font files in each path std::list< OString >::iterator dir_it; - // protect against duplicate paths - std::hash_map< OString, int, OStringHash > visited_dirs; for( dir_it = m_aFontDirectories.begin(); dir_it != m_aFontDirectories.end(); ++dir_it ) { OString aPath( *dir_it ); @@ -2630,8 +2630,6 @@ void PrintFontManager::fillPrintFontInfo( PrintFont* pFont, FastPrintFontInfo& r rInfo.m_eWeight = pFont->m_eWeight; rInfo.m_ePitch = pFont->m_ePitch; rInfo.m_aEncoding = pFont->m_aEncoding; - rInfo.m_eEmbeddedbitmap = pFont->m_eEmbeddedbitmap; - rInfo.m_eAntialias = pFont->m_eAntialias; rInfo.m_bEmbeddable = (pFont->m_eType == fonttype::Type1); rInfo.m_bSubsettable = (pFont->m_eType == fonttype::TrueType); // TODO: rename to SfntType @@ -3936,8 +3934,6 @@ bool PrintFontManager::readOverrideMetrics() BuiltinFont* pFont = new BuiltinFont(); pFont->m_nDirectory = 0; pFont->m_bUserOverride = false; - pFont->m_eEmbeddedbitmap = fcstatus::isunset; - pFont->m_eAntialias = fcstatus::isunset; pFont->m_pMetrics = new PrintFontMetrics; memset( pFont->m_pMetrics->m_aPages, 0xff, sizeof( pFont->m_pMetrics->m_aPages ) ); pFont->m_pMetrics->m_bKernPairsQueried = true; diff --git a/vcl/unx/source/fontmanager/parseAFM.cxx b/vcl/unx/source/fontmanager/parseAFM.cxx index fd131121cbb5..e1a33b4d1b5d 100644 --- a/vcl/unx/source/fontmanager/parseAFM.cxx +++ b/vcl/unx/source/fontmanager/parseAFM.cxx @@ -403,89 +403,91 @@ static int parseGlobals( FileInputStream* fp, register GlobalFontInfo* gfi ) switch(recognize(keyword, tokenlen)) { case STARTFONTMETRICS: - keyword = token(fp,tokenlen); - gfi->afmVersion = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->afmVersion = strdup( keyword ); break; case COMMENT: keyword = linetoken(fp); break; case FONTNAME: - keyword = token(fp, tokenlen); - gfi->fontName = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontName = strdup( keyword ); break; case ENCODINGSCHEME: - keyword = token(fp, tokenlen); - gfi->encodingScheme = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->encodingScheme = strdup( keyword ); break; case FULLNAME: - keyword = linetoken(fp); - gfi->fullName = strdup( keyword ); + if ((keyword = linetoken(fp)) != NULL) + gfi->fullName = strdup( keyword ); break; case FAMILYNAME: - keyword = linetoken(fp); - gfi->familyName = strdup( keyword ); + if ((keyword = linetoken(fp)) != NULL) + gfi->familyName = strdup( keyword ); break; case WEIGHT: - keyword = token(fp, tokenlen); - gfi->weight = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->weight = strdup( keyword ); break; case ITALICANGLE: - keyword = token(fp,tokenlen); - gfi->italicAngle = StringToDouble( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->italicAngle = StringToDouble( keyword ); break; case ISFIXEDPITCH: - keyword = token(fp,tokenlen); - if (MATCH(keyword, False)) - gfi->isFixedPitch = 0; - else - gfi->isFixedPitch = 1; + if ((keyword = token(fp,tokenlen)) != NULL) + { + if (MATCH(keyword, False)) + gfi->isFixedPitch = 0; + else + gfi->isFixedPitch = 1; + } break; case UNDERLINEPOSITION: - keyword = token(fp,tokenlen); - gfi->underlinePosition = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->underlinePosition = atoi(keyword); break; case UNDERLINETHICKNESS: - keyword = token(fp,tokenlen); - gfi->underlineThickness = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->underlineThickness = atoi(keyword); break; case VERSION: - keyword = token(fp,tokenlen); - gfi->version = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->version = strdup( keyword ); break; case NOTICE: - keyword = linetoken(fp); - gfi->notice = strdup( keyword ); + if ((keyword = linetoken(fp)) != NULL) + gfi->notice = strdup( keyword ); break; case FONTBBOX: - keyword = token(fp,tokenlen); - gfi->fontBBox.llx = atoi(keyword); - keyword = token(fp,tokenlen); - gfi->fontBBox.lly = atoi(keyword); - keyword = token(fp,tokenlen); - gfi->fontBBox.urx = atoi(keyword); - keyword = token(fp,tokenlen); - gfi->fontBBox.ury = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.llx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.lly = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.urx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.ury = atoi(keyword); break; case CAPHEIGHT: - keyword = token(fp,tokenlen); - gfi->capHeight = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->capHeight = atoi(keyword); break; case XHEIGHT: - keyword = token(fp,tokenlen); - gfi->xHeight = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->xHeight = atoi(keyword); break; case DESCENT: - keyword = token(fp,tokenlen); - gfi->descender = -atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->descender = -atoi(keyword); break; case DESCENDER: - keyword = token(fp,tokenlen); - gfi->descender = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->descender = atoi(keyword); break; case ASCENT: case ASCENDER: - keyword = token(fp,tokenlen); - gfi->ascender = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->ascender = atoi(keyword); break; case STARTCHARMETRICS: cont = false; @@ -499,8 +501,8 @@ static int parseGlobals( FileInputStream* fp, register GlobalFontInfo* gfi ) keyword = token(fp,tokenlen); break; case STARTDIRECTION: - keyword = token(fp,tokenlen); - direction = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + direction = atoi(keyword); break; /* ignore this for now */ case ENDDIRECTION: break; /* ignore this for now */ @@ -523,9 +525,11 @@ static int parseGlobals( FileInputStream* fp, register GlobalFontInfo* gfi ) keyword=token(fp,tokenlen); //ignore break; case CHARWIDTH: - keyword = token(fp,tokenlen); - if (direction == 0) - gfi->charwidth = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + { + if (direction == 0) + gfi->charwidth = atoi(keyword); + } keyword = token(fp,tokenlen); /* ignore y-width for now */ break; @@ -584,24 +588,27 @@ static int initializeArray( FileInputStream* fp, register int* cwi) keyword = linetoken(fp); break; case CODE: - code = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + code = atoi(keyword); break; case CODEHEX: - sscanf(token(fp,tokenlen),"<%x>", &code); + if ((keyword = token(fp,tokenlen)) != NULL) + sscanf(keyword,"<%x>", &code); break; case XWIDTH: - width = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + width = atoi(keyword); break; case X0WIDTH: (void) token(fp,tokenlen); break; case CHARNAME: - keyword = token(fp,tokenlen); - if (MATCH(keyword, Space)) - { - cont = false; - found = true; - } + if ((keyword = token(fp,tokenlen)) != NULL) + if (MATCH(keyword, Space)) + { + cont = false; + found = true; + } break; case ENDCHARMETRICS: cont = false; @@ -690,8 +697,8 @@ static int parseCharWidths( FileInputStream* fp, register int* cwi) keyword = linetoken(fp); break; case CODE: - keyword = token(fp,tokenlen); - pos = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + pos = atoi(keyword); break; case XYWIDTH: /* PROBLEM: Should be no Y-WIDTH when doing "quick & dirty" */ @@ -699,16 +706,16 @@ static int parseCharWidths( FileInputStream* fp, register int* cwi) error = parseError; break; case CODEHEX: - keyword = token(fp,tokenlen); - sscanf(keyword, "<%x>", &pos); + if ((keyword = token(fp,tokenlen)) != NULL) + sscanf(keyword, "<%x>", &pos); break; case X0WIDTH: (void) token(fp,tokenlen); break; case XWIDTH: - keyword = token(fp,tokenlen); - if (pos >= 0) /* ignore unmapped chars */ - cwi[pos] = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + if (pos >= 0) /* ignore unmapped chars */ + cwi[pos] = atoi(keyword); break; case ENDCHARMETRICS: cont = false; @@ -835,7 +842,8 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) { if (firstTime) firstTime = false; else temp++; - temp->code = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->code = atoi(keyword); if (fi->gfi && fi->gfi->charwidth) temp->wx = fi->gfi->charwidth; count++; @@ -859,7 +867,8 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) firstTime = false; else temp++; - sscanf(token(fp,tokenlen),"<%x>", &temp->code); + if ((keyword = token(fp,tokenlen)) != NULL) + sscanf(keyword,"<%x>", &temp->code); if (fi->gfi && fi->gfi->charwidth) temp->wx = fi->gfi->charwidth; count++; @@ -870,24 +879,32 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) } break; case XYWIDTH: - temp->wx = atoi(token(fp,tokenlen)); - temp->wy = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wy = atoi(keyword); break; case X0WIDTH: - temp->wx = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wx = atoi(keyword); break; case XWIDTH: - temp->wx = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wx = atoi(keyword); break; case CHARNAME: - keyword = token(fp,tokenlen); - temp->name = (char *)strdup(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->name = (char *)strdup(keyword); break; case CHARBBOX: - temp->charBBox.llx = atoi(token(fp,tokenlen)); - temp->charBBox.lly = atoi(token(fp,tokenlen)); - temp->charBBox.urx = atoi(token(fp,tokenlen)); - temp->charBBox.ury = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.llx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.lly = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.urx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.ury = atoi(keyword); break; case LIGATURE: { Ligature **tail = &(temp->ligs); @@ -901,10 +918,10 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) } *tail = (Ligature *) calloc(1, sizeof(Ligature)); - keyword = token(fp,tokenlen); - (*tail)->succ = (char *)strdup(keyword); - keyword = token(fp,tokenlen); - (*tail)->lig = (char *)strdup(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + (*tail)->succ = (char *)strdup(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + (*tail)->lig = (char *)strdup(keyword); break; } case ENDCHARMETRICS: cont = false;; @@ -1000,16 +1017,16 @@ static int parseTrackKernData( FileInputStream* fp, register FontInfo* fi) if (tcount < fi->numOfTracks) { - keyword = token(fp,tokenlen); - fi->tkd[pos].degree = atoi(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos].minPtSize = StringToDouble(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos].minKernAmt = StringToDouble(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos].maxPtSize = StringToDouble(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos++].maxKernAmt = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].degree = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].minPtSize = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].minKernAmt = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].maxPtSize = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos++].maxKernAmt = StringToDouble(keyword); tcount++; } else @@ -1107,14 +1124,14 @@ static int parsePairKernData( FileInputStream* fp, register FontInfo* fi) } if (pcount < fi->numOfPairs) { - keyword = token(fp,tokenlen); - fi->pkd[pos].name1 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos].name2 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos].xamt = atoi(keyword); - keyword = token(fp,tokenlen); - fi->pkd[pos++].yamt = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name1 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name2 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].xamt = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos++].yamt = atoi(keyword); pcount++; } else @@ -1131,12 +1148,12 @@ static int parsePairKernData( FileInputStream* fp, register FontInfo* fi) } if (pcount < fi->numOfPairs) { - keyword = token(fp,tokenlen); - fi->pkd[pos].name1 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos].name2 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos++].xamt = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name1 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name2 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos++].xamt = atoi(keyword); pcount++; } else @@ -1258,8 +1275,8 @@ static int parseCompCharData( FileInputStream* fp, register FontInfo* fi) if (firstTime) firstTime = false; else pos++; fi->ccd[pos].ccName = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->ccd[pos].numOfPieces = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].numOfPieces = atoi(keyword); fi->ccd[pos].pieces = (Pcc *) calloc(fi->ccd[pos].numOfPieces, sizeof(Pcc)); j = 0; @@ -1274,12 +1291,12 @@ static int parseCompCharData( FileInputStream* fp, register FontInfo* fi) case COMPCHARPIECE: if (pcount < fi->ccd[pos].numOfPieces) { - keyword = token(fp,tokenlen); - fi->ccd[pos].pieces[j].pccName = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->ccd[pos].pieces[j].deltax = atoi(keyword); - keyword = token(fp,tokenlen); - fi->ccd[pos].pieces[j++].deltay = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].pieces[j].pccName = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].pieces[j].deltax = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].pieces[j++].deltay = atoi(keyword); pcount++; } else @@ -1373,7 +1390,8 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) if ((code != normalEOF) && (code != earlyEOF)) { - (*fi)->numOfChars = atoi(token(&aFile,tokenlen)); + if ((keyword = token(&aFile,tokenlen)) != NULL) + (*fi)->numOfChars = atoi(keyword); if (flags & (P_M ^ P_W)) { (*fi)->cmi = (CharMetricInfo *) @@ -1423,7 +1441,7 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) break; case STARTTRACKKERN: keyword = token(&aFile,tokenlen); - if (flags & P_T) + if ((flags & P_T) && keyword) { (*fi)->numOfTracks = atoi(keyword); (*fi)->tkd = (TrackKernData *) @@ -1438,7 +1456,7 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) break; case STARTKERNPAIRS: keyword = token(&aFile,tokenlen); - if (flags & P_P) + if ((flags & P_P) && keyword) { (*fi)->numOfPairs = atoi(keyword); (*fi)->pkd = (PairKernData *) @@ -1453,7 +1471,7 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) break; case STARTCOMPOSITES: keyword = token(&aFile,tokenlen); - if (flags & P_C) + if ((flags & P_C) && keyword) { (*fi)->numOfComps = atoi(keyword); (*fi)->ccd = (CompCharData *) diff --git a/vcl/unx/source/gdi/gcach_xpeer.cxx b/vcl/unx/source/gdi/gcach_xpeer.cxx index 634f79d3e002..a69a2426b519 100644 --- a/vcl/unx/source/gdi/gcach_xpeer.cxx +++ b/vcl/unx/source/gdi/gcach_xpeer.cxx @@ -119,7 +119,7 @@ void X11GlyphPeer::InitAntialiasing() // enable XRENDER accelerated aliasing on screens that support it // unless it explicitly disabled by an environment variable if( (nEnvAntiAlias & 2) == 0 ) - mnUsingXRender = XRenderPeer::GetInstance().InitRenderText( mnMaxScreens ); + mnUsingXRender = XRenderPeer::GetInstance().InitRenderText(); // else enable client side antialiasing for these screens // unless it is explicitly disabled by an environment variable diff --git a/vcl/unx/source/gdi/pspgraphics.cxx b/vcl/unx/source/gdi/pspgraphics.cxx index 10a51afeb696..d599e09e71f2 100644 --- a/vcl/unx/source/gdi/pspgraphics.cxx +++ b/vcl/unx/source/gdi/pspgraphics.cxx @@ -1284,32 +1284,6 @@ ImplDevFontAttributes PspGraphics::Info2DevFontAttributes( const psp::FastPrintF aDFA.mbSubsettable = rInfo.m_bSubsettable; aDFA.mbEmbeddable = rInfo.m_bEmbeddable; - switch (rInfo.m_eEmbeddedbitmap) - { - default: - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - break; - case psp::fcstatus::istrue: - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_TRUE; - break; - case psp::fcstatus::isfalse: - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_FALSE; - break; - } - - switch (rInfo.m_eAntialias) - { - default: - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - break; - case psp::fcstatus::istrue: - aDFA.meAntiAlias = ANTIALIAS_TRUE; - break; - case psp::fcstatus::isfalse: - aDFA.meAntiAlias = ANTIALIAS_FALSE; - break; - } - switch( rInfo.m_eType ) { case psp::fonttype::Builtin: diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx index bb5e7c68b356..7cf2009a3e07 100644 --- a/vcl/unx/source/gdi/salgdi3.cxx +++ b/vcl/unx/source/gdi/salgdi3.cxx @@ -630,12 +630,26 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry ); if( pServerFont != NULL ) { + // ignore fonts with e.g. corrupted font files if( !pServerFont->TestFont() ) { GlyphCache::GetInstance().UncacheFont( *pServerFont ); return false; } + + // register to use the font mpServerFont[ nFallbackLevel ] = pServerFont; + + // apply font specific-hint settings if needed + if( !bPrinter_ ) + { + // TODO: is it worth it to cache the hint settings, e.g. in the ImplFontEntry? + ImplFontOptions aFontOptions; + bool GetFCFontOptions( const ImplFontAttributes&, int nSize, ImplFontOptions&); + if( GetFCFontOptions( *pEntry->mpFontData, pEntry->mnHeight, aFontOptions ) ) + pServerFont->SetFontOptions( aFontOptions ); + } + return true; } @@ -743,6 +757,8 @@ private: void (*mp_set_font_matrix)(cairo_t *, const cairo_matrix_t *); void (*mp_show_glyphs)(cairo_t *, const cairo_glyph_t *, int ); void (*mp_set_source_rgb)(cairo_t *, double , double , double ); + void (*mp_set_font_options)(cairo_t *, const void *); + void (*mp_ft_font_options_substitute)(const void*, void*); bool canEmbolden() const { return false; } @@ -778,6 +794,10 @@ public: { (*mp_show_glyphs)(cr, glyphs, no_glyphs); } void set_source_rgb(cairo_t *cr, double red, double green, double blue) { (*mp_set_source_rgb)(cr, red, green, blue); } + void set_font_options(cairo_t *cr, const void *options) + { (*mp_set_font_options)(cr, options); } + void ft_font_options_substitute(const void *options, void *pattern) + { (*mp_ft_font_options_substitute)(options, pattern); } }; static CairoWrapper* pCairoInstance = NULL; @@ -847,6 +867,10 @@ CairoWrapper::CairoWrapper() osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_show_glyphs" ); mp_set_source_rgb = (void (*)(cairo_t *, double , double , double )) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_source_rgb" ); + mp_set_font_options = (void (*)(cairo_t *, const void *options )) + osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_font_options" ); + mp_ft_font_options_substitute = (void (*)(const void *, void *)) + osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_ft_font_options_substitute" ); if( !( mp_xlib_surface_create_with_xrender_format && @@ -863,7 +887,9 @@ CairoWrapper::CairoWrapper() mp_matrix_rotate && mp_set_font_matrix && mp_show_glyphs && - mp_set_source_rgb + mp_set_source_rgb && + mp_set_font_options && + mp_ft_font_options_substitute ) ) { osl_unloadModule( mpCairoLib ); @@ -971,6 +997,9 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout ) cairo_t *cr = rCairo.create(surface); rCairo.surface_destroy(surface); + if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions()) + rCairo.set_font_options( cr, pOptions); + if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) ) { for (long i = 0; i < pClipRegion_->numRects; ++i) @@ -1059,7 +1088,7 @@ void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout ) } // set font foreground color and opacity - XRenderColor aRenderColor = GetXRenderColor( nTextPixel_ ); + XRenderColor aRenderColor = GetXRenderColor( nTextColor_ ); rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 ); // set clipping @@ -1601,6 +1630,122 @@ void X11SalGraphics::GetDevFontSubstList( OutputDevice* ) // ---------------------------------------------------------------------------- +void cairosubcallback( void* pPattern ) +{ + CairoWrapper& rCairo = CairoWrapper::get(); + if( rCairo.isValid() ) + { + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + rCairo.ft_font_options_substitute( rStyleSettings.GetCairoFontOptions(), pPattern); + } +} + +bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, + ImplFontOptions& rFontOptions) +{ + // TODO: get rid of these insane enum-conversions + // e.g. by using the classic vclenum values inside VCL + + psp::FastPrintFontInfo aInfo; + // set family name + aInfo.m_aFamilyName = rFontAttributes.GetFamilyName(); + // set italic + switch( rFontAttributes.GetSlant() ) + { + case ITALIC_NONE: + aInfo.m_eItalic = psp::italic::Upright; + break; + case ITALIC_NORMAL: + aInfo.m_eItalic = psp::italic::Italic; + break; + case ITALIC_OBLIQUE: + aInfo.m_eItalic = psp::italic::Oblique; + break; + default: + aInfo.m_eItalic = psp::italic::Unknown; + break; + + } + // set weight + switch( rFontAttributes.GetWeight() ) + { + case WEIGHT_THIN: + aInfo.m_eWeight = psp::weight::Thin; + break; + case WEIGHT_ULTRALIGHT: + aInfo.m_eWeight = psp::weight::UltraLight; + break; + case WEIGHT_LIGHT: + aInfo.m_eWeight = psp::weight::Light; + break; + case WEIGHT_SEMILIGHT: + aInfo.m_eWeight = psp::weight::SemiLight; + break; + case WEIGHT_NORMAL: + aInfo.m_eWeight = psp::weight::Normal; + break; + case WEIGHT_MEDIUM: + aInfo.m_eWeight = psp::weight::Medium; + break; + case WEIGHT_SEMIBOLD: + aInfo.m_eWeight = psp::weight::SemiBold; + break; + case WEIGHT_BOLD: + aInfo.m_eWeight = psp::weight::Bold; + break; + case WEIGHT_ULTRABOLD: + aInfo.m_eWeight = psp::weight::UltraBold; + break; + case WEIGHT_BLACK: + aInfo.m_eWeight = psp::weight::Black; + break; + default: + aInfo.m_eWeight = psp::weight::Unknown; + break; + } + // set width + switch( rFontAttributes.GetWidthType() ) + { + case WIDTH_ULTRA_CONDENSED: + aInfo.m_eWidth = psp::width::UltraCondensed; + break; + case WIDTH_EXTRA_CONDENSED: + aInfo.m_eWidth = psp::width::ExtraCondensed; + break; + case WIDTH_CONDENSED: + aInfo.m_eWidth = psp::width::Condensed; + break; + case WIDTH_SEMI_CONDENSED: + aInfo.m_eWidth = psp::width::SemiCondensed; + break; + case WIDTH_NORMAL: + aInfo.m_eWidth = psp::width::Normal; + break; + case WIDTH_SEMI_EXPANDED: + aInfo.m_eWidth = psp::width::SemiExpanded; + break; + case WIDTH_EXPANDED: + aInfo.m_eWidth = psp::width::Expanded; + break; + case WIDTH_EXTRA_EXPANDED: + aInfo.m_eWidth = psp::width::ExtraExpanded; + break; + case WIDTH_ULTRA_EXPANDED: + aInfo.m_eWidth = psp::width::UltraExpanded; + break; + default: + aInfo.m_eWidth = psp::width::Unknown; + break; + } + + const psp::PrintFontManager& rPFM = psp::PrintFontManager::get(); + bool bOK = rPFM.getFontOptions( aInfo, nSize, cairosubcallback, rFontOptions); + + return bOK; +} + +// ---------------------------------------------------------------------------- + void X11SalGraphics::GetFontMetric( ImplFontMetricData *pMetric ) { @@ -1876,8 +2021,10 @@ void RegisterFontSubstitutors( ImplDevFontList* pList ) // ----------------------------------------------------------------------- -static rtl::OUString GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUString& rMissingCodes ) +static ImplFontSelectData GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUString& rMissingCodes ) { + ImplFontSelectData aRet(rFontSelData); + const rtl::OString aLangAttrib; //TODO: = MsLangId::convertLanguageToIsoByteString( rFontSelData.meLanguage ); psp::italic::type eItalic = psp::italic::Unknown; @@ -1945,7 +2092,72 @@ static rtl::OUString GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUS } const psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); - return rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch); + aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch); + + switch (eItalic) + { + case psp::italic::Upright: aRet.meItalic = ITALIC_NONE; break; + case psp::italic::Italic: aRet.meItalic = ITALIC_NORMAL; break; + case psp::italic::Oblique: aRet.meItalic = ITALIC_OBLIQUE; break; + default: + break; + } + + switch (eWeight) + { + case psp::weight::Thin: aRet.meWeight = WEIGHT_THIN; break; + case psp::weight::UltraLight: aRet.meWeight = WEIGHT_ULTRALIGHT; break; + case psp::weight::Light: aRet.meWeight = WEIGHT_LIGHT; break; + case psp::weight::SemiLight: aRet.meWeight = WEIGHT_SEMILIGHT; break; + case psp::weight::Normal: aRet.meWeight = WEIGHT_NORMAL; break; + case psp::weight::Medium: aRet.meWeight = WEIGHT_MEDIUM; break; + case psp::weight::SemiBold: aRet.meWeight = WEIGHT_SEMIBOLD; break; + case psp::weight::Bold: aRet.meWeight = WEIGHT_BOLD; break; + case psp::weight::UltraBold: aRet.meWeight = WEIGHT_ULTRABOLD; break; + case psp::weight::Black: aRet.meWeight = WEIGHT_BLACK; break; + default: + break; + } + + switch (eWidth) + { + case psp::width::UltraCondensed: aRet.meWidthType = WIDTH_ULTRA_CONDENSED; break; + case psp::width::ExtraCondensed: aRet.meWidthType = WIDTH_EXTRA_CONDENSED; break; + case psp::width::Condensed: aRet.meWidthType = WIDTH_CONDENSED; break; + case psp::width::SemiCondensed: aRet.meWidthType = WIDTH_SEMI_CONDENSED; break; + case psp::width::Normal: aRet.meWidthType = WIDTH_NORMAL; break; + case psp::width::SemiExpanded: aRet.meWidthType = WIDTH_SEMI_EXPANDED; break; + case psp::width::Expanded: aRet.meWidthType = WIDTH_EXPANDED; break; + case psp::width::ExtraExpanded: aRet.meWidthType = WIDTH_EXTRA_EXPANDED; break; + case psp::width::UltraExpanded: aRet.meWidthType = WIDTH_ULTRA_EXPANDED; break; + default: + break; + } + + switch (ePitch) + { + case psp::pitch::Fixed: aRet.mePitch = PITCH_FIXED; break; + case psp::pitch::Variable: aRet.mePitch = PITCH_VARIABLE; break; + default: + break; + } + + return aRet; +} + +namespace +{ + bool uselessmatch(const ImplFontSelectData &rOrig, const ImplFontSelectData &rNew) + { + return + ( + rOrig.maTargetName == rNew.maSearchName && + rOrig.meWeight == rNew.meWeight && + rOrig.meItalic == rNew.meItalic && + rOrig.mePitch == rNew.mePitch && + rOrig.meWidthType == rNew.meWidthType + ); + } } //-------------------------------------------------------------------------- @@ -1953,7 +2165,7 @@ static rtl::OUString GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUS bool FcPreMatchSubstititution::FindFontSubstitute( ImplFontSelectData &rFontSelData ) const { // We dont' actually want to talk to Fontconfig at all for symbol fonts - if (rFontSelData.IsSymbolFont()) + if( rFontSelData.IsSymbolFont() ) return false; // StarSymbol is a unicode font, but it still deserves the symbol flag if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10) @@ -1961,21 +2173,33 @@ bool FcPreMatchSubstititution::FindFontSubstitute( ImplFontSelectData &rFontSelD return false; rtl::OUString aDummy; - const rtl::OUString aOUName = GetFcSubstitute( rFontSelData, aDummy ); - if( !aOUName.getLength() ) - return false; - const String aName( aOUName ); - if( aName == rFontSelData.maTargetName ) + const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, aDummy ); + // TODO: cache the font substitution suggestion + // FC doing it would be preferable because it knows the invariables + // e.g. FC knows the FC rule that all Arial gets replaced by LiberationSans + // whereas we would have to check for every size or attribute + if( !aOut.maSearchName.Len() ) return false; + const bool bHaveSubstitute = !uselessmatch( rFontSelData, aOut ); + #ifdef DEBUG - ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); - ByteString aSubstName( aName, RTL_TEXTENCODING_UTF8 ); - printf( "FcPreMatchSubstititution \"%s\" -> \"%s\"\n", - aOrigName.GetBuffer(), aSubstName.GetBuffer() ); + const ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); + const ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 ); + printf( "FcPreMatchSubstititution \"%s\" bipw=%d%d%d%d -> ", + aOrigName.GetBuffer(), rFontSelData.meWeight, rFontSelData.meItalic, + rFontSelData.mePitch, rFontSelData.meWidthType ); + if( !bHaveSubstitute ) + printf( "no substitute available\n" ); + else + printf( "\"%s\" bipw=%d%d%d%d\n", aSubstName.GetBuffer(), + aOut.meWeight, aOut.meItalic, aOut.mePitch, aOut.meWidthType ); #endif - rFontSelData.maSearchName = aName; - return true; + + if( bHaveSubstitute ) + rFontSelData = aOut; + + return bHaveSubstitute; } // ----------------------------------------------------------------------- @@ -1991,22 +2215,33 @@ bool FcGlyphFallbackSubstititution::FindFontSubstitute( ImplFontSelectData& rFon || 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) ) return false; - const rtl::OUString aOUName = GetFcSubstitute( rFontSelData, rMissingCodes ); - // TODO: cache the unicode+font specific result - if( !aOUName.getLength() ) - return false; - const String aName( aOUName ); - if( aName == rFontSelData.maTargetName ) + const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, rMissingCodes ); + // TODO: cache the unicode + srcfont specific result + // FC doing it would be preferable because it knows the invariables + // e.g. FC knows the FC rule that all Arial gets replaced by LiberationSans + // whereas we would have to check for every size or attribute + if( !aOut.maSearchName.Len() ) return false; + const bool bHaveSubstitute = !uselessmatch( rFontSelData, aOut ); + #ifdef DEBUG - ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); - ByteString aSubstName( aName, RTL_TEXTENCODING_UTF8 ); - printf( "FcGlyphFallbackSubstititution \"%s\" -> \"%s\"\n", - aOrigName.GetBuffer(), aSubstName.GetBuffer() ); + const ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); + const ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 ); + printf( "FcGFSubstititution \"%s\" bipw=%d%d%d%d ->", + aOrigName.GetBuffer(), rFontSelData.meWeight, rFontSelData.meItalic, + rFontSelData.mePitch, rFontSelData.meWidthType ); + if( !bHaveSubstitute ) + printf( "no substitute available\n" ); + else + printf( "\"%s\" bipw=%d%d%d%d\n", aSubstName.GetBuffer(), + aOut.meWeight, aOut.meItalic, aOut.mePitch, aOut.meWidthType ); #endif - rFontSelData.maSearchName = aName; - return true; + + if( bHaveSubstitute ) + rFontSelData = aOut; + + return bHaveSubstitute; } // =========================================================================== diff --git a/vcl/unx/source/gdi/xlfd_extd.cxx b/vcl/unx/source/gdi/xlfd_extd.cxx index 8449fcc5872e..73731eddf115 100644 --- a/vcl/unx/source/gdi/xlfd_extd.cxx +++ b/vcl/unx/source/gdi/xlfd_extd.cxx @@ -102,9 +102,6 @@ ExtendedXlfd::ExtendedXlfd( bool bScalable ) mbSubsettable = false; mbEmbeddable = false; - meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - meAntiAlias = ANTIALIAS_DONTKNOW; - mnQuality = -1; } diff --git a/vcl/unx/source/gdi/xrender_peer.cxx b/vcl/unx/source/gdi/xrender_peer.cxx index c5d84cffab58..8d24e4098df4 100644 --- a/vcl/unx/source/gdi/xrender_peer.cxx +++ b/vcl/unx/source/gdi/xrender_peer.cxx @@ -25,6 +25,9 @@ * ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + #include <stdio.h> #include <rtl/ustring.hxx> #include <osl/module.h> @@ -172,7 +175,7 @@ void XRenderPeer::InitRenderLib() #if 0 // not having trapezoid support is supported if( !pFunc ) return; #endif - mpXRenderAddTraps = (void(*)(Display*,Picture,int,int,const XTrap*,int))pFunc; + mpXRenderAddTraps = (void(*)(Display*,Picture,int,int,const _XTrap*,int))pFunc; #endif // XRENDER_LINK @@ -190,12 +193,16 @@ void XRenderPeer::InitRenderLib() (*mpXRenderQueryVersion)( mpDisplay, &nMajor, &nMinor ); #endif mnRenderVersion = 16*nMajor + nMinor; + + // the 8bit alpha mask format must be there + XRenderPictFormat aPictFormat={0,0,8,{0,0,0,0,0,0,0,0xFF},0}; + mpStandardFormatA8 = FindPictureFormat( PictFormatAlphaMask|PictFormatDepth, aPictFormat ); } // --------------------------------------------------------------------------- // return mask of screens capable of XRENDER text -sal_uInt32 XRenderPeer::InitRenderText( int nMaxDepth ) +sal_uInt32 XRenderPeer::InitRenderText() { if( mnRenderVersion < 0x01 ) return 0; @@ -206,9 +213,6 @@ sal_uInt32 XRenderPeer::InitRenderText( int nMaxDepth ) if( mnRenderVersion < 0x02 ) return 0; - // the 8bit alpha mask format must be there - XRenderPictFormat aPictFormat={0,0,8,{0,0,0,0,0,0,0,0xFF},0}; - mpStandardFormatA8 = FindPictureFormat( PictFormatAlphaMask|PictFormatDepth, aPictFormat ); if( !mpStandardFormatA8 ) return 0; @@ -217,18 +221,24 @@ sal_uInt32 XRenderPeer::InitRenderText( int nMaxDepth ) SalDisplay* pSalDisp = GetX11SalData()->GetDisplay(); const int nScreenCount = pSalDisp->GetScreenCount(); XRenderPictFormat* pVisualFormat = NULL; + int nMaxDepth = 0; for( int nScreen = 0; nScreen < nScreenCount; ++nScreen ) { Visual* pXVisual = pSalDisp->GetVisual( nScreen ).GetVisual(); pVisualFormat = FindVisualFormat( pXVisual ); if( pVisualFormat != NULL ) + { + int nVDepth = pSalDisp->GetVisual( nScreen ).GetDepth(); + if( nVDepth > nMaxDepth ) + nMaxDepth = nVDepth; nRetMask |= 1U << nScreen; + } } // #97763# disable XRENDER on <15bit displays for XFree<=4.2.0 if( mnRenderVersion <= 0x02 ) if( nMaxDepth < 15 ) - return 0; + nRetMask = 0; return nRetMask; } diff --git a/vcl/unx/source/gdi/xrender_peer.hxx b/vcl/unx/source/gdi/xrender_peer.hxx index 6d40015ee94d..89dccfcef40b 100644 --- a/vcl/unx/source/gdi/xrender_peer.hxx +++ b/vcl/unx/source/gdi/xrender_peer.hxx @@ -29,6 +29,7 @@ #define _SV_XRENDER_PEER_HXX #include <tools/prex.h> +struct _XTrap; // on some older systems this is not declared within Xrender.h #include <X11/extensions/Xrender.h> #include <tools/postx.h> @@ -41,7 +42,7 @@ public: static XRenderPeer& GetInstance(); int GetVersion() const; - sal_uInt32 InitRenderText( int nMaxDepth ); + sal_uInt32 InitRenderText(); protected: XRenderPeer(); @@ -84,7 +85,7 @@ public: const XRenderPictFormat*, int nXSrc, int nYSrc, const XTrapezoid*, int nCount ) const; bool AddTraps( Picture aDst, int nXOfs, int nYOfs, - const XTrap*, int nCount ) const; + const _XTrap*, int nCount ) const; bool AreTrapezoidsSupported() const #ifdef XRENDER_LINK @@ -120,7 +121,7 @@ private: const XRenderColor*,int,int,unsigned int,unsigned int); void (*mpXRenderCompositeTrapezoids)(Display*,int,Picture,Picture, const XRenderPictFormat*,int,int,const XTrapezoid*,int); - void (*mpXRenderAddTraps)(Display*,Picture,int,int,const XTrap*,int); + void (*mpXRenderAddTraps)(Display*,Picture,int,int,const _XTrap*,int); #endif // XRENDER_LINK }; @@ -326,7 +327,7 @@ inline void XRenderPeer::CompositeTrapezoids( int nOp, } inline bool XRenderPeer::AddTraps( Picture aDst, int nXOfs, int nYOfs, - const XTrap* pTraps, int nCount ) const + const _XTrap* pTraps, int nCount ) const { #ifdef XRENDER_LINK XRenderAddTraps( mpDisplay, aDst, nXOfs, nYOfs, pTraps, nCount ); diff --git a/vcl/unx/source/printer/ppdparser.cxx b/vcl/unx/source/printer/ppdparser.cxx index 971db860cf42..b2549573d099 100644 --- a/vcl/unx/source/printer/ppdparser.cxx +++ b/vcl/unx/source/printer/ppdparser.cxx @@ -258,7 +258,6 @@ using namespace rtl; std::list< PPDParser* > PPDParser::aAllParsers; std::hash_map< OUString, OUString, OUStringHash >* PPDParser::pAllPPDFiles = NULL; -static String aEmptyString; class PPDDecompressStream { @@ -1284,12 +1283,12 @@ void PPDParser::parseConstraint( const ByteString& rLine ) m_aConstraints.push_back( aConstraint ); } -const String& PPDParser::getDefaultPaperDimension() const +String PPDParser::getDefaultPaperDimension() const { if( m_pDefaultPaperDimension ) return m_pDefaultPaperDimension->m_aOption; - return aEmptyString; + return String(); } bool PPDParser::getMargins( @@ -1356,10 +1355,10 @@ bool PPDParser::getPaperDimension( return true; } -const String& PPDParser::matchPaper( int nWidth, int nHeight ) const +String PPDParser::matchPaper( int nWidth, int nHeight ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); int nPDim = -1; double PDWidth, PDHeight; @@ -1393,51 +1392,51 @@ const String& PPDParser::matchPaper( int nWidth, int nHeight ) const { // swap portrait/landscape and try again bDontSwap = true; - const String& rRet = matchPaper( nHeight, nWidth ); + String rRet = matchPaper( nHeight, nWidth ); bDontSwap = false; return rRet; } - return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : aEmptyString; + return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : String(); } -const String& PPDParser::getDefaultInputSlot() const +String PPDParser::getDefaultInputSlot() const { if( m_pDefaultInputSlot ) return m_pDefaultInputSlot->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getSlot( int nSlot ) const +String PPDParser::getSlot( int nSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); if( nSlot > 0 && nSlot < m_pInputSlots->countValues() ) return m_pInputSlots->getValue( nSlot )->m_aOption; else if( m_pInputSlots->countValues() > 0 ) return m_pInputSlots->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getSlotCommand( int nSlot ) const +String PPDParser::getSlotCommand( int nSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); if( nSlot > 0 && nSlot < m_pInputSlots->countValues() ) return m_pInputSlots->getValue( nSlot )->m_aValue; else if( m_pInputSlots->countValues() > 0 ) return m_pInputSlots->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getSlotCommand( const String& rSlot ) const +String PPDParser::getSlotCommand( const String& rSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); for( int i=0; i < m_pInputSlots->countValues(); i++ ) { @@ -1445,39 +1444,39 @@ const String& PPDParser::getSlotCommand( const String& rSlot ) const if( pValue->m_aOption == rSlot ) return pValue->m_aValue; } - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimension( int nPaperDimension ) const +String PPDParser::getPaperDimension( int nPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() ) return m_pPaperDimensions->getValue( nPaperDimension )->m_aOption; else if( m_pPaperDimensions->countValues() > 0 ) return m_pPaperDimensions->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimensionCommand( int nPaperDimension ) const +String PPDParser::getPaperDimensionCommand( int nPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() ) return m_pPaperDimensions->getValue( nPaperDimension )->m_aValue; else if( m_pPaperDimensions->countValues() > 0 ) return m_pPaperDimensions->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimensionCommand( const String& rPaperDimension ) const +String PPDParser::getPaperDimensionCommand( const String& rPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); for( int i=0; i < m_pPaperDimensions->countValues(); i++ ) { @@ -1485,7 +1484,7 @@ const String& PPDParser::getPaperDimensionCommand( const String& rPaperDimension if( pValue->m_aOption == rPaperDimension ) return pValue->m_aValue; } - return aEmptyString; + return String(); } void PPDParser::getResolutionFromString( @@ -1543,13 +1542,13 @@ void PPDParser::getResolution( int nNr, int& rXRes, int& rYRes ) const rXRes, rYRes ); } -const String& PPDParser::getResolutionCommand( int nXRes, int nYRes ) const +String PPDParser::getResolutionCommand( int nXRes, int nYRes ) const { if( ( ! m_pResolutions || m_pResolutions->countValues() == 0 ) && m_pDefaultResolution ) return m_pDefaultResolution->m_aValue; if( ! m_pResolutions ) - return aEmptyString; + return String(); int nX, nY; for( int i = 0; i < m_pResolutions->countValues(); i++ ) @@ -1559,46 +1558,46 @@ const String& PPDParser::getResolutionCommand( int nXRes, int nYRes ) const if( nX == nXRes && nY == nYRes ) return m_pResolutions->getValue( i )->m_aValue; } - return aEmptyString; + return String(); } -const String& PPDParser::getDefaultDuplexType() const +String PPDParser::getDefaultDuplexType() const { if( m_pDefaultDuplexType ) return m_pDefaultDuplexType->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplex( int nDuplex ) const +String PPDParser::getDuplex( int nDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() ) return m_pDuplexTypes->getValue( nDuplex )->m_aOption; else if( m_pDuplexTypes->countValues() > 0 ) return m_pDuplexTypes->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplexCommand( int nDuplex ) const +String PPDParser::getDuplexCommand( int nDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() ) return m_pDuplexTypes->getValue( nDuplex )->m_aValue; else if( m_pDuplexTypes->countValues() > 0 ) return m_pDuplexTypes->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplexCommand( const String& rDuplex ) const +String PPDParser::getDuplexCommand( const String& rDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); for( int i=0; i < m_pDuplexTypes->countValues(); i++ ) { @@ -1606,7 +1605,7 @@ const String& PPDParser::getDuplexCommand( const String& rDuplex ) const if( pValue->m_aOption == rDuplex ) return pValue->m_aValue; } - return aEmptyString; + return String(); } void PPDParser::getFontAttributes( @@ -1636,14 +1635,14 @@ void PPDParser::getFontAttributes( } } -const String& PPDParser::getFont( int nFont ) const +String PPDParser::getFont( int nFont ) const { if( ! m_pFontList ) - return aEmptyString; + return String(); if( nFont >=0 && nFont < m_pFontList->countValues() ) return m_pFontList->getValue( nFont )->m_aOption; - return aEmptyString; + return String(); } rtl::OUString PPDParser::translateKey( const rtl::OUString& i_rKey, diff --git a/vcl/util/makefile2.pmk b/vcl/util/makefile2.pmk index 56102a256ea3..df9ba1a214d7 100644 --- a/vcl/util/makefile2.pmk +++ b/vcl/util/makefile2.pmk @@ -36,6 +36,6 @@ CFLAGSCXX+=$(OBJCXXFLAGS) #building with stlport, but graphite was not built with stlport .IF "$(USE_SYSTEM_STL)"!="YES" .IF "$(SYSTEM_GRAPHITE)"=="YES" -CDEFS += -DGRAPHITEADAPTSTL +CDEFS += -DADAPT_EXT_STL .ENDIF .ENDIF diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index 84695baf3557..ebe470d3eb7e 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -590,11 +590,7 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXA& rE aDFA.mnQuality += 500; } - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - // TODO: add alias names - return aDFA; } @@ -669,9 +665,6 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXW& rE aDFA.mnQuality += 500; } - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; - // TODO: add alias names return aDFA; } @@ -1998,8 +1991,6 @@ static bool ImplGetFontAttrFromFile( const String& rFontFileURL, rDFA.mePitch = PITCH_DONTKNOW;; rDFA.mbSubsettable= true; rDFA.mbEmbeddable = false; - rDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - rDFA.meAntiAlias = ANTIALIAS_DONTKNOW; // Create temporary file name char aFileName[] = "soAAT.fot"; @@ -2126,8 +2117,6 @@ bool WinSalGraphics::AddTempDevFont( ImplDevFontList* pFontList, aDFA.mePitch = PITCH_DONTKNOW;; aDFA.mbSubsettable= true; aDFA.mbEmbeddable = false; - aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW; - aDFA.meAntiAlias = ANTIALIAS_DONTKNOW; /* // TODO: improve ImplDevFontAttributes using the "font resource file" diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx index f95f42d6bf4d..1b7ed7dcfccb 100644 --- a/vcl/win/source/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -291,6 +291,10 @@ BOOL WinSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP if( nPart == PART_ENTIRE_CONTROL ) hTheme = getThemeHandle( mhWnd, L"Progress"); break; + case CTRL_SLIDER: + if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) + hTheme = getThemeHandle( mhWnd, L"Trackbar" ); + break; default: hTheme = NULL; break; @@ -890,6 +894,38 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, return ImplDrawTheme( hTheme, hDC, PP_CHUNK, iState, aProgressRect, aCaption ); } + if( nType == CTRL_SLIDER ) + { + iPart = (nPart == PART_TRACK_HORZ_AREA) ? TKP_TRACK : TKP_TRACKVERT; + iState = (nPart == PART_TRACK_HORZ_AREA) ? TRS_NORMAL : TRVS_NORMAL; + + Rectangle aTrackRect = ImplGetThemeRect( hTheme, hDC, iPart, iState, Rectangle() ); + RECT aTRect = rc; + if( nPart == PART_TRACK_HORZ_AREA ) + { + long nH = aTrackRect.GetHeight(); + aTRect.top += (rc.bottom - rc.top - nH)/2; + aTRect.bottom = aTRect.top + nH; + } + else + { + long nW = aTrackRect.GetWidth(); + aTRect.left += (rc.right - rc.left - nW)/2; + aTRect.right = aTRect.left + nW; + } + ImplDrawTheme( hTheme, hDC, iPart, iState, aTRect, aCaption ); + + RECT aThumbRect; + SliderValue* pVal = (SliderValue*)aValue.getOptionalVal(); + aThumbRect.left = pVal->maThumbRect.Left(); + aThumbRect.top = pVal->maThumbRect.Top(); + aThumbRect.right = pVal->maThumbRect.Right(); + aThumbRect.bottom = pVal->maThumbRect.Bottom(); + iPart = (nPart == PART_TRACK_HORZ_AREA) ? TKP_THUMB : TKP_THUMBVERT; + iState = (nState & CTRL_STATE_ENABLED) ? TUS_NORMAL : TUS_DISABLED; + return ImplDrawTheme( hTheme, hDC, iPart, iState, aThumbRect, aCaption ); + } + return false; } @@ -970,6 +1006,10 @@ BOOL WinSalGraphics::drawNativeControl( ControlType nType, if( nPart == PART_ENTIRE_CONTROL ) hTheme = getThemeHandle( mhWnd, L"Progress"); break; + case CTRL_SLIDER: + if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) + hTheme = getThemeHandle( mhWnd, L"Trackbar" ); + break; default: hTheme = NULL; break; @@ -1106,7 +1146,6 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, bRet = TRUE; } } - if( (nType == CTRL_LISTBOX || nType == CTRL_COMBOBOX ) && nPart == PART_ENTIRE_CONTROL ) { HTHEME hTheme = getThemeHandle( mhWnd, L"Combobox"); @@ -1162,6 +1201,33 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, } } } + if( nType == CTRL_SLIDER && ( (nPart == PART_THUMB_HORZ) || (nPart == PART_THUMB_VERT) ) ) + { + HTHEME hTheme = getThemeHandle( mhWnd, L"Trackbar"); + if( hTheme ) + { + int iPart = (nPart == PART_THUMB_HORZ) ? TKP_THUMB : TKP_THUMBVERT; + int iState = (nPart == PART_THUMB_HORZ) ? TUS_NORMAL : TUVS_NORMAL; + Rectangle aThumbRect = ImplGetThemeRect( hTheme, hDC, iPart, iState, Rectangle() ); + if( nPart == PART_THUMB_HORZ ) + { + long nW = aThumbRect.GetWidth(); + Rectangle aRect( rControlRegion.GetBoundRect() ); + aRect.Right() = aRect.Left() + nW - 1; + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + } + else + { + long nH = aThumbRect.GetHeight(); + Rectangle aRect( rControlRegion.GetBoundRect() ); + aRect.Bottom() = aRect.Top() + nH - 1; + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + } + bRet = TRUE; + } + } ReleaseDC( mhWnd, hDC ); return( bRet ); diff --git a/vcl/win/source/window/MAKEFILE.MK b/vcl/win/source/window/MAKEFILE.MK index e83f04cfdfb0..cecfbcf5b2e5 100644 --- a/vcl/win/source/window/MAKEFILE.MK +++ b/vcl/win/source/window/MAKEFILE.MK @@ -38,12 +38,7 @@ ENABLE_EXCEPTIONS=TRUE .INCLUDE : $(PRJ)$/util$/makefile2.pmk # --- #105371# -.IF "$(COM)"=="GCC" -CFLAGS += -D_WIN32_WINNT=0x0501 -.ELSE -CFLAGS += -DWINVER=0x0400 -D_WIN32_WINNT=0x0501 - -.ENDIF +CDEFS +=-U_WIN32_WINNT -D_WIN32_WINNT=0x0501 # --- Files -------------------------------------------------------- |