Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
nsBlender.cpp File Reference
#include "nsBlender.h"
#include "nsCRT.h"

Go to the source code of this file.

Defines

#define BLEND_RED_MASK   0xf800
#define BLEND_GREEN_MASK   0x07e0
#define BLEND_BLUE_MASK   0x001f
#define BLEND_RED_SET_MASK   0xf8
#define BLEND_GREEN_SET_MASK   0xfC
#define BLEND_BLUE_SET_MASK   0xf8
#define BLEND_RED_SHIFT   8
#define BLEND_GREEN_SHIFT   3
#define BLEND_BLUE_SHIFT   3
#define BLEND_GREEN_BITS   6
#define RED16(x)   (((x) & BLEND_RED_MASK) >> BLEND_RED_SHIFT)
#define GREEN16(x)   (((x) & BLEND_GREEN_MASK) >> BLEND_GREEN_SHIFT)
#define BLUE16(x)   (((x) & BLEND_BLUE_MASK) << BLEND_BLUE_SHIFT)
#define MAKE16(r, g, b)

Functions

static void rangeCheck (nsIDrawingSurface *surface, PRInt32 &aX, PRInt32 &aY, PRInt32 &aWidth, PRInt32 &aHeight)
static void Do8Blend (float aOpacity, PRInt32 aNumLines, PRInt32 aNumBytes, PRUint8 *aSImage, PRUint8 *aS2Image, PRUint8 *aDImage, PRInt32 aSLSpan, PRInt32 aDLSpan)
 This is a simple case for 8-bit blending.
static void DoSingleImageBlend (PRUint32 aOpacity256, PRInt32 aNumLines, PRInt32 aNumBytes, PRUint8 *aSImage, PRUint8 *aDImage, PRInt32 aSLSpan, PRInt32 aDLSpan)
 This is the case where we have a single source buffer, all of whose pixels have an alpha value of 1.0.

Define Documentation

#define BLEND_BLUE_MASK   0x001f

Definition at line 82 of file nsBlender.cpp.

Definition at line 85 of file nsBlender.cpp.

Definition at line 88 of file nsBlender.cpp.

Definition at line 89 of file nsBlender.cpp.

#define BLEND_GREEN_MASK   0x07e0

Definition at line 81 of file nsBlender.cpp.

Definition at line 84 of file nsBlender.cpp.

Definition at line 87 of file nsBlender.cpp.

#define BLEND_RED_MASK   0xf800

Definition at line 80 of file nsBlender.cpp.

Definition at line 83 of file nsBlender.cpp.

Definition at line 86 of file nsBlender.cpp.

#define BLUE16 (   x)    (((x) & BLEND_BLUE_MASK) << BLEND_BLUE_SHIFT)

Definition at line 105 of file nsBlender.cpp.

Definition at line 104 of file nsBlender.cpp.

#define MAKE16 (   r,
  g,
  b 
)
Value:

Definition at line 726 of file nsBlender.cpp.

#define RED16 (   x)    (((x) & BLEND_RED_MASK) >> BLEND_RED_SHIFT)

Definition at line 103 of file nsBlender.cpp.


Function Documentation

static void Do8Blend ( float  aOpacity,
PRInt32  aNumLines,
PRInt32  aNumBytes,
PRUint8 aSImage,
PRUint8 aS2Image,
PRUint8 aDImage,
PRInt32  aSLSpan,
PRInt32  aDLSpan 
) [static]

This is a simple case for 8-bit blending.

We treat the opacity as binary.

Definition at line 413 of file nsBlender.cpp.

{
  if (aOpacity <= 0.0) {
    return;
  }

  // OK, just do an opaque blend. Assume the rendered image had just
  // 1-bit alpha.
  PRIntn y;
  if (!aS2Image) {
    for (y = 0; y < aNumLines; y++) {
      memcpy(aDImage, aSImage, aNumBytes);
      aSImage += aSLSpan;
      aDImage += aDLSpan;
    }
  } else {
    for (y = 0; y < aNumLines; y++) {
      for (int i = 0; i < aNumBytes; i++) {
        if (aSImage[i] == aS2Image[i]) {
          aDImage[i] = aSImage[i];
        }
      }
      aSImage += aSLSpan;
      aS2Image += aSLSpan;
      aDImage += aDLSpan;
    }
  }
}

Here is the call graph for this function:

static void DoSingleImageBlend ( PRUint32  aOpacity256,
PRInt32  aNumLines,
PRInt32  aNumBytes,
PRUint8 aSImage,
PRUint8 aDImage,
PRInt32  aSLSpan,
PRInt32  aDLSpan 
) [static]

This is the case where we have a single source buffer, all of whose pixels have an alpha value of 1.0.

Here's how to get the formula for calculating new destination pixels:

There's a destination pixel whose current color is D (0 <= D <= 255). We are required to find the new color value for the destination pixel, call it X. We are given S, the color value of the source pixel (0 <= S <= 255). We are also given P, the opacity to blend with (0 < P < 256).

Note that we have deliberately defined P's "opaque" range bound to be 256 and not 255. This considerably speeds up the code.

Then we have the equation X = D*(1 - P/256) + S*(P/256)

Rearranging gives X = D + ((S - D)*P)/256

This form minimizes the number of integer multiplications, which are much more expensive than shifts, adds and subtractions on most processors.

Definition at line 503 of file nsBlender.cpp.

{
  PRIntn y;

  for (y = 0; y < aNumLines; y++) {
    PRUint8 *s2 = aSImage;
    PRUint8 *d2 = aDImage;
    
    PRIntn i;
    for (i = 0; i < aNumBytes; i++) {
      PRUint32 destPix = *d2;
      
      *d2 = (PRUint8)(destPix + (((*s2 - destPix)*aOpacity256) >> 8));
      
      d2++;
      s2++;
    }
    
    aSImage += aSLSpan;
    aDImage += aDLSpan;
  }
}
static void rangeCheck ( nsIDrawingSurface surface,
PRInt32 aX,
PRInt32 aY,
PRInt32 aWidth,
PRInt32 aHeight 
) [static]

Definition at line 107 of file nsBlender.cpp.

{
  PRUint32 width, height;
  surface->GetDimensions(&width, &height);
  
  // ensure that the origin is within bounds of the drawing surface.
  if (aX < 0)
    aX = 0;
  else if (aX > (PRInt32)width)
    aX = width;
  if (aY < 0)
    aY = 0;
  else if (aY > (PRInt32)height)
    aY = height;
  
  // ensure that the dimensions are within bounds.
  if (aX + aWidth > (PRInt32)width)
    aWidth = width - aX;
  if (aY + aHeight > (PRInt32)height)
    aHeight = height - aY;
}

Here is the call graph for this function: