Blame layout/svg/nsSVGGradientFrame.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef __NS_SVGGRADIENTFRAME_H__
Packit f0b94e
#define __NS_SVGGRADIENTFRAME_H__
Packit f0b94e
Packit f0b94e
#include "mozilla/Attributes.h"
Packit f0b94e
#include "gfxMatrix.h"
Packit f0b94e
#include "gfxRect.h"
Packit f0b94e
#include "nsCOMPtr.h"
Packit f0b94e
#include "nsFrame.h"
Packit f0b94e
#include "nsLiteralString.h"
Packit f0b94e
#include "nsSVGPaintServerFrame.h"
Packit f0b94e
Packit f0b94e
class gfxPattern;
Packit f0b94e
class nsAtom;
Packit f0b94e
class nsIContent;
Packit f0b94e
class nsIFrame;
Packit f0b94e
class nsIPresShell;
Packit f0b94e
class nsStyleContext;
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
class nsSVGAnimatedTransformList;
Packit f0b94e
Packit f0b94e
namespace dom {
Packit f0b94e
class SVGLinearGradientElement;
Packit f0b94e
class SVGRadialGradientElement;
Packit f0b94e
}  // namespace dom
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * Gradients can refer to other gradients. We create an nsSVGPaintingProperty
Packit f0b94e
 * with property type nsGkAtoms::href to track the referenced gradient.
Packit f0b94e
 */
Packit f0b94e
class nsSVGGradientFrame : public nsSVGPaintServerFrame {
Packit f0b94e
  typedef mozilla::gfx::ExtendMode ExtendMode;
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  nsSVGGradientFrame(nsStyleContext* aContext, ClassID aID);
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  NS_DECL_ABSTRACT_FRAME(nsSVGGradientFrame)
Packit f0b94e
Packit f0b94e
  // nsSVGPaintServerFrame methods:
Packit f0b94e
  virtual already_AddRefed<gfxPattern> GetPaintServerPattern(
Packit f0b94e
      nsIFrame* aSource, const DrawTarget* aDrawTarget,
Packit f0b94e
      const gfxMatrix& aContextMatrix,
Packit f0b94e
      nsStyleSVGPaint nsStyleSVG::*aFillOrStroke, float aOpacity,
Packit f0b94e
      imgDrawingParams& aImgParams, const gfxRect* aOverrideBounds) override;
Packit f0b94e
Packit f0b94e
  // nsIFrame interface:
Packit f0b94e
  virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
Packit f0b94e
                                    int32_t aModType) override;
Packit f0b94e
Packit f0b94e
#ifdef DEBUG_FRAME_DUMP
Packit f0b94e
  virtual nsresult GetFrameName(nsAString& aResult) const override {
Packit f0b94e
    return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult);
Packit f0b94e
  }
Packit f0b94e
#endif  // DEBUG
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  // Parse our xlink:href and set up our nsSVGPaintingProperty if we
Packit f0b94e
  // reference another gradient and we don't have a property. Return
Packit f0b94e
  // the referenced gradient's frame if available, null otherwise.
Packit f0b94e
  nsSVGGradientFrame* GetReferencedGradient();
Packit f0b94e
Packit f0b94e
  // Optionally get a stop frame (returns stop index/count)
Packit f0b94e
  void GetStopFrames(nsTArray<nsIFrame*>* aStopFrames);
Packit f0b94e
Packit f0b94e
  const mozilla::nsSVGAnimatedTransformList* GetGradientTransformList(
Packit f0b94e
      nsIContent* aDefault);
Packit f0b94e
  // Will be singular for gradientUnits="objectBoundingBox" with an empty bbox.
Packit f0b94e
  gfxMatrix GetGradientTransform(nsIFrame* aSource,
Packit f0b94e
                                 const gfxRect* aOverrideBounds);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  virtual bool GradientVectorLengthIsZero() = 0;
Packit f0b94e
  virtual already_AddRefed<gfxPattern> CreateGradient() = 0;
Packit f0b94e
Packit f0b94e
  // Accessors to lookup gradient attributes
Packit f0b94e
  uint16_t GetEnumValue(uint32_t aIndex, nsIContent* aDefault);
Packit f0b94e
  uint16_t GetEnumValue(uint32_t aIndex) {
Packit f0b94e
    return GetEnumValue(aIndex, mContent);
Packit f0b94e
  }
Packit f0b94e
  uint16_t GetGradientUnits();
Packit f0b94e
  uint16_t GetSpreadMethod();
Packit f0b94e
Packit f0b94e
  // Gradient-type-specific lookups since the length values differ between
Packit f0b94e
  // linear and radial gradients
Packit f0b94e
  virtual mozilla::dom::SVGLinearGradientElement* GetLinearGradientWithLength(
Packit f0b94e
      uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault);
Packit f0b94e
  virtual mozilla::dom::SVGRadialGradientElement* GetRadialGradientWithLength(
Packit f0b94e
      uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault);
Packit f0b94e
Packit f0b94e
  // The frame our gradient is (currently) being applied to
Packit f0b94e
  nsIFrame* mSource;
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  // Flag to mark this frame as "in use" during recursive calls along our
Packit f0b94e
  // gradient's reference chain so we can detect reference loops. See:
Packit f0b94e
  // http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute
Packit f0b94e
  bool mLoopFlag;
Packit f0b94e
  // Gradients often don't reference other gradients, so here we cache
Packit f0b94e
  // the fact that that isn't happening.
Packit f0b94e
  bool mNoHRefURI;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
// -------------------------------------------------------------------------
Packit f0b94e
// Linear Gradients
Packit f0b94e
// -------------------------------------------------------------------------
Packit f0b94e
Packit f0b94e
class nsSVGLinearGradientFrame : public nsSVGGradientFrame {
Packit f0b94e
  friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
Packit f0b94e
                                                nsStyleContext* aContext);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  explicit nsSVGLinearGradientFrame(nsStyleContext* aContext)
Packit f0b94e
      : nsSVGGradientFrame(aContext, kClassID) {}
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  NS_DECL_FRAMEARENA_HELPERS(nsSVGLinearGradientFrame)
Packit f0b94e
Packit f0b94e
  // nsIFrame interface:
Packit f0b94e
#ifdef DEBUG
Packit f0b94e
  virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
Packit f0b94e
                    nsIFrame* aPrevInFlow) override;
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
  virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
Packit f0b94e
                                    int32_t aModType) override;
Packit f0b94e
Packit f0b94e
#ifdef DEBUG_FRAME_DUMP
Packit f0b94e
  virtual nsresult GetFrameName(nsAString& aResult) const override {
Packit f0b94e
    return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult);
Packit f0b94e
  }
Packit f0b94e
#endif  // DEBUG
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  float GetLengthValue(uint32_t aIndex);
Packit f0b94e
  virtual mozilla::dom::SVGLinearGradientElement* GetLinearGradientWithLength(
Packit f0b94e
      uint32_t aIndex,
Packit f0b94e
      mozilla::dom::SVGLinearGradientElement* aDefault) override;
Packit f0b94e
  virtual bool GradientVectorLengthIsZero() override;
Packit f0b94e
  virtual already_AddRefed<gfxPattern> CreateGradient() override;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
// -------------------------------------------------------------------------
Packit f0b94e
// Radial Gradients
Packit f0b94e
// -------------------------------------------------------------------------
Packit f0b94e
Packit f0b94e
class nsSVGRadialGradientFrame : public nsSVGGradientFrame {
Packit f0b94e
  friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
Packit f0b94e
                                                nsStyleContext* aContext);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  explicit nsSVGRadialGradientFrame(nsStyleContext* aContext)
Packit f0b94e
      : nsSVGGradientFrame(aContext, kClassID) {}
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  NS_DECL_FRAMEARENA_HELPERS(nsSVGRadialGradientFrame)
Packit f0b94e
Packit f0b94e
  // nsIFrame interface:
Packit f0b94e
#ifdef DEBUG
Packit f0b94e
  virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
Packit f0b94e
                    nsIFrame* aPrevInFlow) override;
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
  virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
Packit f0b94e
                                    int32_t aModType) override;
Packit f0b94e
Packit f0b94e
#ifdef DEBUG_FRAME_DUMP
Packit f0b94e
  virtual nsresult GetFrameName(nsAString& aResult) const override {
Packit f0b94e
    return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult);
Packit f0b94e
  }
Packit f0b94e
#endif  // DEBUG
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  float GetLengthValue(uint32_t aIndex);
Packit f0b94e
  float GetLengthValue(uint32_t aIndex, float aDefaultValue);
Packit f0b94e
  float GetLengthValueFromElement(
Packit f0b94e
      uint32_t aIndex, mozilla::dom::SVGRadialGradientElement& aElement);
Packit f0b94e
  virtual mozilla::dom::SVGRadialGradientElement* GetRadialGradientWithLength(
Packit f0b94e
      uint32_t aIndex,
Packit f0b94e
      mozilla::dom::SVGRadialGradientElement* aDefault) override;
Packit f0b94e
  virtual bool GradientVectorLengthIsZero() override;
Packit f0b94e
  virtual already_AddRefed<gfxPattern> CreateGradient() override;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
#endif  // __NS_SVGGRADIENTFRAME_H__