Evas filters reference

Apply inverse color TODO: write down more information

Remove color information from buffer's contents and leave only grayscale TODO: write down more information

This section will present the various filter instructions, their syntax and their effects.

Warning
  A new online documentation is available on the Wiki under EFL Graphics Filters. The documentation below is mostly still valid but incomplete. This page may be removed in the future.

The Evas filters are a combination of filters used to apply specific effects to an Evas Object. For the moment, these effects are specific to the Text and Image Objects.

The filters can be applied to an object using simple Lua scripts. A script will contain a series of buffer declarations and filter commands to apply to these buffers. The Lua programming language reference can be found here.

Basically, when applying an effect to a Text Object, an alpha-only `input` buffer is created, where the text is rendered, and an RGBA `output` buffer is created, where the text with effects shall be finally rendered.

The script language being Lua, it respects the usual Lua syntax and concepts. As these are simple filters, the scripts should be kept as small and simple as possible.

Note: Lua has been used since 1.10. The previous filters syntax is not guaranteed to be compatible with 1.10 and newer versions.

Here are the available commands:

- Syntax
- Buffer management
  - Colorspaces
  - Automatic buffers
  - `buffer` command
- Commands
  - `blend` command
  - `blur` command
  - `grow` command
  - `curve` command
  - `fill` command
  - `mask` command
  - `bump` command
  - `displace` command
  - `transform` command

All the examples in this page can (should) be directly used in evas_obj_text_filter_program_set.

Note that most of the text effects work better with larger font sizes (> 50px), and so do the examples in this page (embedded devices in mind).

# Syntax

Here is a simple example illustrating the syntax:

    fat = buffer ('alpha')
    grow ({ 8, dst = fat })
    blur ({ 12, src = fat, color = 'darkblue' })
    blur ({ 4, color = 'cyan' })
    blend ()

