Index: kimageeffect.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdefx/kimageeffect.cpp,v
retrieving revision 1.47
diff -u -2 -d -p -b -r1.47 kimageeffect.cpp
--- kimageeffect.cpp	3 Jun 2003 07:58:52 -0000	1.47
+++ kimageeffect.cpp	8 Jun 2003 23:00:05 -0000
@@ -2520,4 +2520,103 @@ bool KImageEffect::blendOnLower(
   return true;
 }
+
+void KImageEffect::blendOnLower(const QImage &upper, const QPoint &upperOffset,
+                          QImage &lower, const QRect &lowerRect, float opacity)
+{
+    // clip rect
+    QRect lr =  lowerRect & lower.rect();
+    lr.setWidth( QMIN(lr.width(), upper.width()-upperOffset.x()) );
+    lr.setHeight( QMIN(lr.height(), upper.height()-upperOffset.y()) );
+    if ( !lr.isValid() ) return;
+
+    // blend
+    for (int y = 0; y < lr.height(); y++) {
+        for (int x = 0; x < lr.width(); x++) {
+            QRgb *b = reinterpret_cast<QRgb*>(lower.scanLine(lr.y() + y)+ (lr.x() + x) * sizeof(QRgb));
+            QRgb *d = reinterpret_cast<QRgb*>(upper.scanLine(upperOffset.y() + y) + (upperOffset.x() + x) * sizeof(QRgb));
+            int a = qRound(opacity * qAlpha(*d));
+            *b = qRgb(qRed(*b) - (((qRed(*b) - qRed(*d)) * a) >> 8),
+                      qGreen(*b) - (((qGreen(*b) - qGreen(*d)) * a) >> 8),
+                      qBlue(*b) - (((qBlue(*b) - qBlue(*d)) * a) >> 8));
+        }
+    }
+}
+
+
+QRect KImageEffect::computeDestinationRect(const QSize &lowerSize,
+                                       Disposition disposition, QImage &upper)
+{
+    int w = lowerSize.width();
+    int h = lowerSize.height();
+    int ww = upper.width();
+    int wh = upper.height();
+    QRect d;
+
+    switch (disposition) {
+    case NoImage:
+        break;
+    case Centered:
+        d.setRect((w - ww) / 2, (h - wh) / 2, ww, wh);
+        break;
+    case Tiled:
+        d.setRect(0, 0, w, h);
+        break;
+    case CenterTiled:
+        d.setCoords(-ww + ((w - ww) / 2) % ww, -wh + ((h - wh) / 2) % wh,
+                    w-1, h-1);
+        break;
+    case Scaled:
+        upper = upper.smoothScale(w, h);
+        d.setRect(0, 0, w, h);
+        break;
+    case CenteredAutoFit:
+        if( ww <= w && wh <= h ) {
+            d.setRect((w - ww) / 2, (h - wh) / 2, ww, wh); // like Centered
+            break;
+        }
+        // fall through
+    case CenteredMaxpect: {
+        double sx = (double) w / ww;
+        double sy = (double) h / wh;
+        if (sx > sy) {
+            ww = (int)(sy * ww);
+            wh = h;
+        } else {
+            wh = (int)(sx * wh);
+            ww = w;
+        }
+        upper = upper.smoothScale(ww, wh);
+        d.setRect((w - ww) / 2, (h - wh) / 2, ww, wh);
+        break;
+    }
+    case TiledMaxpect: {
+        double sx = (double) w / ww;
+        double sy = (double) h / wh;
+        if (sx > sy) {
+            ww = (int)(sy * ww);
+            wh = h;
+        } else {
+            wh = (int)(sx * wh);
+            ww = w;
+        }
+        upper = upper.smoothScale(ww, wh);
+        d.setRect(0, 0, w, h);
+        break;
+    }
+    }
+
+    return d;
+}
+
+void KImageEffect::blendOnLower(QImage &upper, QImage &lower,
+                                Disposition disposition, float opacity)
+{
+    QRect r = computeDestinationRect(lower.size(), disposition, upper);
+    for (int y = r.top(); y<r.bottom(); y += upper.height())
+        for (int x = r.left(); x<r.right(); x += upper.width())
+            blendOnLower(upper, QPoint(-QMIN(x, 0), -QMIN(y, 0)),
+                   lower, QRect(x, y, upper.width(), upper.height()), opacity);
+}
+
 
 // For selected icons
Index: kimageeffect.h
===================================================================
RCS file: /home/kde/kdelibs/kdefx/kimageeffect.h,v
retrieving revision 1.30
diff -u -2 -d -p -b -r1.30 kimageeffect.h
--- kimageeffect.h	2 Jun 2003 22:46:18 -0000	1.30
+++ kimageeffect.h	8 Jun 2003 23:00:05 -0000
@@ -107,6 +107,6 @@ public:
      * @param clr source color to be blended into the destination image.
      * @param dst destination image in which the source will be blended into.
-     * @param opacity opacity (in percent) which determines how much the source
-     *                color will be blended into the destination image.
+     * @param opacity opacity (between 0.0 and 1.0) which determines how much
+     *             the source color will be blended into the destination image.
      * @return The destination image (dst) containing the result.
      */
@@ -125,6 +125,6 @@ public:
      * @param src source image to be blended into the destination image.
      * @param dst destination image in which the source will be blended into.
-     * @param opacity opacity (in percent) which determines how much the source
-     *                image will be blended into the destination image.
+     * @param opacity opacity (between 0.0 and 1.0) which determines how much
+     *             the source image will be blended into the destination image.
      * @return The destination image (dst) containing the result.
      */
@@ -204,4 +204,48 @@ public:
      */
     static bool blendOnLower(int x, int y, const QImage & upper, const QImage & lower);
+
+    /** @since 3.2
+     * Blend part of an image into part of another, using the opacity value
+     * and the alpha channel in the expected way.
+     * Note that the destination rectangle will be correctly clipped.
+     *
+     * @param upperOffset Offset for the part of the upper image to be used.
+     * @param lowerRect Rectangle for the part of the lower image where the
+     *                  blending will occur.
+     * @param opacity Opacity (between 0.0 and 1.0) which determines how much
+     *             the source image will be blended into the destination image.
+     */
+    static void blendOnLower(const QImage &upper, const QPoint &upperOffset,
+                             QImage &lower, const QRect &lowerRect, float opacity);
+
+    /** @since 3.2
+     * Disposition of a source image on top of a destination image.
+     */
+    enum Disposition { NoImage = 0, Centered, Tiled, CenterTiled,
+                      CenteredMaxpect, TiledMaxpect, Scaled, CenteredAutoFit };
+
+    /** @since 3.2
+     * Compute the destination rectangle where to draw the upper image on top
+     * of another image using the givem disposition. For tiled
+     * disposition, the rectangle should be duplicated on the whole area to
+     * obtained the wanted effect.
+     *
+     * @param lowerSize The size of the destination image.
+     * @param disposition The wanted disposition.
+     * @param upper The upper image. Note that this image may be scaled to
+     *               adjust to the requested disposition.
+     *
+     * @return the computed rectangle. Its size may exceed @e lowerSize.
+     */
+    static QRect computeDestinationRect(const QSize &lowerSize,
+                                      Disposition disposition, QImage &upper);
+
+    /** @since 3.2
+     * Blend an image on top of another using a given disposition and a given
+     * opacity. The alpha channel of the upper image is used in the expected
+     * way. Beware the upper image may be modified.
+     */
+    static void blendOnLower(QImage &upper, QImage &lower,
+                             Disposition disposition, float opacity);
 
     /**
