Skip to content

Custom UI & Drawbot

Custom UI uses a composited drawing model using Drawbot. The Drawbot suites can be used for:

  1. Basic 2D path drawing: Lines, Rect, Arc, Bezier
  2. Stroking/Filling/Shading paths
  3. Image drawing: Compositing an ARGB/BGRA buffer onto the surface
  4. Pushing/popping surface state
  5. Text drawing, if supplier supports it (clients should first check if text drawing is supported before actual drawing)

Drawing may only occur during PF_Event_DRAW (and not during PF_Event_DRAG or PF_Event_DO_CLICK).

To use Drawbot, first get the drawing reference by passing in PF_Context to a new suite call PF_GetDrawingReference.

If a non-NULL drawing reference is returned, use it to get the supplier and surface references from DRAWBOT_DrawbotSuite.

The Drawbot suites include DRAWBOT_DrawbotSuite, DRAWBOT_SupplierSuite, DRAWBOT_SurfaceSuite, DRAWBOT_PathSuite.


Make Your Custom UI Look Not So "Custom"

Use the new PF_EffectCustomUIOverlayThemeSuite to match the host application UI. Your users will thank you.


Redrawing

In order to redraw a specific area of a pane, we recommend the following:

  1. Call PF_InvalidateRect (from PF_AppSuite) from the effect. This will cause a lazy display redraw, and will update at the next available idle moment. This rect is in coordinates related to the associated pane. Using a NULL rect will update the entire pane.
  2. Set the event outflag to PF_EO_UPDATE_NOW, which will cause an immediate draw event for the specified pane when the current event returns.

If an effect needs to update more than one window at a time, it should set PF_OutFlag_REFRESH_UI (from PF_OutFlags), which will cause a redraw of the entire ECW, comp, and layer windows.


HiDPI and Retina Display Support

To support HiDPI and Retina Displays, you can use offscreen images that are twice the size, and then use the Transform function from Drawbot_SurfaceSuite to scale the image down in half before drawing it.


PF_EffectCustomUISuite

Enables an effect to get the drawing reference. This is the first call needed to use Drawbot.

PF_EffectCustomUISuite1

Function Purpose
PF_GetDrawingReference Get the drawing reference.
PF_GetDrawingReference(
const PF_ContextH effect_contextH,
DRAWBOT_DrawRef *referenceP0);

Drawbot_DrawbotSuite

Using the Drawbot reference, get the supplier and surface references.

Drawbot_DrawbotSuite1

Function Purpose
GetSupplier Get the supplier reference.

Needed to use Drawbot_SupplierSuite.
GetSupplier(
DRAWBOT_DrawRef in_drawbot_ref,
DRAWBOT_SupplierRef *out_supplierP);
GetSurface Get the surface reference.

Needed to use Drawbot_SurfaceSuite.
GetSurface(
DRAWBOT_DrawRef in_drawbot_ref,
DRAWBOT_SurfaceRef *out_surfaceP);

Drawbot_SupplierSuite

Calls to create and release drawing tools, get default settings, and query drawing capabilities.

Drawbot_SupplierSuite1

Function Purpose
NewPen Create a new pen. Release this using ReleaseObject from Drawbot_SupplierSuite.
NewPen(
DRAWBOT_SupplierRef in_supplier_ref,
const DRAWBOT_ColorRGBA *in_colorP,
float in_size,
DRAWBOT_PenRef *out_penP);
NewBrush Create a new brush. Release this using ReleaseObject from Drawbot_SupplierSuite.
NewBrush(
DRAWBOT_SupplierRef in_supplier_ref,
const DRAWBOT_ColorRGBA *in_colorP,
DRAWBOT_BrushRef *out_brushP);
SupportsText Check if current supplier supports text.
SupportsText(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_Boolean *out_supports_textB);
GetDefaultFontSize Get the default font size.
GetDefaultFontSize(
DRAWBOT_SupplierRef in_supplier_ref,
float *out_font_sizeF);
NewDefaultFont Create a new font with default settings.

You can pass the default font size from GetDefaultFontSize.

Release this using ReleaseObject from Drawbot_SupplierSuite.
NewDefaultFont(
DRAWBOT_SupplierRef in_supplier_ref,
float in_font_sizeF,
DRAWBOT_FontRef *out_fontP);
NewImageFromBuffer Create a new image from buffer passed to in_dataP.

Release this using ReleaseObject from Drawbot_SupplierSuite.
NewImageFromBuffer(
DRAWBOT_SupplierRef in_supplier_ref,
int in_width,
int in_height,
int in_row_bytes,
DRAWBOT_PixelLayout in_pl,
const void *in_dataP,
DRAWBOT_ImageRef *out_imageP);