This example will display a cyan and dark blue glow surrounding the main text (its color depends on the object's theme).

The syntax is pretty simple and follows a small set of rules:

- All dimensions are in pixels
- The commands will be executed in sequential order
- Most commands have default values
- A command argument can either be set by name, or sequentially omitting the name. So that:

      function (arg1, arg2, arg3)

- is equivalent to:

      function ({ arg1, arg2, arg2 })

- or even (considering opt1, opt2 and opt3 are the first 3 arguments):

      function ({ opt1 = arg1, opt2 = arg2, opt3 = arg3 })

- and since this is Lua, we can also write it as:

      function { arg1, opt3 = arg3, opt2 = arg2 }

- Boolean values are `true/`false` but` 1/0 and special string values are also accepted: 'yes'/'no', 'enabled'/'disabled'

### Special keywords and their values

Some options accept a certain set of values (like enums):

- `color`
  - Colors can be referred to by strings or integers:
  - An integer can refer to any RGB or ARGB values: `0xRRGGBB` or `0xAARRGGBB`. If alpha is zero, the color will be opaque (alpha = `0xFF`), unless R=G=B=0 (invisible). These colors are not premultiplied.
  - Hexadecimal values: `'#RRGGBB'`, `'#RRGGBBAA'`, `'#RGB'`, `'#RGBA'`
  - The following string values are also accepted:
    - 'white' == '#FFFFFF'
    - 'black' == '#000000'
    - 'red' == '#FF0000'
    - 'green' == '#008000'
    - 'blue' == '#0000FF'
    - 'darkblue' == '#0000A0'
    - 'yellow' == '#FFFF00'
    - 'magenta' == '#FF00FF'
    - 'cyan' == '#00FFFF'
    - 'orange' == '#FFA500'
    - 'purple' == '#800080'
    - 'brown' == '#A52A2A'
    - 'maroon' == '#800000'
    - 'lime' == '#00FF00'
    - 'gray' == '#808080'
    - 'grey' == '#808080'
    - 'silver' == '#C0C0C0'
    - 'olive' == '#808000'
    - 'invisible', 'transparent' == '#0000' – (alpha is zero)
- `fillmode`
  - 'none'
  - 'stretch_x'
  - 'stretch_y'
  - 'repeat_x'
  - 'repeat_y'
  - 'repeat_x_stretch_y', 'stretch_y_repeat_x'
  - 'repeat_y_stretch_x', 'stretch_x_repeat_y'
  - 'repeat', 'repeat_xy'
  - 'stretch', 'stretch_xy'

# Buffer management

The Evas filters subsystem is based on the concept of using various buffers as image layers and drawing or applying filters to these buffers. Think of it as how image drawing tools like The Gimp can combine multiple layers and apply operations on them.

Most of the buffers are allocated automatically at runtime, depending on the various inputs and commands used (eg. 2-D blur will require a temporary intermediate buffer).

## Colorspaces and size

The buffers' size will be automatically defined at runtime, based on the content of the input and the series of operations to apply (eg. blur adds some necessary margins).

The buffers can be either ALPHA (1 color channel only) or RGBA (full color). Some operations might require specifically an ALPHA buffer, some others RGBA.

Most buffers will have the same size, except those specified by an external source.

## Automatic buffers

The two most important buffers, input and output, are statically defined and always present when running a filter. input is an ALPHA buffer, containing the Text Object's rendered text, and output is the final target on which to render as RGBA.

Some operations, like 2-D blur might require temporary intermediate buffers, that will be allocated automatically. Those buffers are internal only and can't be used from the script.

Finally, if a buffer is created using another Evas Object as source (see buffer for more details), its pixel data will be filled by rendering the Evas Object into this buffer. This is how it will be possible to load external images, textures and even animations into a buffer.

Since
  1.9

## Buffer command

Create a new buffer.

    name1 = buffer()
    name2 = buffer("alpha")
    name3 = buffer("rgba")
    name4 = buffer({ type = "rgba" })
    name5 = buffer({ src = "partname" })

Parameters

  type | Buffer type: `rgba` (default) or `alpha`
  src | An optional source. If set, type will be `rgba`.

Returns
  A new buffer. This value must not be saved to a variable.

This creates a new named buffer, specify its colorspace or source. Possible options:

- `alpha:` Create an alpha-only buffer (1 channel, no color)
- `rgba:` Create an RGBA buffer (4 channels, full color)
- {src = "partname"}: Use another Evas Object as source for this buffer's pixels. The name can either be an Edje part name or the one specified in `evas_obj_text_filter_source_set`.

If no option is given, an RGBA buffer will be created. All buffers have the same size, unless they are based on an external source.

See also
  evas_obj_text_filter_source_set

Since
  1.10

# Filter commands

## Blend

Blend a buffer onto another. This is the simplest filter, as it just renders one buffer on another, potentially using a color, an offset and fill options.

    blend ({ src = input, dst = output, ox = 0, oy = 0, color = 'white', fillmode = 'none' })

Parameters

  src | Source buffer to blend.
  dst | Destination buffer for blending.
  ox | X offset. Moves the buffer to the right (ox > 0) or to the left (ox < 0) by N pixels.
  oy | Y offset. Moves the buffer to the bottom (oy > 0) or to the top (oy < 0) by N pixels.
  color | A color to use for alpha to RGBA conversion. See colors. If the input is an alpha buffer and the output is RGBA, this will draw the buffer in this color. If both buffers are RGBA, this will have no effect.
  fillmode | Map the input onto the whole surface of the output by stretching or repeating it. See fillmodes.
  alphaonly | If true, this means all RGBA->Alpha conversions discard the RGB components entirely, and only use the Alpha channel. False by default, which means RGB is used as Grey color level.

If src is an alpha buffer and dst is an RGBA buffer, then the color option should be set.

    blend ({ color = '#3399FF' })

Since
  1.9

## Blur

Apply blur effect on a buffer (box or gaussian).

    blur ({ rx = 3, ry = nil, type = 'default', ox = 0, oy = 0, color = 'white', src = input, dst = output })

Parameters

  rx | X radius. Specifies the radius of the blurring kernel (X direction).
  ry | Y radius. Specifies the radius of the blurring kernel (Y direction). If -1 is used, then ry = rx.
  type | Blur type to apply. One of `default`, `box` or `gaussian`. See below for details about `default`.
  ox | X offset. Moves the buffer to the right (ox > 0) or to the left (ox < 0) by N pixels.
  oy | Y offset. Moves the buffer to the bottom (oy > 0) or to the top (oy < 0) by N pixels.
  color | A color to use for alpha to RGBA conversion. See colors. If the input is an alpha buffer and the output is RGBA, this will draw the buffer in this color.
  src | Source buffer to blur.
  dst | Destination buffer for blending.
  count | Number of times to repeat the blur. Only valid with `box` blur. Valid range is: 1 to 6.

The blur type `default` is recommended in all situations as it will select the smoothest and fastest operation possible depending on the kernel size. Instead of running a real gaussian blur, 2 or 3 box blurs may be chained to produce a similar effect at a much higher speed. The value count can be set to a value from 1 to 6 if blur type `box` has been specified.

The speedups of `box` over `gaussian` are of orders of 4x to more than 20x faster.

If src is an alpha buffer and dst is an RGBA buffer, then the color option should be set.

ox and oy can be used to move the blurry output by a few pixels, like a drop shadow. Example:

    blur ({ 10, color = 'black', oy = 5, ox = 5 })
    blend ({ color = '#3399FF' })

Since
  1.9

## Bump

Apply a light effect (ambient light, specular reflection and shadows) based on a bump map.

This can be used to give a relief effect on the object.

    bump ({ map, azimuth = 135.0, elevation = 45.0, depth = 8.0, specular = 0.0,
            color = 'white', compensate = false, src = input, dst = output,
            black = 'black', white = 'white', fillmode = 'repeat' })

Parameters

  map | An alpha buffer treated like a Z map for the light effect (bump map). Must be specified.
  azimuth | The angle between the light vector and the X axis in the XY plane (Z = 0). 135.0 means 45 degrees from the top-left. Counter-clockwise notation.
  elevation | The angle between the light vector and the Z axis. 45.0 means 45 degrees to the screen's plane. Ranges from 0 to 90 only.
  depth | The depth of the object in an arbitrary unit. More depth means the shadows will be stronger. Default is 8.0.
  specular | An arbitrary unit for the specular light effect. Default is 0.0, but a common value would be 40.0.
  color | The main color of the object if src is an alpha buffer. This represents the light's normal color. See colors.
  compensate | If set to true, compensate for whitening or darkening on flat surfaces. Default is false but it is recommended if specular light is wanted.
  src | Source buffer. This should be an alpha buffer.
  dst | Destination buffer. This should be an RGBA buffer (although alpha is supported). Must be of the same size as src.
  black | The shadows' color. Usually this will be black (`#000`).
  white | The specular light's color. Usually this will be white (`#FFF`).
  fillmode | This specifies how to handle map when its dimensions don't match those of src and dst. Default is to `repeat`. See fillmodes.

Note
  As of 2014/02/11, the ALPHA to RGBA support is of much better quality than ALPHA only, but very slow. RGBA sources are not supported yet.

Here is a full example of a very simple bevel effect:

    a = buffer ('alpha')
    blur ({ 5, dst = a })
    bump ({ map = a, compensate = true, color = '#3399FF', specular = 10.0 })

Since
  1.9

## Curve

Apply a color curve to a specific channel in a buffer.

    curve ({ points, interpolation = 'linear', channel = 'rgb', src = input, dst = output })

Modify the colors of a buffer. This applies a color curve y = f(x) to every pixel.

Parameters

  points | The color curve to apply. See below for the syntax.
  interpolation | How to interpolate between points. One of `linear` (y = ax + b) or `none` (y = Yk).
  channel | Target channel for the color modification. One of `R(ed)`, `G(reen)`, `B(lue)`, `A(lpha)`, `RGB` and `RGBA`. If src is an alpha buffer, this parameter will be ignored.
  src | Source buffer.
  dst | Destination buffer, must be of same dimensions and color space as src.

The points argument contains a list of (X,Y) points in the range 0..255, describing a function f(x) = y to apply to all pixel values.

The syntax of this points string is 'x1:y1 - x2:y2 - x3:y3 - ... - xn:yn' (remember that all spaces are discarded). The points `xn` are in increasing order: x1 < x2 < x3 < ... < xn, and all values `xn` or `yn` are within the range 0..255.

The identity curve is then described as '0:0-255:255', with linear interpolation:

    curve ({ points = '0:0 - 255:255', interpolation = linear })

If ignored, y(x = 0) is 0 and y(x = 255) is 255.

The following example will generate a 4px thick stroke around text letters:

    a = buffer ('alpha')
    blur ({ 4, dst = a })
    curve ({ points = '0:0 - 20:0 - 60:255 - 160:255 - 200:0 - 255:0', src = a, dst = a })
    blend ({ src = a, color = 'black' })

The curve command can be used to alter the output of a blur operation.

Since
  1.9

## Displace

Apply a displacement map on a buffer.

    displace ({ map, intensity = 10, flags = 0, src = input, dst = output, fillmode = 'repeat' })

Parameters

  map | An RGBA buffer containing a displacement map. See below for more details.
  intensity | Maximum distance for the displacement. This means 0 and 255 will represent a displacement of `intensity` pixels.
  flags | One of `default`, `nearest`, `smooth`, `nearest_stretch` or `smooth_stretch`. This defines how pixels should be treated when going out of the src image bounds. `default` is equivalent to `smooth_stretch`.
  src | Source buffer
  dst | Destination buffer. Must be of same color format and size as src.
  fillmode | Defines how to handle cases where the map has a different size from src and dst. It should be a combination of `stretch` or `repeat:` `none` is not supported. See fillmodes.

### Displacement map

The map buffer is an RGBA image containing displacement and alpha values. Its size can be different from `src` or `dst`.

The red channel is used for X displacements while the green channel is used for Y displacements. All subpixel values are in the range 0..255. A value of 128 means 0 displacement, lower means displace to the top/left and higher than 128 displace to the bottom/right.

If signed char is used instead of unsigned char to represent these R and G values, then < 0 means displace top/left while > 0 means bottom/right.

The `alpha` channel is used as an alpha multiplier for blending.

Considering I(x, y) represents the pixel at position (x, y) in the image I, then here is how the displacement is applied to dst:

    D = map (x, y)
    dst (x, y) = D.alpha * src (x + (D.red - 128) * intensity / 128, y + (D.green - 128) * intensity / 128) / 255 + (255 - D.alpha) * dst (x, y) / 255

Of course, the real algorithm takes into account interpolation between pixels as well.

Since
  1.9

## Fill

Fill a buffer with a specific color. Not blending, can be used to clear a buffer.

    fill ({ dst = output, color = 'transparent', l = 0, r = 0, t = 0, b = 0 })

Parameters

  dst | Target buffer to fill with color.
  color | The color used to fill the buffer. All pixels within the fill area will be reset to this value. See colors.
  l | Left padding: skip l pixels from the left border of the buffer
  r | Right padding: skip r pixels from the right border of the buffer
  t | Top padding: skip t pixels from the top border of the buffer
  b | Bottom padding: skip b pixels from the bottom border of the buffer

This function should generally not be used, except for:

- Testing an effect over a specific background color
- Clearing out a buffer with either white or transparent color

Since
  1.9

## Grow

Grow or shrink a buffer's contents. This is not a zoom effect.

    grow ({ radius, smooth = true, src = input, dst = output })

Parameters

  radius | The radius of the grow kernel. If a negative value is specified, the contents will shrink rather than grow.
  smooth | If `true`, use a smooth transitions between black and white (smooth blur and smoother curve).
  src | Source buffer to blur.
  dst | Destination buffer for blending. This must be of same size and colorspace as src.

Example:

    fat = buffer ('alpha')
    grow ({ 8, dst = fat })
    blend ({ src = fat, color = 'black' })
    blend ({ color = '#3399FF' })

This will first grow the letters in the buffer `input` by a few pixels, and then draw this buffer in black in the background.

Since
  1.9

## Mask

Blend two input buffers into a third (target).

    mask ({ mask, src = input, dst = output, color = 'white', fillmode = 'repeat' })

Parameters

  mask | A mask or texture to blend with the input src into the target dst.
  src | Source buffer. This can also be thought of a mask if src is alpha and mask is RGBA.
  dst | Destination buffer for blending. This must be of same size and colorspace as src.
  color | A color to use for alpha to RGBA conversion for the blend operations. White means no change. See colors. This will have no effect on RGBA sources.
  fillmode | Defines whether to stretch or repeat the mask if its size that of `src`. Should be set when masking with external textures. Default is repeat. See fillmodes.

Note that src and mask are interchangeable, if they have the same dimensions.

Example:

    a = buffer ('alpha')
    blur ({ 6, dst = a })
    curve ({ points = '0:255 - 128:255 - 255:0', src = a, dst = a })
    blend ({ color = 'yellow' })
    mask ({ mask = a, color = 'black' })

This will create an inner shadow effect.

Since
  1.9

## Transform

Apply a geometrical transformation to a buffer.

Right now, only vertical flip is implemented and available. This operation does not blend and assumes the destination buffer is empty.

    transform ({ dst, op = 'vflip', src = input, oy = 0 })

Parameters

  dst | Destination buffer. Must be of the same colorspace as src. Must be specified.
  op | Must be `'vflip'`. There is no other operation yet.
  src | Source buffer to transform.
  oy | Y offset.

Example:

    t = buffer ('alpha')
    transform ({ oy = 20, dst = t })
    blend ({ src = t, color = 'silver' })
    blend ({ color = 'black' })

This will create a mirrored text effect, for a font of 50px.

Note
  Because of the meaning of oy, this effect probably needs to be customized for a single font size (FIXME).

Since
  1.9

## Padding_Set

Forcily set a specific padding for this filter.

    padding_set ({ l, r = [l], t = [r], b = [t] })

Parameters

  l | Padding on the left side in pixels.
  r | Padding on the right side in pixels. If unset, defaults to l.
  t | Padding on the top in pixels. If unset, defaults to r.
  b | Padding on the bottom in pixels. If unset, defaults to t.

All values must be >= 0. When filtering 'filled' images, some values may be too high and would result in completely hiding the image.

It is not possible to set only one of those without forcing the others as well. A common use case will be when changing a blur size during an animation, or when applying a mask that will hide most of the (blurred) text.

Example (the `fill` command is used for illustration purposes):

    fat = buffer ('alpha')
    padding_set ({ l = 10, r = 20, t = 15, b = 25 })
    fill ({ color = 'black' })
    fill ({ color = 'darkblue', l = 2, r = 2, t = 2, b = 2 })
    grow ({ 30, dst = fat })
    blur ({ 40, src = fat, color = 'white' })
    blend ({ color = 'darkblue' })

This will set the left, right, top and bottom paddings to their respective values, and some effects may look like they've been "clipped" out.

Since
  1.10