instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), surface);
instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), alpha);
nsSVGFilterFrame::FilterPaint(nsISVGRendererCanvas *aCanvas,                              nsISVGChildFrame *aTarget){  nsCOMPtr<nsIDOMSVGFilterElement> aFilter = do_QueryInterface(mContent);  NS_ASSERTION(aFilter, "Wrong content element (not filter)");  PRBool unimplementedFilter = PR_FALSE;  PRUint32 requirements = 0;  PRUint32 count = mContent->GetChildCount();  for (PRUint32 i=0; i<count; ++i) {    nsIContent* child = mContent->GetChildAt(i);    nsCOMPtr<nsISVGFilter> filter = do_QueryInterface(child);    if (filter) {      PRUint32 tmp;      filter->GetRequirements(&tmp);      requirements |= tmp;    }    nsCOMPtr<nsIDOMSVGFEUnimplementedMOZElement> unimplemented;    unimplemented = do_QueryInterface(child);    if (unimplemented)      unimplementedFilter = PR_TRUE;  }  // check for source requirements or filter elements that we don't support yet  if (requirements & ~(NS_FE_SOURCEGRAPHIC | NS_FE_SOURCEALPHA) ||      unimplementedFilter) {#ifdef DEBUG_tor    if (requirements & ~(NS_FE_SOURCEGRAPHIC | NS_FE_SOURCEALPHA))      fprintf(stderr, "FilterFrame: unimplemented source requirement\n");    if (unimplementedFilter)      fprintf(stderr, "FilterFrame: unimplemented filter element\n");#endif    nsRect dummyRect;    aTarget->PaintSVG(aCanvas, dummyRect, PR_TRUE);    return NS_OK;  }  nsCOMPtr<nsIDOMSVGMatrix> ctm;  nsISVGContainerFrame *aContainer;  CallQueryInterface(aTarget, &aContainer);  if (aContainer)    ctm = aContainer->GetCanvasTM();  else {    nsISVGGeometrySource *aSource;    CallQueryInterface(aTarget, &aSource);    if (aSource)      aSource->GetCanvasTM(getter_AddRefs(ctm));  }  float s1, s2;  ctm->GetA(&s1);  ctm->GetD(&s2);#ifdef DEBUG_tor  fprintf(stderr, "scales: %f %f\n", s1, s2);#endif  nsIFrame *frame;  CallQueryInterface(aTarget, &frame);  nsIContent *target = frame->GetContent();  aTarget->SetMatrixPropagation(PR_FALSE);  aTarget->NotifyCanvasTMChanged(PR_TRUE);  PRUint16 type;  mFilterUnits->GetAnimVal(&type);  float x, y, width, height;  nsCOMPtr<nsIDOMSVGRect> bbox;  aTarget->GetBBox(getter_AddRefs(bbox));  if (type == nsIDOMSVGFilterElement::SVG_FUNITS_OBJECTBOUNDINGBOX) {    bbox->GetX(&x);    x += nsSVGUtils::ObjectSpace(bbox, mX, nsSVGUtils::X);    bbox->GetY(&y);    y += nsSVGUtils::ObjectSpace(bbox, mY, nsSVGUtils::Y);    width = nsSVGUtils::ObjectSpace(bbox, mWidth, nsSVGUtils::X);    height = nsSVGUtils::ObjectSpace(bbox, mHeight, nsSVGUtils::Y);  } else {    x = nsSVGUtils::UserSpace(target, mX, nsSVGUtils::X);    y = nsSVGUtils::UserSpace(target, mY, nsSVGUtils::Y);    width = nsSVGUtils::UserSpace(target, mWidth, nsSVGUtils::X);    height = nsSVGUtils::UserSpace(target, mHeight, nsSVGUtils::Y);  }    PRInt32 filterResX = PRInt32(s1 * width + 0.5);  PRInt32 filterResY = PRInt32(s2 * height + 0.5);  if (mContent->HasAttr(kNameSpaceID_None, nsSVGAtoms::filterRes)) {    mFilterResX->GetAnimVal(&filterResX);    mFilterResY->GetAnimVal(&filterResY);  }  // filterRes = 0 disables rendering, < 0 is error  if (filterResX <= 0.0f || filterResY <= 0.0f)    return NS_OK;#ifdef DEBUG_tor  fprintf(stderr, "filter bbox: %f,%f  %fx%f\n", x, y, width, height);  fprintf(stderr, "filterRes: %u %u\n", filterResX, filterResY);#endif  nsCOMPtr<nsIDOMSVGMatrix> filterTransform;  NS_NewSVGMatrix(getter_AddRefs(filterTransform),                  filterResX/width,  0.0f,                  0.0f,              filterResY/height,                  -x*filterResX/width,                 -y*filterResY/height);  aTarget->SetOverrideCTM(filterTransform);  aTarget->NotifyCanvasTMChanged(PR_TRUE);  // paint the target geometry  nsISVGOuterSVGFrame* outerSVGFrame = GetOuterSVGFrame();  nsCOMPtr<nsISVGRenderer> renderer;  nsCOMPtr<nsISVGRendererSurface> surface;  outerSVGFrame->GetRenderer(getter_AddRefs(renderer));  renderer->CreateSurface(filterResX, filterResY, getter_AddRefs(surface));  if (!surface) {    FilterFailCleanup(aCanvas, aTarget);    return NS_OK;  }  aCanvas->PushSurface(surface);  nsRect dummyRect;  aTarget->PaintSVG(aCanvas, dummyRect, PR_TRUE);  aCanvas->PopSurface();  mPrimitiveUnits->GetAnimVal(&type);  nsSVGFilterInstance instance(renderer, target, bbox,                               x, y, width, height,                               filterResX, filterResY,                               type);  if (requirements & NS_FE_SOURCEALPHA) {    nsCOMPtr<nsISVGRendererSurface> alpha;    renderer->CreateSurface(filterResX, filterResY, getter_AddRefs(alpha));    if (!alpha) {      FilterFailCleanup(aCanvas, aTarget);      return NS_OK;    }    PRUint8 *data, *alphaData;    PRUint32 length;    PRInt32 stride;    surface->Lock();    alpha->Lock();    surface->GetData(&data, &length, &stride);    alpha->GetData(&alphaData, &length, &stride);    for (PRUint32 yy=0; yy<filterResY; yy++)      for (PRUint32 xx=0; xx<filterResX; xx++) {        alphaData[stride*yy + 4*xx]     = 0;        alphaData[stride*yy + 4*xx + 1] = 0;        alphaData[stride*yy + 4*xx + 2] = 0;        alphaData[stride*yy + 4*xx + 3] = data[stride*yy + 4*xx + 3];    }    surface->Unlock();    alpha->Unlock();    instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), surface);    instance.DefineRegion(NS_LITERAL_STRING("SourceAlpha"),                           nsRect(0, 0, filterResX, filterResY));  }  // this always needs to be defined last because the default image  // for the first filter element is supposed to be SourceGraphic  instance.DefineImage(NS_LITERAL_STRING("SourceGraphic"), surface);  instance.DefineRegion(NS_LITERAL_STRING("SourceGraphic"),                         nsRect(0, 0, filterResX, filterResY));  for (PRUint32 k=0; k<count; ++k) {    nsresult rv;    nsIContent* child = mContent->GetChildAt(k);    nsCOMPtr<nsISVGFilter> filter = do_QueryInterface(child);    if (filter)      rv = filter->Filter(&instance);    if (NS_FAILED(rv)) {      FilterFailCleanup(aCanvas, aTarget);      return NS_OK;    }  }  nsCOMPtr<nsISVGRendererSurface> filterResult;  instance.LookupImage(NS_LITERAL_STRING(""), getter_AddRefs(filterResult));  nsCOMPtr<nsIDOMSVGMatrix> scale, fini;  NS_NewSVGMatrix(getter_AddRefs(scale),                  width/filterResX, 0.0f,                  0.0f, height/filterResY,                  x, y);  ctm->Multiply(scale, getter_AddRefs(fini));  aCanvas->CompositeSurfaceMatrix(filterResult, fini, 1.0);  aTarget->SetOverrideCTM(nsnull);  aTarget->SetMatrixPropagation(PR_TRUE);  aTarget->NotifyCanvasTMChanged(PR_TRUE);  return NS_OK;}