DRAWBOT_PixelLayout can be one of the following:
  • kDRAWBOT_PixelLayout_24RGB
  • kDRAWBOT_PixelLayout_24BGR
  • kDRAWBOT_PixelLayout_32RGB
  • ARGB (A is ignored)
  • kDRAWBOT_PixelLayout_32BGR
  • BGRA (A is ignored)
  • kDRAWBOT_PixelLayout_32ARGB_Straight
  • kDRAWBOT_PixelLayout_32ARGB_Premul
  • kDRAWBOT_PixelLayout_32BGRA_Straight
  • kDRAWBOT_PixelLayout_32BGRA_Premul
NewPath Create a new path. Release this using ReleaseObject from Drawbot_SupplierSuite.
NewPath(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_PathRef *out_pathP);
SupportsPixelLayoutBGRA A given Drawbot implementation can support multiple channel orders, but will likely prefer one over the other.
Use the following four callbacks to get the preferred channel order for any API that takes a DRAWBOT_PixelLayout (e.g. NewImageFromBuffer).
SupportsPixelLayoutBGRA(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_Boolean *out_supports_bgraPB);
PrefersPixelLayoutBGRA
PrefersPixelLayoutBGRA(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_Boolean *out_prefers_bgraPB);
SupportsPixelLayoutARGB
SupportsPixelLayoutARGB(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_Boolean *out_supports_argbPB);
PrefersPixelLayoutARGB
PrefersPixelLayoutARGB(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_Boolean *out_prefers_argbPB);
RetainObject Retain (increase reference count on) any object (pen, brush, path, etc). For example, it should be used when any object is copied and the copied object should be retained.
RetainObject(
DRAWBOT_ObjectRef in_obj_ref);
ReleaseObject Release (decrease reference count on) any object (pen, brush, path, etc). This function MUST be called for any object created using NewXYZ() from this suite.
Do not call this function on a DRAWBOT_SupplierRef and DRAWBOT_SupplierRef, since these are not created by the plug-in.
ReleaseObject(
DRAWBOT_ObjectRef in_obj_ref);

Drawbot_SurfaceSuite

Calls to draw on the surface, and to query and set drawing settings.

Drawbot_SurfaceSuite1

Function Purpose
PushStateStack Push the current surface state onto the stack. It should be popped to retrieve old state.
It is required to restore state if you are going to clip or transform a surface or change the interpolation or anti-aliasing policy.
PushStateStack(
DRAWBOT_SurfaceRef in_surface_ref);
PopStateStack Pop the last pushed surface state off the stack.
PopStateStack(
DRAWBOT_SurfaceRef in_surface_ref);
PaintRect Paint a rectangle with a color on the surface.
PaintRect(
DRAWBOT_SurfaceRef in_surface_ref,
const DRAWBOT_ColorRGBA *in_colorP,
const DRAWBOT_RectF32 *in_rectPR);
FillPath Fill a path using a brush and fill type.
FillPath(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_BrushRef in_brush_ref,
DRAWBOT_PathRef in_path_ref,
DRAWBOT_FillType in_fill_type);


DRAWBOT_FillType is one of the following:
  • kDRAWBOT_FillType_EvenOdd
  • kDRAWBOT_FillType_Winding
StrokePath Stroke a path using a pen.
StrokePath(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_PenRef in_pen_ref,
DRAWBOT_PathRef in_path_ref);
Clip Clip the surface.
Clip(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_SupplierRef in_supplier_ref,
const DRAWBOT_Rect32 *in_rectPR);
GetClipBounds Get clip bounds.
GetClipBounds(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_Rect32 *out_rectPR);
IsWithinClipBounds Checks whether a rect is within the clip bounds.
IsWithinClipBounds(
DRAWBOT_SurfaceRef in_surface_ref,
const DRAWBOT_Rect32 *in_rectPR,
DRAWBOT_Boolean *out_withinPB);
Transform Transform the last surface state.
Transform(
DRAWBOT_SurfaceRef in_surface_ref,
const DRAWBOT_MatrixF32 *in_matrixP);
DrawString Draw a string.
DrawString(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_BrushRef in_brush_ref,
DRAWBOT_FontRef in_font_ref,
const DRAWBOT_UTF16Char *in_stringP,
const DRAWBOT_PointF32 *in_originP,
DRAWBOT_TextAlignment in_alignment_style,
DRAWBOT_TextTruncation in_truncation_style,
float in_truncation_width);


DRAWBOT_TextAlignment is one of the following:
  • kDRAWBOT_TextAlignment_Left
  • kDRAWBOT_TextAlignment_Center
  • kDRAWBOT_TextAlignment_Right
DRAWBOT_TextTruncation is one of the following:
  • kDRAWBOT_TextTruncation_None
  • kDRAWBOT_TextTruncation_End
  • kDRAWBOT_TextTruncation_EndEllipsis
  • kDRAWBOT_TextTruncation_PathEllipsis
