F:/KPlato/koffice/libs/pigment/compositeops/KoCompositeOpOver.h

Aller à la documentation de ce fichier.
00001 /*
00002  *  Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this library; see the file COPYING.LIB.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #ifndef KOCOMPOSITEOPOVER_H_
00021 #define KOCOMPOSITEOPOVER_H_
00022 
00023 #include "KoColorSpaceMaths.h"
00024 #include "KoCompositeOp.h"
00025 
00026 #define NATIVE_OPACITY_OPAQUE KoColorSpaceMathsTraits<channels_type>::max()
00027 #define NATIVE_OPACITY_TRANSPARENT KoColorSpaceMathsTraits<channels_type>::min()
00028 
00032 template<class _CSTraits>
00033 class KoCompositeOpOver : public KoCompositeOp {
00034     typedef typename _CSTraits::channels_type channels_type;
00035     public:
00036 
00037         KoCompositeOpOver(KoColorSpace * cs)
00038         : KoCompositeOp(cs, COMPOSITE_OVER, i18n("Normal" ) )
00039         {
00040         }
00041 
00042     public:
00043         struct Pixel {
00044             quint16 lightness;
00045             quint16 a;
00046             quint16 b;
00047             quint16 alpha;
00048         };
00049 
00050         void composite(quint8 *dstRowStart,
00051                         qint32 dststride,
00052                         const quint8 *srcRowStart,
00053                         qint32 srcstride,
00054                         const quint8 *maskRowStart,
00055                         qint32 maskstride,
00056                         qint32 rows,
00057                         qint32 cols,
00058                         quint8 U8_opacity,
00059                         const QBitArray & channelFlags) const
00060         {
00061             Q_UNUSED( channelFlags );
00062 
00063             channels_type opacity = KoColorSpaceMaths<quint8, channels_type>::scaleToA(U8_opacity);
00064             qint32 pixelSize = colorSpace()->pixelSize();
00065 
00066             while (rows > 0) {
00067                 const channels_type *srcN = reinterpret_cast<const channels_type *>(srcRowStart);
00068                 channels_type *dstN = reinterpret_cast<channels_type *>(dstRowStart);
00069                 const quint8 *mask = maskRowStart;
00070                 
00071                 qint32 columns = cols;
00072 
00073                 while (columns > 0) {
00074                     
00075                     channels_type srcAlpha = srcN[_CSTraits::alpha_pos];
00076 
00077                     // apply the alphamask
00078                     if (mask != 0) {
00079                         if (*mask != OPACITY_OPAQUE) {
00080                             srcAlpha = KoColorSpaceMaths<channels_type,quint8>::multiply(srcAlpha, *mask);
00081                         }
00082                         mask++;
00083                     }
00084 
00085                     if (srcAlpha != NATIVE_OPACITY_TRANSPARENT) {
00086 
00087                         if (opacity != NATIVE_OPACITY_OPAQUE) {
00088                             srcAlpha = KoColorSpaceMaths<channels_type>::multiply(srcAlpha, opacity);
00089                         }
00090 
00091                         if (srcAlpha == NATIVE_OPACITY_OPAQUE) {
00092                             memcpy(dstN, srcN, pixelSize);
00093                         } else {
00094                             channels_type dstAlpha = dstN[_CSTraits::alpha_pos];
00095 
00096                             channels_type srcBlend;
00097 
00098                             if (dstAlpha == NATIVE_OPACITY_OPAQUE) {
00099                                 srcBlend = srcAlpha;
00100                             } else {
00101                                 channels_type newAlpha = dstAlpha + KoColorSpaceMaths<channels_type>::multiply(NATIVE_OPACITY_OPAQUE - dstAlpha, srcAlpha);
00102                                 dstN[_CSTraits::alpha_pos] = newAlpha;
00103 
00104                                 if (newAlpha != 0) {
00105                                     srcBlend = KoColorSpaceMaths<channels_type>::divide(srcAlpha, newAlpha);
00106                                 } else {
00107                                     srcBlend = srcAlpha;
00108                                 }
00109                             }
00110 
00111                             if (srcBlend == NATIVE_OPACITY_OPAQUE) {
00112                                 memcpy(dstN, srcN, pixelSize);
00113                             } else {
00114                                 for(uint i = 0; i <  _CSTraits::channels_nb; i++)
00115                                 {
00116                                     if( (int)i != _CSTraits::alpha_pos)
00117                                         dstN[i] = KoColorSpaceMaths<channels_type>::blend(srcN[i], dstN[i], srcBlend);
00118                                 }
00119                             }
00120                         }
00121                     }
00122                     columns--;
00123                     srcN+=_CSTraits::channels_nb;
00124                     dstN+=_CSTraits::channels_nb;
00125                 }
00126 
00127                 rows--;
00128                 srcRowStart += srcstride;
00129                 dstRowStart += dststride;
00130                 if(maskRowStart) {
00131                     maskRowStart += maskstride;
00132                 }
00133             }
00134         }
00135 
00136 };
00137 
00138 #endif

Généré le Wed Nov 22 23:41:13 2006 pour KPlato par  doxygen 1.5.1-p1