Back to index

lightning-sunbird  0.9+nobinonly
Classes | Functions
nsSVGCairoCanvas.cpp File Reference
#include "nsCOMPtr.h"
#include "nsSVGCairoCanvas.h"
#include "nsISVGCairoCanvas.h"
#include "nsIDOMSVGMatrix.h"
#include "nsIRenderingContext.h"
#include "nsIDeviceContext.h"
#include "nsTransform2D.h"
#include "nsPresContext.h"
#include "nsRect.h"
#include "nsISVGCairoSurface.h"
#include "cairo.h"
#include "nsIImage.h"
#include "nsIComponentManager.h"
#include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsRenderingContextGTK.h"
#include <gdk/gdkx.h>

Go to the source code of this file.

Classes

class  nsSVGCairoCanvas
 Cairo canvas implementation. More...

Functions

nsresult NS_NewSVGCairoCanvas (nsISVGRendererCanvas **result, nsIRenderingContext *ctx, nsPresContext *presContext, const nsRect &dirtyRect)
static nsresult CopyCairoImageToIImage (PRUint8 *aData, PRInt32 aWidth, PRInt32 aHeight, gfxIImageFrame *aImage)

Function Documentation

static nsresult CopyCairoImageToIImage ( PRUint8 aData,
PRInt32  aWidth,
PRInt32  aHeight,
gfxIImageFrame aImage 
) [static]

Definition at line 446 of file nsSVGCairoCanvas.cpp.

{
  PRUint8 *alphaBits, *rgbBits;
  PRUint32 alphaLen, rgbLen;
  PRUint32 alphaStride, rgbStride;

  nsresult rv = aImage->LockImageData();
  if (NS_FAILED(rv)) {
    return rv;
  }

#ifndef XP_WIN
  rv = aImage->LockAlphaData();
  if (NS_FAILED(rv)) {
    aImage->UnlockImageData();
    return rv;
  }
#endif

  rv = aImage->GetImageBytesPerRow(&rgbStride);
  rv |= aImage->GetImageData(&rgbBits, &rgbLen);

#ifndef XP_WIN
  rv |= aImage->GetAlphaBytesPerRow(&alphaStride);
  rv |= aImage->GetAlphaData(&alphaBits, &alphaLen);
#endif

  if (NS_FAILED(rv)) {
    aImage->UnlockImageData();
#ifndef XP_WIN
    aImage->UnlockAlphaData();
#endif
    return rv;
  }

  nsCOMPtr<nsIImage> img(do_GetInterface(aImage));
  PRBool topToBottom = img->GetIsRowOrderTopToBottom();

  for (PRUint32 j = 0; j < (PRUint32) aHeight; j++) {
    PRUint8 *inrow = (PRUint8*)(aData + (aWidth * 4 * j));

    PRUint32 rowIndex;
    if (topToBottom)
      rowIndex = j;
    else
      rowIndex = aHeight - j - 1;

    PRUint8 *outrowrgb = rgbBits + (rgbStride * rowIndex);
#ifndef XP_WIN
    PRUint8 *outrowalpha = alphaBits + (alphaStride * rowIndex);
#endif

    for (PRUint32 i = 0; i < (PRUint32) aWidth; i++) {
#ifdef IS_LITTLE_ENDIAN
      PRUint8 b = *inrow++;
      PRUint8 g = *inrow++;
      PRUint8 r = *inrow++;
      PRUint8 a = *inrow++;
#else
      PRUint8 a = *inrow++;
      PRUint8 r = *inrow++;
      PRUint8 g = *inrow++;
      PRUint8 b = *inrow++;
#endif
      // now recover the real bgra from the cairo
      // premultiplied values
      if (a == 0) {
        // can't do much for us if we're at 0
        b = g = r = 0;
      } else {
        // the (a/2) factor is a bias similar to one cairo applies
        // when premultiplying
        b = (b * 255 + a / 2) / a;
        g = (g * 255 + a / 2) / a;
        r = (r * 255 + a / 2) / a;
      }

#ifndef XP_WIN
      *outrowalpha++ = a;
#endif

#ifdef XP_MACOSX
      // On the mac, RGB_A8 is really RGBX_A8
      *outrowrgb++ = 0;
#endif

#if defined(XP_WIN) || defined(XP_OS2)
      // On windows, RGB_A8 is really BGR_A8.
      // in fact, BGR_A8 is also BGR_A8.
      // Preblend with white since win32 printing can't deal with RGBA
      MOZ_BLEND(*outrowrgb++, 255, b, (unsigned)a);
      MOZ_BLEND(*outrowrgb++, 255, g, (unsigned)a);
      MOZ_BLEND(*outrowrgb++, 255, r, (unsigned)a);
#else
      *outrowrgb++ = r;
      *outrowrgb++ = g;
      *outrowrgb++ = b;
#endif
    }
  }

#ifndef XP_WIN
  rv = aImage->UnlockAlphaData();
#else
  rv = NS_OK;
#endif

  rv |= aImage->UnlockImageData();
  if (NS_FAILED(rv))
    return rv;

  nsRect r(0, 0, aWidth, aHeight);
  img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
  return NS_OK;
}

Here is the call graph for this function:

nsresult NS_NewSVGCairoCanvas ( nsISVGRendererCanvas **  result,
nsIRenderingContext ctx,
nsPresContext presContext,
const nsRect dirtyRect 
)

Definition at line 363 of file nsSVGCairoCanvas.cpp.

{
  nsSVGCairoCanvas* pg = new nsSVGCairoCanvas();
  if (!pg) return NS_ERROR_OUT_OF_MEMORY;

  NS_ADDREF(pg);

  nsresult rv = pg->Init(ctx, presContext, dirtyRect);

  if (NS_FAILED(rv)) {
    NS_RELEASE(pg);
    return rv;
  }
  
  *result = pg;
  return rv;
}

Here is the call graph for this function: