public ColorCafe calcDestColor (ColorCafe sourceColor, ColorCafe backgroundColor,
         double lightValue)
   {
      double sourceRed   = (double)sourceColor.red   / 255.0;
      double sourceGreen = (double)sourceColor.green / 255.0;
      double sourceBlue  = (double)sourceColor.blue  / 255.0;
      double sourceAlpha = (double)sourceColor.alpha / 255.0;
      double backgroundRed   = (double)backgroundColor.red   / 255.0;
      double backgroundGreen = (double)backgroundColor.green / 255.0;
      double backgroundBlue  = (double)backgroundColor.blue  / 255.0;

      // First, blend the source color to the background color using the alpha
      // of the source color.
      double red   = Interp.linearInterp (backgroundRed,   sourceRed  , sourceAlpha);
      double green = Interp.linearInterp (backgroundGreen, sourceGreen, sourceAlpha);
      double blue  = Interp.linearInterp (backgroundBlue,  sourceBlue , sourceAlpha);

      if (isLightEnabled)
      {
         // Now calculate the light color.
         double lightRed   = lightValue * (double)lightColor.red   / 255.0;
         double lightGreen = lightValue * (double)lightColor.green / 255.0;
         double lightBlue  = lightValue * (double)lightColor.blue  / 255.0;

         // Apply the light color to the new color.
         red   *= lightRed  ;
         green *= lightGreen;
         blue  *= lightBlue ;
      }

      // Clamp the color channels to the (0..1) range.
      red   = (red   < 0.0)? 0.0: red  ;
      red   = (red   > 1.0)? 1.0: red  ;
      green = (green < 0.0)? 0.0: green;
      green = (green > 1.0)? 1.0: green;
      blue  = (blue  < 0.0)? 0.0: blue ;
      blue  = (blue  > 1.0)? 1.0: blue ;

      // Rescale the color channels to the noise::uint8 (0..255) range and return
      // the new color.
      ColorCafe newColor = new ColorCafe((int)(red * 255.0) & 0xff,(int)(green * 255.0) & 0xff,
            (int)(blue  * 255.0) & 0xff, Math.max (sourceColor.alpha, backgroundColor.alpha));
      return newColor;
   }