SkImageFilter.h revision 0456e0b7b85060e9b9597ce414c4c2b19aff4f58
1894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com/*
2894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Copyright 2011 Google Inc.
3894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com *
4894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Use of this source code is governed by a BSD-style license that can be
5894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * found in the LICENSE file.
6894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com */
7894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
8894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#ifndef SkImageFilter_DEFINED
9894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#define SkImageFilter_DEFINED
10894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
11894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#include "SkFlattenable.h"
12894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
1315356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comclass SkBitmap;
1476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.comclass SkDevice;
1515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comclass SkMatrix;
1615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comstruct SkPoint;
1715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com
1815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com/**
1915356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  Experimental.
2015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *
2115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  Base class for image filters. If one is installed in the paint, then
2215356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  all drawing occurs as usual, but it is as if the drawing happened into an
2315356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  offscreen (before the xfermode is applied). This offscreen bitmap will
2415356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  then be handed to the imagefilter, who in turn creates a new bitmap which
2515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  is what will finally be drawn to the device (using the original xfermode).
2615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *
2732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  THIS SIGNATURE IS TEMPORARY
2832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *
2932d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  There are several weaknesses in this function signature:
3032d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  1. Does not expose the destination/target device, so filters that can draw
3132d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *     directly to it are unable to take advantage of that optimization.
3232d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  2. Does not expose a way to create a "compabitible" image (i.e. gpu -> gpu)
3332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  3. As with #1, the filter is unable to "read" the dest (which would be slow)
3432d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *
3532d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  Therefore, we should not create any real dependencies on this API yet -- it
3632d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  is being checked in as a check-point so we can explore these and other
3732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com *  considerations.
3815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com */
3954e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.orgclass SK_API SkImageFilter : public SkFlattenable {
40894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.compublic:
410456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com    SK_DECLARE_INST_COUNT(SkImageFilter)
420456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com
4376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    class Proxy {
4476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    public:
458926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com        virtual ~Proxy() {};
468926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com
4776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        virtual SkDevice* createDevice(int width, int height) = 0;
488926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com        // returns true if the proxy can handle this filter natively
498926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com        virtual bool canHandleImageFilter(SkImageFilter*) = 0;
5076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        // returns true if the proxy handled the filter itself. if this returns
5176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        // false then the filter's code will be called.
5276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
5376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com                                 const SkMatrix& ctm,
5476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com                                 SkBitmap* result, SkIPoint* offset) = 0;
5576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    };
56894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
57894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com    /**
58894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  Request a new (result) image to be created from the src image.
59894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  If the src has no pixels (isNull()) then the request just wants to
60894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  receive the config and width/height of the result.
61894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *
62894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  The matrix is the current matrix on the canvas.
63894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *
64894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  Offset is the amount to translate the resulting image relative to the
65894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  src when it is drawn.
66894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *
67894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  If the result image cannot be created, return false, in which case both
68894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  the result and offset parameters will be ignored by the caller.
69894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     */
7076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm,
7115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com                     SkBitmap* result, SkIPoint* offset);
7215356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com
7315356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com    /**
7432d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com     *  Given the src bounds of an image, this returns the bounds of the result
7532d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com     *  image after the filter has been applied.
7632d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com     */
7732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst);
7832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
7932d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    /**
8015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com     *  Experimental.
8115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com     *
8215356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com     *  If the filter can be expressed as a gaussian-blur, return true and
8315356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com     *  set the sigma to the values for horizontal and vertical.
8415356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com     */
8515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com    virtual bool asABlur(SkSize* sigma) const;
86894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
8705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org    /**
8805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *  Experimental.
8905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *
9005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *  If the filter can be expressed as an erode, return true and
9105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *  set the radius in X and Y.
9205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     */
9305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org    virtual bool asAnErode(SkISize* radius) const;
9405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org
9505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org    /**
9605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *  Experimental.
9705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *
9805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *  If the filter can be expressed as a dilation, return true and
9905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     *  set the radius in X and Y.
10005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     */
10105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org    virtual bool asADilate(SkISize* radius) const;
10205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org
103894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.comprotected:
10454e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org    SkImageFilter() {}
10554e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org    explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
10632d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
10732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    // Default impl returns false
10876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
10915356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com                               SkBitmap* result, SkIPoint* offset);
11032d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    // Default impl copies src into dst and returns true
11132d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*);
112894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
113894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.comprivate:
11454e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org    typedef SkFlattenable INHERITED;
115894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com};
116894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
117894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#endif
118