DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef _MOZILLA_GFX_PATTERNHELPERS_H
#define _MOZILLA_GFX_PATTERNHELPERS_H

#include "mozilla/Alignment.h"
#include "mozilla/gfx/2D.h"

namespace mozilla {
namespace gfx {

/**
 * This class is used to allow general pattern creation functions to return
 * any type of pattern via an out-paramater without allocating a pattern
 * instance on the free-store (an instance of this class being created on the
 * stack before passing it in to the creation function). Without this class
 * writing pattern creation functions would be a pain since Pattern objects are
 * not reference counted, making lifetime management of instances created on
 * the free-store and returned from a creation function hazardous. Besides
 * that, in the case that ColorPattern's are expected to be common, it is
 * particularly desirable to avoid the overhead of allocating on the
 * free-store.
 */
class GeneralPattern
{
public:
  explicit GeneralPattern()
    : mPattern(nullptr)
  {}

  GeneralPattern(const GeneralPattern& aOther)
    : mPattern(nullptr)
  {}

  ~GeneralPattern() {
    if (mPattern) {
      mPattern->~Pattern();
    }
  }

  Pattern* Init(const Pattern& aPattern) {
    MOZ_ASSERT(!mPattern);
    switch (aPattern.GetType()) {
    case PatternType::COLOR:
      mPattern = new (mColorPattern.addr())
        ColorPattern(static_cast<const ColorPattern&>(aPattern));
      break;
    case PatternType::LINEAR_GRADIENT:
      mPattern = new (mLinearGradientPattern.addr())
        LinearGradientPattern(static_cast<const LinearGradientPattern&>(aPattern));
      break;
    case PatternType::RADIAL_GRADIENT:
      mPattern = new (mRadialGradientPattern.addr())
        RadialGradientPattern(static_cast<const RadialGradientPattern&>(aPattern));
      break;
    case PatternType::SURFACE:
      mPattern = new (mSurfacePattern.addr())
        SurfacePattern(static_cast<const SurfacePattern&>(aPattern));
      break;
    default:
      MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unknown pattern type");
    }
    return mPattern;
  }

  ColorPattern* InitColorPattern(const Color &aColor) {
    MOZ_ASSERT(!mPattern);
    mPattern = new (mColorPattern.addr()) ColorPattern(aColor);
    return mColorPattern.addr();
  }

  LinearGradientPattern* InitLinearGradientPattern(const Point &aBegin,
                                                   const Point &aEnd,
                                                   GradientStops *aStops,
                                                   const Matrix &aMatrix = Matrix()) {
    MOZ_ASSERT(!mPattern);
    mPattern = new (mLinearGradientPattern.addr())
      LinearGradientPattern(aBegin, aEnd, aStops, aMatrix);
    return mLinearGradientPattern.addr();
  }

  RadialGradientPattern* InitRadialGradientPattern(const Point &aCenter1,
                                                   const Point &aCenter2,
                                                   Float aRadius1,
                                                   Float aRadius2,
                                                   GradientStops *aStops,
                                                   const Matrix &aMatrix = Matrix()) {
    MOZ_ASSERT(!mPattern);
    mPattern = new (mRadialGradientPattern.addr())
      RadialGradientPattern(aCenter1, aCenter2, aRadius1, aRadius2, aStops, aMatrix);
    return mRadialGradientPattern.addr();
  }

  SurfacePattern* InitSurfacePattern(SourceSurface *aSourceSurface,
                                     ExtendMode aExtendMode,
                                     const Matrix &aMatrix = Matrix(),
                                     SamplingFilter aSamplingFilter = SamplingFilter::GOOD,
                                     const IntRect &aSamplingRect = IntRect()) {
    MOZ_ASSERT(!mPattern);
    mPattern = new (mSurfacePattern.addr())
      SurfacePattern(aSourceSurface, aExtendMode, aMatrix, aSamplingFilter, aSamplingRect);
    return mSurfacePattern.addr();
  }

  Pattern* GetPattern() {
    return mPattern;
  }

  const Pattern* GetPattern() const {
    return mPattern;
  }

  operator Pattern&() {
    if (!mPattern) {
      MOZ_CRASH("GFX: GeneralPattern not initialized");
    }
    return *mPattern;
  }

private:
  union {
    AlignedStorage2<ColorPattern> mColorPattern;
    AlignedStorage2<LinearGradientPattern> mLinearGradientPattern;
    AlignedStorage2<RadialGradientPattern> mRadialGradientPattern;
    AlignedStorage2<SurfacePattern> mSurfacePattern;
  };
  Pattern *mPattern;
};

} // namespace gfx
} // namespace mozilla

#endif //  _MOZILLA_GFX_PATTERNHELPERS_H