already_AddRefed<Path>
nsSVGPathGeometryElement::GetOrBuildPath(const DrawTarget& aDrawTarget,
                                         FillRule aFillRule)
{
  // We only cache the path if it matches the backend used for screen painting:
  bool cacheable  = aDrawTarget.GetBackendType() ==
                    gfxPlatform::GetPlatform()->GetDefaultContentBackend();

  // Checking for and returning mCachedPath before checking the pref means
  // that the pref is only live on page reload (or app restart for SVG in
  // chrome). The benefit is that we avoid causing a CPU memory cache miss by
  // looking at the global variable that the pref's stored in.
  if (cacheable && mCachedPath) {
    if (aDrawTarget.GetBackendType() == mCachedPath->GetBackendType()) {
      RefPtr<Path> path(mCachedPath);
      return path.forget();
    }
  }
  RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder(aFillRule);
  RefPtr<Path> path = BuildPath(builder);
  if (cacheable && NS_SVGPathCachingEnabled()) {
    mCachedPath = path;
  }
  return path.forget();
}
static void
PaintCheckMark(nsIFrame* aFrame,
               nsRenderingContext* aCtx,
               const nsRect& aDirtyRect,
               nsPoint aPt)
{
  nsRect rect(aPt, aFrame->GetSize());
  rect.Deflate(aFrame->GetUsedBorderAndPadding());

  // Points come from the coordinates on a 7X7 unit box centered at 0,0
  const int32_t checkPolygonX[] = { -3, -1,  3,  3, -1, -3 };
  const int32_t checkPolygonY[] = { -1,  1, -3, -1,  3,  1 };
  const int32_t checkNumPoints = sizeof(checkPolygonX) / sizeof(int32_t);
  const int32_t checkSize      = 9; // 2 units of padding on either side
                                    // of the 7x7 unit checkmark

  // Scale the checkmark based on the smallest dimension
  nscoord paintScale = std::min(rect.width, rect.height) / checkSize;
  nsPoint paintCenter(rect.x + rect.width  / 2,
                      rect.y + rect.height / 2);

  DrawTarget* drawTarget = aCtx->GetDrawTarget();
  RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder();
  nsPoint p = paintCenter + nsPoint(checkPolygonX[0] * paintScale,
                                    checkPolygonY[0] * paintScale);

  int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
  builder->MoveTo(NSPointToPoint(p, appUnitsPerDevPixel));
  for (int32_t polyIndex = 1; polyIndex < checkNumPoints; polyIndex++) {
    p = paintCenter + nsPoint(checkPolygonX[polyIndex] * paintScale,
                              checkPolygonY[polyIndex] * paintScale);
    builder->LineTo(NSPointToPoint(p, appUnitsPerDevPixel));
  }
  RefPtr<Path> path = builder->Finish();
  drawTarget->Fill(path,
                   ColorPattern(ToDeviceColor(aFrame->StyleColor()->mColor)));
}