[Libreoffice-commits] .: Branch 'distro/suse/suse-3.6' - 8 commits - oox/inc oox/source svtools/inc svtools/source vcl/inc vcl/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Fri Oct 12 10:18:36 PDT 2012
oox/inc/oox/drawingml/textparagraphproperties.hxx | 2
oox/source/drawingml/textparagraphproperties.cxx | 7
svtools/inc/svtools/grfmgr.hxx | 4
svtools/source/filter/wmf/enhwmf.cxx | 4
svtools/source/filter/wmf/winwmf.cxx | 2
svtools/source/graphic/grfcache.cxx | 312 +++++++++++++++++++++-
svtools/source/graphic/grfmgr2.cxx | 262 +++++++++---------
vcl/inc/vcl/bitmap.hxx | 105 ++++++-
vcl/source/gdi/bitmap3.cxx | 232 +++++-----------
9 files changed, 615 insertions(+), 315 deletions(-)
New commits:
commit 898e6f94e595a53f6b6fcc22e8702a7357f76a32
Author: Muthu Subramanian <sumuthu at suse.com>
Date: Tue Aug 14 17:41:59 2012 +0530
n#759180: Push oox default spacing values.
Conflicts:
oox/source/drawingml/textparagraph.cxx
Change-Id: Ibb5027b3b74fb1c264fbc6b1efae9e8cd1a3b00e
diff --git a/oox/inc/oox/drawingml/textparagraphproperties.hxx b/oox/inc/oox/drawingml/textparagraphproperties.hxx
index 9e9fe88..622203d 100644
--- a/oox/inc/oox/drawingml/textparagraphproperties.hxx
+++ b/oox/inc/oox/drawingml/textparagraphproperties.hxx
@@ -106,7 +106,7 @@ public:
void apply( const TextParagraphProperties& rSourceProps );
void pushToPropSet( const ::oox::core::XmlFilterBase* pFilterBase,
const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > & xPropSet,
- PropertyMap& rioBulletList, const BulletList* pMasterBuList, sal_Bool bApplyBulletList, float fFontSize ) const;
+ PropertyMap& rioBulletList, const BulletList* pMasterBuList, sal_Bool bApplyBulletList, float fFontSize, bool bPushDefaultValues = false ) const;
void pushToPropSet( const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > & xPropSet) const;
/** Returns the largest character size of this paragraph. If possible the
diff --git a/oox/source/drawingml/textparagraphproperties.cxx b/oox/source/drawingml/textparagraphproperties.cxx
index 0ca8641..e3977af 100644
--- a/oox/source/drawingml/textparagraphproperties.cxx
+++ b/oox/source/drawingml/textparagraphproperties.cxx
@@ -391,7 +391,8 @@ void TextParagraphProperties::apply( const TextParagraphProperties& rSourceProps
}
void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase* pFilterBase,
- const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, const BulletList* pMasterBuList, sal_Bool bApplyBulletMap, float fCharacterSize ) const
+ const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, const BulletList* pMasterBuList, sal_Bool bApplyBulletMap, float fCharacterSize,
+ bool bPushDefaultValues ) const
{
PropertySet aPropSet( xPropSet );
aPropSet.setProperties( maTextParagraphPropertyMap );
@@ -406,9 +407,9 @@ void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase* p
maBulletList.pushToPropMap( pFilterBase, rioBulletMap );
- if ( maParaTopMargin.bHasValue )
+ if ( maParaTopMargin.bHasValue || bPushDefaultValues )
aPropSet.setProperty( PROP_ParaTopMargin, maParaTopMargin.toMargin( fCharacterSize != 0.0 ? fCharacterSize : getCharHeightPoints ( 18.0 ) ) );
- if ( maParaBottomMargin.bHasValue )
+ if ( maParaBottomMargin.bHasValue || bPushDefaultValues )
aPropSet.setProperty( PROP_ParaBottomMargin, maParaBottomMargin.toMargin( fCharacterSize != 0.0 ? fCharacterSize : getCharHeightPoints ( 18.0 ) ) );
if ( nNumberingType == NumberingType::BITMAP )
{
commit 73e73ca997fa921d76752b36e62bb5795b77d676
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Jun 22 15:50:30 2012 +0200
try somewhat harder to smoothscale objects (bnc#765998)
The used bilinear algorithm is apparently of a rather low quality,
use the new generic box algorithm instead. That makes it somewhat
slower, but the result is cached, and hopefully the speed difference
is not that significant.
Change-Id: I5a4dbe4851d467babc0d0fdcc3375b35441daf93
diff --git a/svtools/inc/svtools/grfmgr.hxx b/svtools/inc/svtools/grfmgr.hxx
index edb3db1..438efcd 100644
--- a/svtools/inc/svtools/grfmgr.hxx
+++ b/svtools/inc/svtools/grfmgr.hxx
@@ -38,11 +38,11 @@
#define GRFMGR_DRAW_NOTCACHED 0x00000000UL
#define GRFMGR_DRAW_CACHED 0x00000001UL
-#define GRFMGR_DRAW_BILINEAR 0x00000002UL
+#define GRFMGR_DRAW_SMOOTHSCALE 0x00000002UL
#define GRFMGR_DRAW_USE_DRAWMODE_SETTINGS 0x00000004UL
#define GRFMGR_DRAW_SUBSTITUTE 0x00000008UL
#define GRFMGR_DRAW_NO_SUBSTITUTE 0x00000010UL
-#define GRFMGR_DRAW_STANDARD (GRFMGR_DRAW_CACHED|GRFMGR_DRAW_BILINEAR)
+#define GRFMGR_DRAW_STANDARD (GRFMGR_DRAW_CACHED|GRFMGR_DRAW_SMOOTHSCALE)
// --------------------
// - AutoSwap Defines -
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index 4e7da1b..6bf2bc5 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -344,34 +344,7 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
sal_Bool bHMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
sal_Bool bVMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
- if( nFlags & GRFMGR_DRAW_BILINEAR )
- {
- const double fRevScaleX = ( nNewW > 1L ) ? ( (double) ( nW - 1L ) / ( nNewW - 1L ) ) : 0.0;
- const double fRevScaleY = ( nNewH > 1L ) ? ( (double) ( nH - 1L ) / ( nNewH - 1L ) ) : 0.0;
-
- // create horizontal mapping table
- for( nX = 0L, nTmpX = nW - 1L, nTmp = nW - 2L; nX < nNewW; nX++ )
- {
- fTmp = nX * fRevScaleX;
-
- if( bHMirr )
- fTmp = nTmpX - fTmp;
-
- pMapFX[ nX ] = (long) ( ( fTmp - ( pMapIX[ nX ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
- }
-
- // create vertical mapping table
- for( nY = 0L, nTmpY = nH - 1L, nTmp = nH - 2L; nY < nNewH; nY++ )
- {
- fTmp = nY * fRevScaleY;
-
- if( bVMirr )
- fTmp = nTmpY - fTmp;
-
- pMapFY[ nY ] = (long) ( ( fTmp - ( pMapIY[ nY ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
- }
- }
- else
+ if( !( nFlags & GRFMGR_DRAW_SMOOTHSCALE ))
{
// #98290# Use a different mapping for non-interpolating mode, to avoid missing rows/columns
const double fRevScaleX = ( nNewW > 1L ) ? ( (double) nW / nNewW ) : 0.0;
@@ -453,7 +426,22 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
bRet = ( aOutBmpEx = aBmpEx ).Scale( aUnrotatedSzPix );
if( bRet )
- aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
+ bRet = aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
+ }
+ else if( nFlags & GRFMGR_DRAW_SMOOTHSCALE )
+ {
+ // Scale using the Box filter, rather than this algorithm, as that one provides
+ // better quality, while being somewhat slower (the result should be cached though).
+ aOutBmpEx = aBmpEx;
+ bRet = true;
+ if( bHMirr || bVMirr )
+ bRet = aOutBmpEx.Mirror(( bHMirr ? BMP_MIRROR_HORZ : BMP_MIRROR_NONE )
+ | ( bVMirr ? BMP_MIRROR_VERT : BMP_MIRROR_NONE ));
+ if( bRet )
+ bRet = aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
+ if( bRet ) // scale as last (rotating would destroy the smooth scaling)
+ bRet = aOutBmpEx.Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ),
+ BMP_SCALE_BOX );
}
else
{
@@ -479,6 +467,17 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
{
if( bSimple )
bRet = ( aOutBmpEx = aBmpEx ).Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ) );
+ else if( nFlags & GRFMGR_DRAW_SMOOTHSCALE )
+ {
+ // Scale using the Box filter, rather than this algorithm, as that one provides
+ // better quality, while being somewhat slower (the result should be cached though).
+ aOutBmpEx = aBmpEx;
+ bRet = aOutBmpEx.Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ),
+ BMP_SCALE_BOX );
+ if( bRet && ( bHMirr || bVMirr ))
+ bRet = aOutBmpEx.Mirror(( bHMirr ? BMP_MIRROR_HORZ : BMP_MIRROR_NONE )
+ | ( bVMirr ? BMP_MIRROR_VERT : BMP_MIRROR_NONE ));
+ }
else
{
bRet = ImplCreateScaled( aBmpEx,
commit 744213cca0377417ca7dabed238d184ffecbfc11
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Jun 22 13:57:39 2012 +0200
make it possible to cache the resulting pixmap with a metafile
If the metafile contains just one single bitmap, the drawing code
optimizes by just using that one bitmap. It (=the resulting pixmap
after scaling etc.) however has not been cached so far, which means
smoothscaling (to be done) would be quite slow with every paint.
Conflicts:
svtools/source/graphic/grfmgr2.cxx
Change-Id: I30950c55fbadfddedc7df31283c66ed064b1a1a6
diff --git a/svtools/source/graphic/grfcache.cxx b/svtools/source/graphic/grfcache.cxx
index bfd9341..bfb39e4 100644
--- a/svtools/source/graphic/grfcache.cxx
+++ b/svtools/source/graphic/grfcache.cxx
@@ -29,6 +29,7 @@
#include <salhelper/timer.hxx>
#include <tools/debug.hxx>
+#include <vcl/metaact.hxx>
#include <vcl/outdev.hxx>
#include <tools/poly.hxx>
#include <rtl/strbuf.hxx>
@@ -419,6 +420,8 @@ private:
sal_uLong mnOutDevDrawMode;
sal_uInt16 mnOutDevBitCount;
+ static bool IsCacheableAsBitmap( const GDIMetaFile& rMtf, OutputDevice* pOut, const Size& rSz );
+
public:
static sal_uLong GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz,
@@ -486,14 +489,305 @@ public:
// -----------------------------------------------------------------------------
+// This whole function is based on checkMetadataBitmap() from grfmgr2.cxx, see that one for details.
+// If you do changes here, change the original function too.
+static void checkMetadataBitmap( const BitmapEx& rBmpEx,
+ Point /*rSrcPoint*/,
+ Size rSrcSize,
+ const Point& rDestPoint,
+ const Size& rDestSize,
+ const Size& rRefSize,
+ bool& o_rbNonBitmapActionEncountered )
+{
+ if( rSrcSize == Size())
+ rSrcSize = rBmpEx.GetSizePixel();
+
+ if( rDestPoint != Point( 0, 0 ))
+ {
+ o_rbNonBitmapActionEncountered = true;
+ return;
+ }
+ if( rDestSize != rRefSize )
+ { if( rBmpEx.GetSizePixel().Width() > 100 && rBmpEx.GetSizePixel().Height() > 100
+ && abs( rDestSize.Width() - rRefSize.Width()) < 5
+ && abs( rDestSize.Height() - rRefSize.Height()) < 5 )
+ ; // ok, assume it's close enough
+ else
+ { // fall back to mtf rendering
+ o_rbNonBitmapActionEncountered = true;
+ return;
+ }
+ }
+}
+
+// This function is based on GraphicManager::ImplCreateOutput(), in fact it mostly copies
+// it, the difference is that this one does not create anything, it only checks if
+// ImplCreateOutput() would use the optimization of using the single bitmap.
+// If you do changes here, change the original function too.
+bool GraphicDisplayCacheEntry::IsCacheableAsBitmap( const GDIMetaFile& rMtf,
+ OutputDevice* pOut, const Size& rSz )
+{
+ const Size aNewSize( rMtf.GetPrefSize() );
+ GDIMetaFile rOutMtf = rMtf;
+
+ // Count bitmap actions, and flag actions that paint, but
+ // are no bitmaps.
+ sal_Int32 nNumBitmaps(0);
+ bool bNonBitmapActionEncountered(false);
+ if( aNewSize.Width() && aNewSize.Height() && rSz.Width() && rSz.Height() )
+ {
+ const MapMode rPrefMapMode( rMtf.GetPrefMapMode() );
+ const Size rSizePix( pOut->LogicToPixel( aNewSize, rPrefMapMode ) );
+
+ sal_uInt32 nCurPos;
+ MetaAction* pAct;
+ for( nCurPos = 0, pAct = (MetaAction*)rOutMtf.FirstAction(); pAct;
+ pAct = (MetaAction*)rOutMtf.NextAction(), nCurPos++ )
+ {
+ switch( pAct->GetType() )
+ {
+ case META_FONT_ACTION:
+ // FALLTHROUGH intended
+ case META_NULL_ACTION:
+ // FALLTHROUGH intended
+
+ // OutDev state changes (which don't affect bitmap
+ // output)
+ case META_LINECOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_FILLCOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTCOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTFILLCOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTALIGN_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTLINECOLOR_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTLINE_ACTION:
+ // FALLTHROUGH intended
+ case META_PUSH_ACTION:
+ // FALLTHROUGH intended
+ case META_POP_ACTION:
+ // FALLTHROUGH intended
+ case META_LAYOUTMODE_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTLANGUAGE_ACTION:
+ // FALLTHROUGH intended
+ case META_COMMENT_ACTION:
+ break;
+
+ // bitmap output methods
+ case META_BMP_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpAction* pAction = (MetaBmpAction*)pAct;
+
+ checkMetadataBitmap(
+ BitmapEx( pAction->GetBitmap()),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pAction->GetBitmap().GetSizePixel(),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ }
+ ++nNumBitmaps;
+ break;
+
+ case META_BMPSCALE_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpScaleAction* pAction = (MetaBmpScaleAction*)pAct;
+
+ checkMetadataBitmap(
+ BitmapEx( pAction->GetBitmap()),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ }
+ ++nNumBitmaps;
+ break;
+
+ case META_BMPSCALEPART_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpScalePartAction* pAction = (MetaBmpScalePartAction*)pAct;
+
+ checkMetadataBitmap( BitmapEx( pAction->GetBitmap() ),
+ pAction->GetSrcPoint(),
+ pAction->GetSrcSize(),
+ pOut->LogicToPixel( pAction->GetDestPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetDestSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ }
+ ++nNumBitmaps;
+ break;
+
+ case META_BMPEX_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpExAction* pAction = (MetaBmpExAction*)pAct;
+
+ checkMetadataBitmap(
+ pAction->GetBitmapEx(),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pAction->GetBitmapEx().GetSizePixel(),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ }
+ ++nNumBitmaps;
+ break;
+
+ case META_BMPEXSCALE_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpExScaleAction* pAction = (MetaBmpExScaleAction*)pAct;
+
+ checkMetadataBitmap(
+ pAction->GetBitmapEx(),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ }
+ ++nNumBitmaps;
+ break;
+
+ case META_BMPEXSCALEPART_ACTION:
+ if( !nNumBitmaps && !bNonBitmapActionEncountered )
+ {
+ MetaBmpExScalePartAction* pAction = (MetaBmpExScalePartAction*)pAct;
+
+ checkMetadataBitmap( pAction->GetBitmapEx(),
+ pAction->GetSrcPoint(),
+ pAction->GetSrcSize(),
+ pOut->LogicToPixel( pAction->GetDestPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetDestSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
+ }
+ ++nNumBitmaps;
+ break;
+
+ // these actions actually output something (that's
+ // different from a bitmap)
+ case META_RASTEROP_ACTION:
+ if( ((MetaRasterOpAction*)pAct)->GetRasterOp() == ROP_OVERPAINT )
+ break;
+ // FALLTHROUGH intended
+ case META_PIXEL_ACTION:
+ // FALLTHROUGH intended
+ case META_POINT_ACTION:
+ // FALLTHROUGH intended
+ case META_LINE_ACTION:
+ // FALLTHROUGH intended
+ case META_RECT_ACTION:
+ // FALLTHROUGH intended
+ case META_ROUNDRECT_ACTION:
+ // FALLTHROUGH intended
+ case META_ELLIPSE_ACTION:
+ // FALLTHROUGH intended
+ case META_ARC_ACTION:
+ // FALLTHROUGH intended
+ case META_PIE_ACTION:
+ // FALLTHROUGH intended
+ case META_CHORD_ACTION:
+ // FALLTHROUGH intended
+ case META_POLYLINE_ACTION:
+ // FALLTHROUGH intended
+ case META_POLYGON_ACTION:
+ // FALLTHROUGH intended
+ case META_POLYPOLYGON_ACTION:
+ // FALLTHROUGH intended
+
+ case META_TEXT_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTARRAY_ACTION:
+ // FALLTHROUGH intended
+ case META_STRETCHTEXT_ACTION:
+ // FALLTHROUGH intended
+ case META_TEXTRECT_ACTION:
+ // FALLTHROUGH intended
+
+ case META_MASK_ACTION:
+ // FALLTHROUGH intended
+ case META_MASKSCALE_ACTION:
+ // FALLTHROUGH intended
+ case META_MASKSCALEPART_ACTION:
+ // FALLTHROUGH intended
+
+ case META_GRADIENT_ACTION:
+ // FALLTHROUGH intended
+ case META_HATCH_ACTION:
+ // FALLTHROUGH intended
+ case META_WALLPAPER_ACTION:
+ // FALLTHROUGH intended
+
+ case META_TRANSPARENT_ACTION:
+ // FALLTHROUGH intended
+ case META_EPS_ACTION:
+ // FALLTHROUGH intended
+ case META_FLOATTRANSPARENT_ACTION:
+ // FALLTHROUGH intended
+ case META_GRADIENTEX_ACTION:
+ // FALLTHROUGH intended
+ case META_RENDERGRAPHIC_ACTION:
+ // FALLTHROUGH intended
+
+ // OutDev state changes that _do_ affect bitmap
+ // output
+ case META_CLIPREGION_ACTION:
+ // FALLTHROUGH intended
+ case META_ISECTRECTCLIPREGION_ACTION:
+ // FALLTHROUGH intended
+ case META_ISECTREGIONCLIPREGION_ACTION:
+ // FALLTHROUGH intended
+ case META_MOVECLIPREGION_ACTION:
+ // FALLTHROUGH intended
+
+ case META_MAPMODE_ACTION:
+ // FALLTHROUGH intended
+ case META_REFPOINT_ACTION:
+ // FALLTHROUGH intended
+ default:
+ bNonBitmapActionEncountered = true;
+ break;
+ }
+ }
+ }
+ return nNumBitmaps == 1 && !bNonBitmapActionEncountered;
+}
+
sal_uLong GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Point& /*rPt*/, const Size& rSz,
const GraphicObject& rObj, const GraphicAttr& rAttr )
{
const Graphic& rGraphic = rObj.GetGraphic();
const GraphicType eType = rGraphic.GetType();
- sal_uLong nNeededSize;
+ bool canCacheAsBitmap = false;
if( GRAPHIC_BITMAP == eType )
+ canCacheAsBitmap = true;
+ else if( GRAPHIC_GDIMETAFILE == eType )
+ canCacheAsBitmap = IsCacheableAsBitmap( rGraphic.GetGDIMetaFile(), pOut, rSz );
+ else
+ return 0;
+ if( canCacheAsBitmap )
{
const Size aOutSizePix( pOut->LogicToPixel( rSz ) );
const long nBitCount = pOut->GetBitCount();
@@ -501,27 +795,23 @@ sal_uLong GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Poi
if( ( aOutSizePix.Width() > MAX_BMP_EXTENT ) ||
( aOutSizePix.Height() > MAX_BMP_EXTENT ) )
{
- nNeededSize = ULONG_MAX;
+ return ULONG_MAX;
}
else if( nBitCount )
{
- nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8;
-
+ sal_uLong nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8;
if( rObj.IsTransparent() || ( rAttr.GetRotation() % 3600 ) )
nNeededSize += nNeededSize / nBitCount;
+ return nNeededSize;
}
else
{
- OSL_FAIL( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" );
- nNeededSize = 256000;
+ OSL_FAIL( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" );
+ return 256000;
}
}
- else if( GRAPHIC_GDIMETAFILE == eType )
- nNeededSize = rGraphic.GetSizeBytes();
else
- nNeededSize = 0;
-
- return nNeededSize;
+ return rGraphic.GetSizeBytes();
}
// -----------------------------------------------------------------------------
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index b792f3f..4e7da1b 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -538,6 +538,7 @@ static BitmapEx checkMetadataBitmap( const BitmapEx& rBmpEx,
const Size& rRefSize,
bool& o_rbNonBitmapActionEncountered )
{
+// NOTE: If you do changes in this function, change checkMetadataBitmap() in grfcache.cxx too.
BitmapEx aBmpEx;
if( rSrcSize == Size())
rSrcSize = rBmpEx.GetSizePixel();
@@ -612,9 +613,12 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
const Size& rSizePix( pOut->LogicToPixel( aNewSize,
rPrefMapMode ) );
- // taking care of font width default if scaling metafile.
- // #117889# use existing metafile scan, to determine whether
- // the metafile basically displays a single bitmap. Note that
+// NOTE: If you do changes in this function, check GraphicDisplayCacheEntry::IsCacheableAsBitmap
+// in grfcache.cxx too.
+
+ // Determine whether the metafile basically displays
+ // a single bitmap (in which case that bitmap is simply used directly
+ // instead of playing the metafile). Note that
// the solution, as implemented here, is quite suboptimal (the
// cases where a mtf consisting basically of a single bitmap,
// that fail to pass the test below, are probably frequent). A
commit 3fbf2af7211a77ac0d4fbe49403cec416caa1db6
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Jun 22 11:50:38 2012 +0200
fix counting of bitmaps in a metafile
if( !number ) { ... ++number; } would never get beyond 1.
Change-Id: Iac33df3a21280c76fcdd130b699b4ab6466b1f46
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index 1c2ea1a..b792f3f 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -685,8 +685,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
pAction->GetBitmap().GetSizePixel(),
rSizePix,
bNonBitmapActionEncountered );
- ++nNumBitmaps;
}
+ ++nNumBitmaps;
break;
case META_BMPSCALE_ACTION:
@@ -703,8 +703,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
rPrefMapMode ),
rSizePix,
bNonBitmapActionEncountered );
- ++nNumBitmaps;
}
+ ++nNumBitmaps;
break;
case META_BMPSCALEPART_ACTION:
@@ -722,8 +722,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
rPrefMapMode ),
rSizePix,
bNonBitmapActionEncountered );
- ++nNumBitmaps;
}
+ ++nNumBitmaps;
break;
case META_BMPEX_ACTION:
@@ -739,8 +739,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
pAction->GetBitmapEx().GetSizePixel(),
rSizePix,
bNonBitmapActionEncountered );
- ++nNumBitmaps;
}
+ ++nNumBitmaps;
break;
case META_BMPEXSCALE_ACTION:
@@ -757,8 +757,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
rPrefMapMode ),
rSizePix,
bNonBitmapActionEncountered );
- ++nNumBitmaps;
}
+ ++nNumBitmaps;
break;
case META_BMPEXSCALEPART_ACTION:
@@ -775,8 +775,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
rPrefMapMode ),
rSizePix,
bNonBitmapActionEncountered );
- ++nNumBitmaps;
}
+ ++nNumBitmaps;
break;
// these actions actually output something (that's
commit c7610f13df9a5f944a2fceb94a7079d3f42fe381
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Jun 20 20:00:55 2012 +0200
fix off-by-one when reading WMF/EMF
According to docs http://msdn.microsoft.com/en-us/library/dd162589(v=vs.85),
cxDest/cyDest are "Logical width/height of the destination rectangle.",
so there should be no +1 as there would be if they were the top-bottom corner.
Change-Id: Iefa6db8e6131abe785b7878d97df1c891b73011c
diff --git a/svtools/source/filter/wmf/enhwmf.cxx b/svtools/source/filter/wmf/enhwmf.cxx
index b81d973..cce3dca 100644
--- a/svtools/source/filter/wmf/enhwmf.cxx
+++ b/svtools/source/filter/wmf/enhwmf.cxx
@@ -950,7 +950,7 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
cxSrc = cySrc = 0;
Bitmap aBitmap;
- Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
+ Rectangle aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative
cyDest = abs( (int)cyDest ); // and also 122889
@@ -1019,7 +1019,7 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
>> cyDest;
Bitmap aBitmap;
- Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
+ Rectangle aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative
cyDest = abs( (int)cyDest ); // and also 122889
commit dbe3b6afaddeb137632b8f6dda01c68835bb2c72
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Jun 20 19:34:36 2012 +0200
fix off-by-one in WMF/EMF reading
It's rather lame that Rectangle from tools primarily specifies
the rectangle as topleft/bottomright, rather than topleft/size,
as that easily leads to confusion such as here.
Change-Id: Ice86fae90d9159b98e0896b6c875b99c3e1a3686
diff --git a/svtools/source/filter/wmf/winwmf.cxx b/svtools/source/filter/wmf/winwmf.cxx
index a568e3f..5b3d085 100644
--- a/svtools/source/filter/wmf/winwmf.cxx
+++ b/svtools/source/filter/wmf/winwmf.cxx
@@ -1229,7 +1229,7 @@ void WMFReader::ReadWMF()
if( bEMFAvailable )
{
pOut->AddFromGDIMetaFile( aMeta );
- pOut->SetrclFrame( Rectangle(0, 0, aMeta.GetPrefSize().Width(), aMeta.GetPrefSize().Height() ));
+ pOut->SetrclFrame( Rectangle( Point(0, 0), aMeta.GetPrefSize()));
// the stream needs to be set to the wmf end position,
// otherwise the GfxLink that is created will be incorrect
commit b4a3a18e0df04d0ddd7735fb718593132bf401c4
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Wed Jun 20 21:29:52 2012 +0200
be somewhat lenient when doing the one-bitmap WMF optimization
The document from bnc#765998 contains a rather huge WMF with poor
quality. It could be smoothscaled to get a much better result,
but doing that would be too slow with an image of this size,
and it would be done every single time the image would need to be
painted, because the resulting image would not be cached.
One reason for this is that the WMF appears to be kinda broken (or let's
say imprecise [which is no wonder after trying to read things like
http://msdn.microsoft.com/en-us/library/dd162607(v=vs.85).aspx
and trying to understand what exactly rlcFrames is supposed to be]).
Change-Id: I017db36ec96f5405ff5965943003d5aa93018a37
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index 1967e44..1c2ea1a 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -48,64 +48,6 @@
#define WATERMARK_LUM_OFFSET 50
#define WATERMARK_CON_OFFSET -70
-// -----------
-// - helpers -
-// -----------
-
-namespace {
-
-void muckWithBitmap( const Point& rDestPoint,
- const Size& rDestSize,
- const Size& rRefSize,
- bool& o_rbNonBitmapActionEncountered )
-{
- const Point aEmptyPoint;
-
- if( aEmptyPoint != rDestPoint ||
- rDestSize != rRefSize )
- {
- // non-fullscale, or offsetted bmp -> fallback to mtf
- // rendering
- o_rbNonBitmapActionEncountered = true;
- }
-}
-
-BitmapEx muckWithBitmap( const BitmapEx& rBmpEx,
- const Point& rSrcPoint,
- const Size& rSrcSize,
- const Point& rDestPoint,
- const Size& rDestSize,
- const Size& rRefSize,
- bool& o_rbNonBitmapActionEncountered )
-{
- BitmapEx aBmpEx;
-
- muckWithBitmap(rDestPoint,
- rDestSize,
- rRefSize,
- o_rbNonBitmapActionEncountered);
-
- if( o_rbNonBitmapActionEncountered )
- return aBmpEx;
-
- aBmpEx = rBmpEx;
-
- if( (rSrcPoint.X() != 0 && rSrcPoint.Y() != 0) ||
- rSrcSize != rBmpEx.GetSizePixel() )
- {
- // crop bitmap to given source rectangle (no
- // need to copy and convert the whole bitmap)
- const Rectangle aCropRect( rSrcPoint,
- rSrcSize );
- aBmpEx.Crop( aCropRect );
- }
-
- return aBmpEx;
-}
-
-} // namespace {
-
-
// ------------------
// - GraphicManager -
// ------------------
@@ -585,6 +527,66 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
// -----------------------------------------------------------------------------
+// This function checks whether the bitmap is usable for skipping
+// mtf rendering by using just this one bitmap (i.e. in case the metafile
+// contains just this one pixmap that covers the entire metafile area).
+static BitmapEx checkMetadataBitmap( const BitmapEx& rBmpEx,
+ Point rSrcPoint,
+ Size rSrcSize,
+ const Point& rDestPoint,
+ const Size& rDestSize,
+ const Size& rRefSize,
+ bool& o_rbNonBitmapActionEncountered )
+{
+ BitmapEx aBmpEx;
+ if( rSrcSize == Size())
+ rSrcSize = rBmpEx.GetSizePixel();
+
+ if( rDestPoint != Point( 0, 0 ))
+ { // The pixmap in the metafile has an offset (and so would not cover)
+ // the entire result -> fall back to mtf rendering.
+ o_rbNonBitmapActionEncountered = true;
+ return aBmpEx;
+ }
+ if( rDestSize != rRefSize )
+ { // The pixmap is not fullscale (does not cover the entire metafile area).
+ // HACK: The code here should refuse to use the bitmap directly
+ // and fall back to mtf rendering, but there seem to be metafiles
+ // that do not specify exactly their area (the Windows API requires apps
+ // the specify it manually, the rectangle is specified as topleft/bottomright
+ // rather than topleft/size [which may be confusing], and the docs
+ // on the exact meaning are somewhat confusing as well), so if it turns
+ // out this metafile really contains just one bitmap and no other painting,
+ // and if the sizes almost match, just use the pixmap (which will be scaled
+ // to fit exactly the requested size, so there should not be any actual problem
+ // caused by this small difference). This will allow caching of the resulting
+ // (scaled) pixmap, which can make a noticeable performance difference.
+ if( rBmpEx.GetSizePixel().Width() > 100 && rBmpEx.GetSizePixel().Height() > 100
+ && abs( rDestSize.Width() - rRefSize.Width()) < 5
+ && abs( rDestSize.Height() - rRefSize.Height()) < 5 )
+ ; // ok, assume it's close enough
+ else
+ { // fall back to mtf rendering
+ o_rbNonBitmapActionEncountered = true;
+ return aBmpEx;
+ }
+ }
+
+ aBmpEx = rBmpEx;
+
+ if( (rSrcPoint.X() != 0 && rSrcPoint.Y() != 0) ||
+ rSrcSize != rBmpEx.GetSizePixel() )
+ {
+ // crop bitmap to given source rectangle (no
+ // need to copy and convert the whole bitmap)
+ const Rectangle aCropRect( rSrcPoint,
+ rSrcSize );
+ aBmpEx.Crop( aCropRect );
+ }
+
+ return aBmpEx;
+}
+
sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
const Point& rPt, const Size& rSz,
const GDIMetaFile& rMtf, const GraphicAttr& rAttr,
@@ -675,12 +677,14 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
{
MetaBmpAction* pAction = (MetaBmpAction*)pAct;
- rOutBmpEx = BitmapEx( pAction->GetBitmap() );
- muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pAction->GetBitmap().GetSizePixel(),
- rSizePix,
- bNonBitmapActionEncountered );
+ rOutBmpEx = checkMetadataBitmap(
+ BitmapEx( pAction->GetBitmap()),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pAction->GetBitmap().GetSizePixel(),
+ rSizePix,
+ bNonBitmapActionEncountered );
++nNumBitmaps;
}
break;
@@ -690,13 +694,15 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
{
MetaBmpScaleAction* pAction = (MetaBmpScaleAction*)pAct;
- rOutBmpEx = BitmapEx( pAction->GetBitmap() );
- muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
+ rOutBmpEx = checkMetadataBitmap(
+ BitmapEx( pAction->GetBitmap()),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
++nNumBitmaps;
}
break;
@@ -706,7 +712,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
{
MetaBmpScalePartAction* pAction = (MetaBmpScalePartAction*)pAct;
- rOutBmpEx = muckWithBitmap( BitmapEx( pAction->GetBitmap() ),
+ rOutBmpEx = checkMetadataBitmap(
+ BitmapEx( pAction->GetBitmap() ),
pAction->GetSrcPoint(),
pAction->GetSrcSize(),
pOut->LogicToPixel( pAction->GetDestPoint(),
@@ -724,12 +731,14 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
{
MetaBmpExAction* pAction = (MetaBmpExAction*)pAct;
- rOutBmpEx = pAction->GetBitmapEx();
- muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pAction->GetBitmapEx().GetSizePixel(),
- rSizePix,
- bNonBitmapActionEncountered );
+ rOutBmpEx = checkMetadataBitmap(
+ pAction->GetBitmapEx(),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pAction->GetBitmapEx().GetSizePixel(),
+ rSizePix,
+ bNonBitmapActionEncountered );
++nNumBitmaps;
}
break;
@@ -739,13 +748,15 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
{
MetaBmpExScaleAction* pAction = (MetaBmpExScaleAction*)pAct;
- rOutBmpEx = pAction->GetBitmapEx();
- muckWithBitmap( pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
+ rOutBmpEx = checkMetadataBitmap(
+ pAction->GetBitmapEx(),
+ Point(), Size(),
+ pOut->LogicToPixel( pAction->GetPoint(),
+ rPrefMapMode ),
+ pOut->LogicToPixel( pAction->GetSize(),
+ rPrefMapMode ),
+ rSizePix,
+ bNonBitmapActionEncountered );
++nNumBitmaps;
}
break;
@@ -755,7 +766,7 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
{
MetaBmpExScalePartAction* pAction = (MetaBmpExScalePartAction*)pAct;
- rOutBmpEx = muckWithBitmap( pAction->GetBitmapEx(),
+ rOutBmpEx = checkMetadataBitmap( pAction->GetBitmapEx(),
pAction->GetSrcPoint(),
pAction->GetSrcSize(),
pOut->LogicToPixel( pAction->GetDestPoint(),
commit 622f7f9939aa7001bbf7b631bf5b4e23f8cf82e0
Author: Tomaž Vajngerl <quikee at gmail.com>
Date: Fri Jun 15 07:17:36 2012 +0200
Add new Scale modes, simplify convolution calculation.
Convolution calculation now uses 2x transposing horizontal pass
instead of horizontal and vertical which simplifies the code by
reducing code duplication.
Instead of more convolution methods, only one generic method is
used and kernels are now a parameter to the method. For this
Kernel class was introduced with responsibility to calculate
kernel walues and hold kernel specific information.
Besides Lanzcos resampling also Box, Bilinear and Bicubic resampling
was introduced. Box is the simplest and fastest but with still
good quality.
diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index f1183ac..efc37a0 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -50,6 +50,9 @@
#define BMP_SCALE_FAST 0x00000001UL
#define BMP_SCALE_INTERPOLATE 0x00000002UL
#define BMP_SCALE_LANCZOS 0x00000003UL
+#define BMP_SCALE_BICUBIC 0x00000004UL
+#define BMP_SCALE_BILINEAR 0x00000005UL
+#define BMP_SCALE_BOX 0x00000006UL
// Aliases, try to use these two (or BMP_SCALE_FAST/BMP_SCALE_NONE),
// use a specific algorithm only if you really need to.
@@ -163,7 +166,7 @@ class VCL_DLLPUBLIC BmpFilterParam
friend class Animation;
private:
- BmpFilter meFilter;
+ BmpFilter meFilter;
sal_uLong mnProgressStart;
sal_uLong mnProgressEnd;
@@ -218,6 +221,89 @@ public:
}
};
+// --------------------
+// Resample Kernels
+// --------------------
+
+class Kernel
+{
+
+public:
+ Kernel () {}
+ virtual ~Kernel() {}
+
+ virtual double GetWidth() = 0;
+ virtual double Calculate( double x ) = 0;
+};
+
+class Lanczos3Kernel : public Kernel
+{
+
+public:
+ virtual double GetWidth() { return 3.0; }
+ virtual double Calculate (double x)
+ {
+ return (-3.0 <= x && x < 3.0) ? SincFilter(x) * SincFilter( x / 3.0 ) : 0.0;
+ }
+
+ inline double SincFilter(double x)
+ {
+ if (x == 0.0)
+ {
+ return 1.0;
+ }
+ x = x * M_PI;
+ return sin(x) / x;
+ }
+};
+
+class BicubicKernel : public Kernel {
+ virtual double GetWidth() { return 2.0; }
+ virtual double Calculate (double x)
+ {
+ if (x < 0.0)
+ {
+ x = -x;
+ }
+
+ if (x <= 1.0)
+ {
+ return (1.5 * x - 2.5) * x * x + 1.0;
+ }
+ else if (x < 2.0)
+ {
+ return ((-0.5 * x + 2.5) * x - 4) * x + 2;
+ }
+ return 0.0;
+ }
+};
+
+class BilinearKernel : public Kernel {
+ virtual double GetWidth() { return 1.0; }
+ virtual double Calculate (double x)
+ {
+ if (x < 0.0)
+ {
+ x = -x;
+ }
+ if (x < 1.0)
+ {
+ return 1.0-x;
+ }
+ return 0.0;
+ }
+};
+
+class BoxKernel : public Kernel {
+ virtual double GetWidth() { return 0.5; }
+ virtual double Calculate (double x)
+ {
+ if (-0.5 <= x && x < 0.5)
+ return 1.0;
+ return 0.0;
+ }
+};
+
// ----------
// - Bitmap -
// ----------
@@ -282,17 +368,14 @@ public:
SAL_DLLPRIVATE sal_Bool ImplScaleFast( const double& rScaleX, const double& rScaleY );
SAL_DLLPRIVATE sal_Bool ImplScaleInterpolate( const double& rScaleX, const double& rScaleY );
- SAL_DLLPRIVATE bool ImplScaleLanczos( const double& rScaleX, const double& rScaleY );
+ SAL_DLLPRIVATE bool ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel);
- SAL_DLLPRIVATE void ImplCalculateContributions( const int aSourceSize, const int aDestinationSize,
- const double aSupport, const int aNumberOfContributions,
- double* pWeights, int* pPixels, int* pCount );
- SAL_DLLPRIVATE bool ImplHorizontalConvolution( Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc,
- int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount );
- SAL_DLLPRIVATE bool ImplVerticalConvolution( Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc,
- int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount );
+ SAL_DLLPRIVATE static void ImplCalculateContributions( const int aSourceSize, const int aDestinationSize,
+ int& aNumberOfContributions, double*& pWeights, int*& pPixels, int*& pCount,
+ Kernel& aKernel );
- SAL_DLLPRIVATE static double ImplLanczosKernel( const double aValue, const double aSupport );
+ SAL_DLLPRIVATE bool ImplConvolutionPass( Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc,
+ int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount );
SAL_DLLPRIVATE sal_Bool ImplMakeMono( sal_uInt8 cThreshold );
SAL_DLLPRIVATE sal_Bool ImplMakeMonoDither();
@@ -310,7 +393,7 @@ public:
long nR1, long nR2, long nG1, long nG2, long nB1, long nB2,
long nColors, long nPixels, long& rIndex );
SAL_DLLPRIVATE sal_Bool ImplConvolute3( const long* pMatrix, long nDivisor,
- const BmpFilterParam* pFilterParam, const Link* pProgress );
+ const BmpFilterParam* pFilterParam, const Link* pProgress );
SAL_DLLPRIVATE sal_Bool ImplMedianFilter( const BmpFilterParam* pFilterParam, const Link* pProgress );
SAL_DLLPRIVATE sal_Bool ImplSobelGrey( const BmpFilterParam* pFilterParam, const Link* pProgress );
SAL_DLLPRIVATE sal_Bool ImplEmbossGrey( const BmpFilterParam* pFilterParam, const Link* pProgress );
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index ec458d9..a469681 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -912,13 +912,37 @@ sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uLong
if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) )
{
if( BMP_SCALE_FAST == nScaleFlag )
+ {
bRet = ImplScaleFast( rScaleX, rScaleY );
+ }
else if( BMP_SCALE_INTERPOLATE == nScaleFlag )
+ {
bRet = ImplScaleInterpolate( rScaleX, rScaleY );
+ }
else if( BMP_SCALE_LANCZOS == nScaleFlag )
- bRet = ImplScaleLanczos( rScaleX, rScaleY );
+ {
+ Lanczos3Kernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel);
+ }
+ else if( BMP_SCALE_BICUBIC == nScaleFlag )
+ {
+ BicubicKernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
+ }
+ else if( BMP_SCALE_BILINEAR == nScaleFlag )
+ {
+ BilinearKernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
+ }
+ else if( BMP_SCALE_BOX == nScaleFlag )
+ {
+ BoxKernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
+ }
else
- bRet = sal_False;
+ {
+ return false;
+ }
}
else
bRet = sal_True;
@@ -2208,33 +2232,28 @@ sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
return bRet;
}
-bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY )
+bool Bitmap::ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel )
{
- const Size aSizePix( GetSizePixel() );
- const long nWidth = aSizePix.Width();
- const long nHeight = aSizePix.Height();
+ const long nWidth = GetSizePixel().Width();
+ const long nHeight = GetSizePixel().Height();
const long nNewWidth = FRound( nWidth * rScaleX );
const long nNewHeight = FRound( nHeight * rScaleY );
- double aSupport = 3.0; // Sampling radius
-
- // Do horizontal filtering
- double aScale = nNewWidth / (double) nWidth;
- double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
-
- int aNumberOfContributions = (int) ( 2 * aScaledRadius + 1 );
+ bool bResult;
+ BitmapReadAccess* pReadAcc;
+ Bitmap aNewBitmap;
- double* pWeights = new double[ nNewWidth*aNumberOfContributions ];
- int* pPixels = new int[ nNewWidth*aNumberOfContributions ];
- int* pCount = new int[ nNewWidth ];
+ int aNumberOfContributions;
+ double* pWeights;
+ int* pPixels;
+ int* pCount;
- ImplCalculateContributions( nWidth, nNewWidth, aSupport, aNumberOfContributions, pWeights, pPixels, pCount );
-
- BitmapReadAccess* pReadAcc = AcquireReadAccess();
- Bitmap aNewBitmap( Size( nNewWidth, nHeight ), 24);
- bool bResult = ImplHorizontalConvolution( aNewBitmap, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
+ // Do horizontal filtering
+ ImplCalculateContributions( nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel );
+ pReadAcc = AcquireReadAccess();
+ aNewBitmap = Bitmap( Size( nHeight, nNewWidth ), 24);
+ bResult = ImplConvolutionPass( aNewBitmap, nNewWidth, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
- // Cleanup
ReleaseAccess( pReadAcc );
delete[] pWeights;
delete[] pCount;
@@ -2243,26 +2262,15 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY )
if ( !bResult )
return bResult;
- // Swap current bitmap with new bitmap
+ // Swap Bitmaps
ImplAssignWithSize( aNewBitmap );
// Do vertical filtering
- aScale = nNewHeight / (double) nHeight;
- aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
-
- aNumberOfContributions = (int) ( 2 * aScaledRadius + 1 );
-
- pWeights = new double[ nNewHeight*aNumberOfContributions ];
- pPixels = new int[ nNewHeight*aNumberOfContributions ];
- pCount = new int[ nNewHeight ];
-
- ImplCalculateContributions(nHeight, nNewHeight, aSupport, aNumberOfContributions, pWeights, pPixels, pCount );
-
+ ImplCalculateContributions( nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel );
pReadAcc = AcquireReadAccess();
aNewBitmap = Bitmap( Size( nNewWidth, nNewHeight ), 24);
- bResult = ImplVerticalConvolution( aNewBitmap, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
+ bResult = ImplConvolutionPass( aNewBitmap, nNewHeight, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
- // Cleanup
ReleaseAccess( pReadAcc );
delete[] pWeights;
delete[] pCount;
@@ -2271,19 +2279,24 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY )
if ( !bResult )
return bResult;
- // Swap current bitmap with new bitmap
ImplAssignWithSize( aNewBitmap );
return true;
}
-void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDestinationSize, const double aSupport,
- const int aNumberOfContributions, double* pWeights, int* pPixels,
- int* pCount )
+void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDestinationSize, int& aNumberOfContributions,
+ double*& pWeights, int*& pPixels, int*& pCount, Kernel& aKernel)
{
+ const double aSamplingRadius = aKernel.GetWidth();
const double aScale = aDestinationSize / (double) aSourceSize;
- const double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
- const double aFilterFactor = (aScale <= 1.0) ? aScale : 1.0;
+ const double aScaledRadius = (aScale < 1.0) ? aSamplingRadius / aScale : aSamplingRadius;
+ const double aFilterFactor = (aScale < 1.0) ? aScale : 1.0;
+
+ aNumberOfContributions = (int) ( 2 * ceil(aScaledRadius) + 1 );
+
+ pWeights = new double[ aDestinationSize*aNumberOfContributions ];
+ pPixels = new int[ aDestinationSize*aNumberOfContributions ];
+ pCount = new int[ aDestinationSize ];
double aWeight, aCenter;
int aIndex, aLeft, aRight;
@@ -2295,37 +2308,19 @@ void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDesti
aCurrentCount = 0;
aCenter = i / aScale;
- aLeft = (int) ((aCenter + 0.5) - aScaledRadius );
- aRight = (int) ( aLeft + 2 * aScaledRadius );
+ aLeft = (int) floor(aCenter - aScaledRadius);
+ aRight = (int) ceil (aCenter + aScaledRadius);
for ( int j = aLeft; j <= aRight; j++ )
{
- aWeight = ImplLanczosKernel( (aCenter - j) * aFilterFactor, aSupport );
+ aWeight = aKernel.Calculate( aFilterFactor * ( aCenter - (double) j ) );
- if (aWeight == 0.0)
- {
+ // Reduce calculations with ignoring weights of 0.0
+ if (fabs(aWeight < 0.0001))
continue;
- }
-
- // Mirror edges
- if (j < 0)
- {
- aPixelIndex = -j;
- }
- else if ( j >= aSourceSize )
- {
- aPixelIndex = (aSourceSize - j) + aSourceSize - 1;
- }
- else
- {
- aPixelIndex = j;
- }
- // Edge case for small bitmaps
- if ( aPixelIndex < 0 || aPixelIndex >= aSourceSize )
- {
- aWeight = 0.0;
- }
+ // Handling on edges
+ aPixelIndex = MinMax( j, 0, aSourceSize - 1);
pWeights[ aIndex + aCurrentCount ] = aWeight;
pPixels[ aIndex + aCurrentCount ] = aPixelIndex;
@@ -2336,17 +2331,14 @@ void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDesti
}
}
-bool Bitmap::ImplHorizontalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
+bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
{
BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess();
if (!pReadAcc || !pWriteAcc)
- {
return false;
- }
const int nHeight = GetSizePixel().Height();
- const int nNewWidth = aNewBitmap.GetSizePixel().Width();
BitmapColor aColor;
double aValueRed, aValueGreen, aValueBlue;
@@ -2355,79 +2347,20 @@ bool Bitmap::ImplHorizontalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pRe
for ( int y = 0; y < nHeight; y++ )
{
- for ( int i = 0; i < nNewWidth; i++ )
+ for ( int x = 0; x < nNewSize; x++ )
{
- aBaseIndex = i * aNumberOfContributions;
- aValueRed = aValueGreen = aValueBlue = 0.0;
- aSum = 0.0;
+ aBaseIndex = x * aNumberOfContributions;
+ aSum = aValueRed = aValueGreen = aValueBlue = 0.0;
- for ( int j=0; j < pCount[i]; j++ )
+ for ( int j=0; j < pCount[x]; j++ )
{
aIndex = aBaseIndex + j;
- aWeight = pWeights[ aIndex ];
- aSum += aWeight;
- if( pReadAcc->HasPalette() )
- {
- aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( y , pPixels[ aIndex ] ) );
- }
- else
- {
- aColor = pReadAcc->GetPixel( y , pPixels[ aIndex ] );
- }
+ aSum += aWeight = pWeights[ aIndex ];
- aValueRed += aWeight * aColor.GetRed();
- aValueGreen += aWeight * aColor.GetGreen();
- aValueBlue += aWeight * aColor.GetBlue();
- }
-
- BitmapColor aResultColor(
- (sal_uInt8) MinMax( aValueRed / aSum, 0, 255 ),
- (sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ),
- (sal_uInt8) MinMax( aValueBlue / aSum, 0, 255 ) );
- pWriteAcc->SetPixel( y, i, aResultColor );
- }
- }
- aNewBitmap.ReleaseAccess( pWriteAcc );
- return true;
-}
-
-bool Bitmap::ImplVerticalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
-{
- BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess();
-
- if (!pReadAcc || !pWriteAcc)
- {
- return false;
- }
-
- const int nWidth = GetSizePixel().Width();
- const int nNewHeight = aNewBitmap.GetSizePixel().Height();
-
- BitmapColor aColor;
- double aValueRed, aValueGreen, aValueBlue;
- double aSum, aWeight;
- int aBaseIndex, aIndex;
- for (int x = 0; x < nWidth; x++)
- {
- for (int i = 0; i < nNewHeight; i++)
- {
- aBaseIndex = i * aNumberOfContributions;
- aSum = 0.0;
- aValueRed = aValueGreen = aValueBlue = 0.0;
-
- for (int j=0; j < pCount[i]; j++)
- {
- aIndex = aBaseIndex + j;
- aWeight = pWeights[ aIndex ];
- aSum += aWeight;
+ aColor = pReadAcc->GetPixel( y, pPixels[ aIndex ] );
if( pReadAcc->HasPalette() )
- {
- aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( pPixels[ aIndex ] , x ) );
- }
- else
- {
- aColor = pReadAcc->GetPixel( pPixels[ aIndex ] , x );
- }
+ aColor = pReadAcc->GetPaletteColor( aColor );
+
aValueRed += aWeight * aColor.GetRed();
aValueGreen += aWeight * aColor.GetGreen();
aValueBlue += aWeight * aColor.GetBlue();
@@ -2437,32 +2370,11 @@ bool Bitmap::ImplVerticalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pRead
(sal_uInt8) MinMax( aValueRed / aSum, 0, 255 ),
(sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ),
(sal_uInt8) MinMax( aValueBlue / aSum, 0, 255 ) );
- pWriteAcc->SetPixel( i, x, aResultColor );
+ pWriteAcc->SetPixel( x, y, aResultColor );
}
}
-
aNewBitmap.ReleaseAccess( pWriteAcc );
return true;
}
-double Bitmap::ImplLanczosKernel( const double aValue, const double aSupport ) {
- double x = aValue;
- if (x == 0.0)
- {
- return 1.0;
- }
- if (x < 0.0)
- {
- x = -x;
- }
-
- x *= M_PI;
- if (x < aSupport)
- {
- double x3 = x / 3.0;
- return (sin(x) / x) * sin(x3) / x3;
- }
- return 0.0;
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list