GetGlobalTransform(ctx, nsnull);
if (NS_FAILED(GetGlobalTransform(ctx, nsnull))) { cairo_destroy(ctx); return NS_ERROR_FAILURE; }
nsSVGCairoGlyphGeometry::GetCoveredRegion(nsISVGRendererRegion **_retval){  *_retval = nsnull;  cairo_t *ctx = cairo_create(gSVGCairoDummySurface);  /* get the metrics */  nsCOMPtr<nsISVGCairoGlyphMetrics> metrics;  {    nsCOMPtr<nsISVGRendererGlyphMetrics> xpmetrics;    mSource->GetMetrics(getter_AddRefs(xpmetrics));    metrics = do_QueryInterface(xpmetrics);    NS_ASSERTION(metrics, "wrong metrics object!");    if (!metrics)      return NS_ERROR_FAILURE;  }  GetGlobalTransform(ctx, nsnull);  metrics->SelectFont(ctx);  float x,y;  mSource->GetX(&x);  mSource->GetY(&y);  cairo_move_to(ctx, x, y);  PRUint16 type;    mSource->GetFillPaintType(&type);  PRBool hasCoveredFill = type != nsISVGGeometrySource::PAINT_TYPE_NONE;  mSource->GetStrokePaintType(&type);  bool hasCoveredStroke = type != nsISVGGeometrySource::PAINT_TYPE_NONE;  if (!hasCoveredFill && !hasCoveredStroke) return NS_OK;  nsAutoString text;  mSource->GetCharacterData(text);    if (text.Length() == 0) {    double xx = x, yy = y;    cairo_user_to_device(ctx, &xx, &yy);    cairo_destroy(ctx);    return NS_NewSVGCairoRectRegion(_retval, xx, yy, 0, 0);  }  nsSVGCharacterPosition *cp;  if (NS_FAILED(mSource->GetCharacterPosition(&cp))) {    cairo_destroy(ctx);    return NS_ERROR_FAILURE;  }  if (!cp) {    if (hasCoveredStroke) {      cairo_text_path(ctx, NS_ConvertUCS2toUTF8(text).get());    } else {      cairo_text_extents_t extent;      cairo_text_extents(ctx,                         NS_ConvertUCS2toUTF8(text).get(),                         &extent);      cairo_rectangle(ctx, x + extent.x_bearing, y + extent.y_bearing,                      extent.width, extent.height);    }  } else {    cairo_matrix_t matrix;    for (PRUint32 i=0; i<text.Length(); i++) {      cairo_get_matrix(ctx, &matrix);      cairo_move_to(ctx, cp[i].x, cp[i].y);      cairo_rotate(ctx, cp[i].angle);      if (hasCoveredStroke) {        cairo_text_path(ctx, NS_ConvertUCS2toUTF8(Substring(text, i, 1)).get());      } else {        cairo_text_extents_t extent;        cairo_text_extents(ctx,                           NS_ConvertUCS2toUTF8(Substring(text, i, 1)).get(),                           &extent);        cairo_rel_move_to(ctx, extent.x_bearing, extent.y_bearing);        cairo_rel_line_to(ctx, extent.width, 0);        cairo_rel_line_to(ctx, 0, extent.height);        cairo_rel_line_to(ctx, -extent.width, 0);        cairo_close_path(ctx);      }      cairo_set_matrix(ctx, &matrix);    }  }  delete [] cp;  double xmin, ymin, xmax, ymax;  if (hasCoveredStroke) {    float width;    mSource->GetStrokeWidth(&width);    cairo_set_line_width(ctx, double(width));        PRUint16 capStyle;    mSource->GetStrokeLinecap(&capStyle);    switch (capStyle) {    case nsISVGGeometrySource::STROKE_LINECAP_BUTT:      cairo_set_line_cap(ctx, CAIRO_LINE_CAP_BUTT);      break;    case nsISVGGeometrySource::STROKE_LINECAP_ROUND:      cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND);      break;    case nsISVGGeometrySource::STROKE_LINECAP_SQUARE:      cairo_set_line_cap(ctx, CAIRO_LINE_CAP_SQUARE);      break;    }        float miterlimit;    mSource->GetStrokeMiterlimit(&miterlimit);    cairo_set_miter_limit(ctx, double(miterlimit));        PRUint16 joinStyle;    mSource->GetStrokeLinejoin(&joinStyle);    switch(joinStyle) {    case nsISVGGeometrySource::STROKE_LINEJOIN_MITER:      cairo_set_line_join(ctx, CAIRO_LINE_JOIN_MITER);      break;    case nsISVGGeometrySource::STROKE_LINEJOIN_ROUND:      cairo_set_line_join(ctx, CAIRO_LINE_JOIN_ROUND);      break;    case nsISVGGeometrySource::STROKE_LINEJOIN_BEVEL:      cairo_set_line_join(ctx, CAIRO_LINE_JOIN_BEVEL);      break;    }        cairo_stroke_extents(ctx, &xmin, &ymin, &xmax, &ymax);  } else {    cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax);  }  cairo_user_to_device(ctx, &xmin, &ymin);  cairo_user_to_device(ctx, &xmax, &ymax);  cairo_destroy(ctx);  return NS_NewSVGCairoRectRegion(_retval, xmin, ymin, xmax-xmin, ymax-ymin);}