DrawImage Draw an image created using NewImageFromBuffer() on the surface. Alpha = [0.0f, 1.0f ].
DrawImage(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_ImageRef in_image_ref,
const DRAWBOT_PointF32 *in_originP,
float in_alpha);
SetInterpolationPolicy
SetInterpolationPolicy(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_InterpolationPolicy in_interp);


DRAWBOT_InterpolationPolicy is one of the following:
  • kDRAWBOT_InterpolationPolicy_None
  • kDRAWBOT_InterpolationPolicy_Med
  • kDRAWBOT_InterpolationPolicy_High
GetInterpolationPolicy
GetInterpolationPolicy(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_InterpolationPolicy *out_interpP);
SetAntiAliasPolicy
SetAntiAliasPolicy(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_AntiAliasPolicy in_policy);


DRAWBOT_AntiAliasPolicy is one of the following:
  • kDRAWBOT_AntiAliasPolicy_None
  • kDRAWBOT_AntiAliasPolicy_Med
  • kDRAWBOT_AntiAliasPolicy_High
GetAntiAliasPolicy
GetAntiAliasPolicy(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_AntiAliasPolicy *out_policyP);
Flush Flush drawing. This is not always needed, and if overused, may cause excessive redrawing and flashing.
Flush(
DRAWBOT_SurfaceRef in_surface_ref);

Drawbot_PathSuite

Calls to draw paths.

Drawbot_PathSuite1

Function Purpose
MoveTo Move to a point.
MoveTo(
DRAWBOT_PathRef in_path_ref,
float in_x,
float in_y);
LineTo Add a line to the path.
LineTo(
DRAWBOT_PathRef in_path_ref,
float in_x,
float in_y);
BezierTo Add a cubic bezier to the path.
BezierTo(
DRAWBOT_PathRef in_path_ref,
const DRAWBOT_PointF32 *in_pt1P,
const DRAWBOT_PointF32 *in_pt2P,
const DRAWBOT_PointF32 *in_pt3P);
AddRect Add a rect to the path.
AddRect(
DRAWBOT_PathRef in_path_ref,
const DRAWBOT_RectF32 *in_rectPR);
AddArc Add a arc to the path. Zero start degrees == 3 o'clock.
Sweep is clockwise. Units for angle are in degrees.
AddArc(
DRAWBOT_PathRef in_path_ref,
const DRAWBOT_PointF32 *in_centerP,
float in_radius,
float in_start_angle,
float in_sweep);
Close Close the path.
Close(
DRAWBOT_PathRef in_path_ref);

PF_EffectCustomUIOverlayThemeSuite

This suite should be used for stroking and filling paths and vertices on the Composition and Layer Windows. After Effects is using this suite internally, and we have made it available to make custom UI look consistent across effects. The foreground/shadow colors are computed based on the app brightness level so that custom UI is always visible regardless of the application's Brightness setting in the Preferences.

PF_EffectCustomUIOverlayThemeSuite1

Function Purpose
PF_GetPreferredForegroundColor Get the preferred foreground color.
PF_GetPreferredForegroundColor(
DRAWBOT_ColorRGBA *foreground_colorP);
PF_GetPreferredShadowColor Get the preferred shadow color.
PF_GetPreferredShadowColor(
DRAWBOT_ColorRGBA *shadow_colorP);
PF_GetPreferredStrokeWidth Get the preferred foreground & shadow stroke width.
PF_GetPreferredStrokeWidth(
float *stroke_widthPF);
PF_GetPreferredVertexSize Get the preferred vertex size.
PF_GetPreferredVertexSize(
float *vertex_sizePF);
PF_GetPreferredShadowOffset Get the preferred shadow offset.
PF_GetPreferredShadowOffset(
A_LPoint *shadow_offsetP);
PF_StrokePath Stroke the path with the overlay theme foreground color.
Optionally draw the shadow using the overlay theme shadow color.
Uses overlay theme stroke width for stroking foreground and shadow strokes.
PF_StrokePath(
const DRAWBOT_DrawRef drawbot_ref,
const DRAWBOT_PathRef path_ref
PF_Boolean draw_shadowB);
PF_FillPath Fills the path with overlay theme foreground color.
Optionally draw the shadow using the overlay theme shadow color.
PF_FillPath(
const DRAWBOT_DrawRef drawbot_ref,
const DRAWBOT_PathRef path_ref
PF_Boolean draw_shadowB);
PF_FillVertex Fills a square vertex around the center point using the overlay theme foreground color and vertex size.
PF_FillVertex(
const DRAWBOT_DrawRef drawbot_ref,
const A_FloatPoint *center_pointP
PF_Boolean draw_shadowB);