bitmapex.cxx (0d6bca7a) bitmapex.cxx (f8c0d554)
1/**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 823 unchanged lines hidden (view full) ---

832
833 return nTransparency;
834}
835
836// ------------------------------------------------------------------
837
838namespace
839{
1/**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 823 unchanged lines hidden (view full) ---

832
833 return nTransparency;
834}
835
836// ------------------------------------------------------------------
837
838namespace
839{
840 void impSmoothPoint(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead)
841 {
842 double fDeltaX(rSource.getX() - nIntX);
843 double fDeltaY(rSource.getY() - nIntY);
844 sal_Int32 nIndX(0L);
845 sal_Int32 nIndY(0L);
846
847 if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width())
848 {
849 nIndX++;
850 }
851 else if(fDeltaX < 0.0 && nIntX >= 1L)
852 {
853 fDeltaX = -fDeltaX;
854 nIndX--;
855 }
856
857 if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height())
858 {
859 nIndY++;
860 }
861 else if(fDeltaY < 0.0 && nIntY >= 1L)
862 {
863 fDeltaY = -fDeltaY;
864 nIndY--;
865 }
866
867 if(nIndX || nIndY)
868 {
869 const double fColorToReal(1.0 / 255.0);
870 double fR(rValue.GetRed() * fColorToReal);
871 double fG(rValue.GetGreen() * fColorToReal);
872 double fB(rValue.GetBlue() * fColorToReal);
873 double fRBottom(0.0), fGBottom(0.0), fBBottom(0.0);
874
875 if(nIndX)
876 {
877 const double fMulA(fDeltaX * fColorToReal);
878 double fMulB(1.0 - fDeltaX);
879 const BitmapColor aTopPartner(rRead.GetColor(nIntY, nIntX + nIndX));
880
881 fR = (fR * fMulB) + (aTopPartner.GetRed() * fMulA);
882 fG = (fG * fMulB) + (aTopPartner.GetGreen() * fMulA);
883 fB = (fB * fMulB) + (aTopPartner.GetBlue() * fMulA);
884
885 if(nIndY)
886 {
887 fMulB *= fColorToReal;
888 const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX));
889 const BitmapColor aBottomPartner(rRead.GetColor(nIntY + nIndY, nIntX + nIndX));
890
891 fRBottom = (aBottom.GetRed() * fMulB) + (aBottomPartner.GetRed() * fMulA);
892 fGBottom = (aBottom.GetGreen() * fMulB) + (aBottomPartner.GetGreen() * fMulA);
893 fBBottom = (aBottom.GetBlue() * fMulB) + (aBottomPartner.GetBlue() * fMulA);
894 }
895 }
896
897 if(nIndY)
898 {
899 if(!nIndX)
900 {
901 const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX));
902
903 fRBottom = aBottom.GetRed() * fColorToReal;
904 fGBottom = aBottom.GetGreen() * fColorToReal;
905 fBBottom = aBottom.GetBlue() * fColorToReal;
906 }
907
908 const double fMulB(1.0 - fDeltaY);
909
910 fR = (fR * fMulB) + (fRBottom * fDeltaY);
911 fG = (fG * fMulB) + (fGBottom * fDeltaY);
912 fB = (fB * fMulB) + (fBBottom * fDeltaY);
913 }
914
915 rValue.SetRed((sal_uInt8)(fR * 255.0));
916 rValue.SetGreen((sal_uInt8)(fG * 255.0));
917 rValue.SetBlue((sal_uInt8)(fB * 255.0));
918 }
919 }
920
921 Bitmap impTransformBitmap(
840 Bitmap impTransformBitmap(
922 const Bitmap& rSource,
923 const Size aDestinationSize,
924 const basegfx::B2DHomMatrix& rTransform,
925 bool bSmooth)
841 const Bitmap& rSource,
842 const Size aDestinationSize,
843 const basegfx::B2DHomMatrix& rTransform,
844 bool bSmooth)
926 {
845 {
927 Bitmap aDestination(aDestinationSize, 24);
928 BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess();
929
846 Bitmap aDestination(aDestinationSize, 24);
847 BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess();
848
930 if(pWrite)
931 {
932 const Size aContentSizePixel(rSource.GetSizePixel());
933 BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess();
849 if(pWrite)
850 {
851 //const Size aContentSizePixel(rSource.GetSizePixel());
852 BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess();
934
853
935 if(pRead)
936 {
937 const Size aDestinationSizePixel(aDestination.GetSizePixel());
938 bool bWorkWithIndex(rSource.GetBitCount() <= 8);
939 BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff));
854 if(pRead)
855 {
856 const Size aDestinationSizePixel(aDestination.GetSizePixel());
857 const BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff));
940
858
941 for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++)
942 {
943 for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++)
944 {
945 const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
946 const sal_Int32 nIntX(basegfx::fround(aSourceCoor.getX()));
859 for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++)
860 {
861 for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++)
862 {
863 const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
947
864
948 if(nIntX >= 0L && nIntX < aContentSizePixel.getWidth())
949 {
950 const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY()));
865 if(bSmooth)
866 {
867 pWrite->SetPixel(
868 y,
869 x,
870 pRead->GetInterpolatedColorWithFallback(
871 aSourceCoor.getY(),
872 aSourceCoor.getX(),
873 aOutside));
874 }
875 else
876 {
877 // this version does the correct <= 0.0 checks, so no need
878 // to do the static_cast< sal_Int32 > self and make an error
879 pWrite->SetPixel(
880 y,
881 x,
882 pRead->GetColorWithFallback(
883 aSourceCoor.getY(),
884 aSourceCoor.getX(),
885 aOutside));
886 }
887 }
888 }
951
889
952 if(nIntY >= 0L && nIntY < aContentSizePixel.getHeight())
953 {
954 // inside pixel
955 BitmapColor aValue;
890 delete pRead;
891 }
956
892
957 if(bWorkWithIndex)
958 {
959 aValue = pRead->GetPaletteColor(pRead->GetPixelIndex(nIntY, nIntX));
960 }
961 else
962 {
963 aValue = pRead->GetPixel(nIntY, nIntX);
964 }
893 delete pWrite;
894 }
965
895
966 if(bSmooth)
967 {
968 impSmoothPoint(aValue, aSourceCoor, nIntX, nIntY, *pRead);
969 }
970
971 pWrite->SetPixel(y, x, aValue);
972 continue;
973 }
974 }
975
976 // here are outside pixels. Complete mask
977 if(bWorkWithIndex)
978 {
979 pWrite->SetPixel(y, x, aOutside);
980 }
981 }
982 }
983
984 delete pRead;
985 }
986
987 delete pWrite;
988 }
989
990 rSource.AdaptBitCount(aDestination);
991
992 return aDestination;
896 rSource.AdaptBitCount(aDestination);
897
898 return aDestination;
993 }
899 }
994} // end of anonymous namespace
900} // end of anonymous namespace
901
995BitmapEx BitmapEx::TransformBitmapEx(
996 double fWidth,
997 double fHeight,
902BitmapEx BitmapEx::TransformBitmapEx(
903 double fWidth,
904 double fHeight,
998 const basegfx::B2DHomMatrix& rTransformation) const
905 const basegfx::B2DHomMatrix& rTransformation,
906 bool bSmooth) const
999{
1000 if(fWidth <= 1 || fHeight <= 1)
1001 return BitmapEx();
1002
1003 // force destination to 24 bit, we want to smooth output
1004 const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
907{
908 if(fWidth <= 1 || fHeight <= 1)
909 return BitmapEx();
910
911 // force destination to 24 bit, we want to smooth output
912 const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
1005 static bool bDoSmoothAtAll(true);
1006 const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll));
913 const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth));
1007
1008 // create mask
1009 if(IsTransparent())
1010 {
1011 if(IsAlpha())
1012 {
914
915 // create mask
916 if(IsTransparent())
917 {
918 if(IsAlpha())
919 {
1013 const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll));
920 const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth));
1014 return BitmapEx(aDestination, AlphaMask(aAlpha));
1015 }
1016 else
1017 {
1018 const Bitmap aMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false));
1019 return BitmapEx(aDestination, aMask);
1020 }
1021 }
1022
1023 return BitmapEx(aDestination);
1024}
1025
1026// ------------------------------------------------------------------
1027
1028BitmapEx BitmapEx::getTransformed(
1029 const basegfx::B2DHomMatrix& rTransformation,
921 return BitmapEx(aDestination, AlphaMask(aAlpha));
922 }
923 else
924 {
925 const Bitmap aMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false));
926 return BitmapEx(aDestination, aMask);
927 }
928 }
929
930 return BitmapEx(aDestination);
931}
932
933// ------------------------------------------------------------------
934
935BitmapEx BitmapEx::getTransformed(
936 const basegfx::B2DHomMatrix& rTransformation,
1030 double fMaximumArea) const
937 const basegfx::B2DRange& rVisibleRange,
938 double fMaximumArea,
939 bool bSmooth) const
1031{
1032 BitmapEx aRetval;
1033
1034 if(IsEmpty())
1035 return aRetval;
1036
1037 const sal_uInt32 nSourceWidth(GetSizePixel().Width());
1038 const sal_uInt32 nSourceHeight(GetSizePixel().Height());
1039
1040 if(!nSourceWidth || !nSourceHeight)
1041 return aRetval;
1042
940{
941 BitmapEx aRetval;
942
943 if(IsEmpty())
944 return aRetval;
945
946 const sal_uInt32 nSourceWidth(GetSizePixel().Width());
947 const sal_uInt32 nSourceHeight(GetSizePixel().Height());
948
949 if(!nSourceWidth || !nSourceHeight)
950 return aRetval;
951
1043 // Get dest range
952 // Get aOutlineRange
1044 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
953 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
954
1045 aOutlineRange.transform(rTransformation);
1046
955 aOutlineRange.transform(rTransformation);
956
1047 // get target size
1048 double fWidth(aOutlineRange.getWidth());
1049 double fHeight(aOutlineRange.getHeight());
957 // create visible range from it by moving from relative to absolute
958 basegfx::B2DRange aVisibleRange(rVisibleRange);
1050
959
960 aVisibleRange.transform(
961 basegfx::tools::createScaleTranslateB2DHomMatrix(
962 aOutlineRange.getRange(),
963 aOutlineRange.getMinimum()));
964
965 // get target size (which is visible range's size)
966 double fWidth(aVisibleRange.getWidth());
967 double fHeight(aVisibleRange.getHeight());
968
1051 if(fWidth < 1.0 || fHeight < 1.0)
969 if(fWidth < 1.0 || fHeight < 1.0)
970 {
1052 return aRetval;
971 return aRetval;
972 }
1053
1054 // test if discrete size (pixel) maybe too big and limit it
1055 const double fArea(fWidth * fHeight);
973
974 // test if discrete size (pixel) maybe too big and limit it
975 const double fArea(fWidth * fHeight);
1056 const bool bNeedToReduce(fArea > fMaximumArea);
976 const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea));
1057 double fReduceFactor(1.0);
1058
1059 if(bNeedToReduce)
1060 {
1061 fReduceFactor = sqrt(fMaximumArea / fArea);
1062 fWidth *= fReduceFactor;
1063 fHeight *= fReduceFactor;
1064 }

--- 4 unchanged lines hidden (view full) ---

1069 basegfx::tools::createScaleB2DHomMatrix(
1070 1.0 / nSourceWidth,
1071 1.0 / nSourceHeight));
1072
1073 // multiply with given transform which leads from unit coordinates inside
1074 // aOutlineRange
1075 aTransform = rTransformation * aTransform;
1076
977 double fReduceFactor(1.0);
978
979 if(bNeedToReduce)
980 {
981 fReduceFactor = sqrt(fMaximumArea / fArea);
982 fWidth *= fReduceFactor;
983 fHeight *= fReduceFactor;
984 }

--- 4 unchanged lines hidden (view full) ---

989 basegfx::tools::createScaleB2DHomMatrix(
990 1.0 / nSourceWidth,
991 1.0 / nSourceHeight));
992
993 // multiply with given transform which leads from unit coordinates inside
994 // aOutlineRange
995 aTransform = rTransformation * aTransform;
996
1077 // substract top-left of aOutlineRange
1078 aTransform.translate(-aOutlineRange.getMinX(), -aOutlineRange.getMinY());
997 // substract top-left of absolute VisibleRange
998 aTransform.translate(
999 -aVisibleRange.getMinX(),
1000 -aVisibleRange.getMinY());
1079
1080 // scale to target pixels (if needed)
1081 if(bNeedToReduce)
1082 {
1083 aTransform.scale(fReduceFactor, fReduceFactor);
1084 }
1085
1086 // invert to get transformation from target pixel coordiates to source pixels
1087 aTransform.invert();
1088
1089 // create bitmap using source, destination and linear back-transformation
1001
1002 // scale to target pixels (if needed)
1003 if(bNeedToReduce)
1004 {
1005 aTransform.scale(fReduceFactor, fReduceFactor);
1006 }
1007
1008 // invert to get transformation from target pixel coordiates to source pixels
1009 aTransform.invert();
1010
1011 // create bitmap using source, destination and linear back-transformation
1090 aRetval = TransformBitmapEx(fWidth, fHeight, aTransform);
1012 aRetval = TransformBitmapEx(fWidth, fHeight, aTransform, bSmooth);
1091
1092 return aRetval;
1093}
1094
1095// ------------------------------------------------------------------
1096
1097BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const
1098{

--- 255 unchanged lines hidden ---
1013
1014 return aRetval;
1015}
1016
1017// ------------------------------------------------------------------
1018
1019BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const
1020{

--- 255 unchanged lines hidden ---