diff options
author | Vladimir Glazunov <vg@openoffice.org> | 2010-03-22 18:17:46 +0100 |
---|---|---|
committer | Vladimir Glazunov <vg@openoffice.org> | 2010-03-22 18:17:46 +0100 |
commit | 51b401061b70d699c34f30a21cf6a9fde80dfd75 (patch) | |
tree | 918c15296391b82ecf0b277101b49b9f20476f12 /vcl | |
parent | bbdd8d299409a81f14aa6432c9d8842fa6bc8dc6 (diff) | |
parent | b9bf85ffe5c1b22bb096cb63fc7059ebe590134e (diff) |
CWS-TOOLING: integrate CWS vcl109
Diffstat (limited to 'vcl')
41 files changed, 1833 insertions, 903 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/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/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/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/outdev.hxx b/vcl/inc/vcl/outdev.hxx index be5c0a880ed7..70c1e6aa624d 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -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/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/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/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/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/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/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/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 6ca90540d8ee..963b7a3daa30 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -5908,15 +5908,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/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/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/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/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/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 869189fb1415..17e42f412d61 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -99,6 +99,8 @@ struct NWFWidgetData GtkWidget * gTooltipPopup; GtkWidget * gProgressBar; GtkWidget * gTreeView; + GtkWidget * gHScale; + GtkWidget * gVScale; NWPixmapCacheList* gNWPixmapCacheList; NWPixmapCache* gCacheTabItems; @@ -131,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 ) @@ -172,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 ); @@ -589,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 ); @@ -875,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 ) { @@ -1103,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 ); } @@ -3012,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, @@ -3962,3 +4127,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/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/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/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/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/xrender_peer.cxx b/vcl/unx/source/gdi/xrender_peer.cxx index c5d84cffab58..6e15f5a00eb7 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 diff --git a/vcl/unx/source/gdi/xrender_peer.hxx b/vcl/unx/source/gdi/xrender_peer.hxx index 6d40015ee94d..f82f9b58e8c3 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> @@ -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/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 ); |