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 --- |