Skip to content

custom-ui-and-drawbot

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

FunctionPurpose
PF_GetDrawingReferenceGet 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

FunctionPurpose
GetSupplierGet the supplier reference.
Needed to use Drawbot_SupplierSuite.
 GetSupplier(
DRAWBOT_DrawRef in_drawbot_ref,
DRAWBOT_SupplierRef *out_supplierP);
GetSurfaceGet 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

FunctionPurpose
NewPenCreate 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);
NewBrushCreate 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);
SupportsTextCheck if current supplier supports text.
 SupportsText(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_Boolean *out_supports_textB);
GetDefaultFontSizeGet the default font size.
 GetDefaultFontSize(
DRAWBOT_SupplierRef in_supplier_ref,
float *out_font_sizeF);
NewDefaultFontCreate 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);
NewImageFromBufferCreate 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
NewPathCreate a new path. Release this using ReleaseObject from Drawbot_SupplierSuite.
 NewPath(
DRAWBOT_SupplierRef in_supplier_ref,
DRAWBOT_PathRef *out_pathP);
SupportsPixelLayoutBGRAA 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);
RetainObjectRetain (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);
ReleaseObjectRelease (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

FunctionPurpose
PushStateStackPush 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);
PopStateStackPop the last pushed surface state off the stack.
 PopStateStack(
DRAWBOT_SurfaceRef in_surface_ref);
PaintRectPaint a rectangle with a color on the surface.
 PaintRect(
DRAWBOT_SurfaceRef in_surface_ref,
const DRAWBOT_ColorRGBA *in_colorP,
const DRAWBOT_RectF32 *in_rectPR);
FillPathFill 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
StrokePathStroke a path using a pen.
 StrokePath(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_PenRef in_pen_ref,
DRAWBOT_PathRef in_path_ref);
ClipClip the surface.
 Clip(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_SupplierRef in_supplier_ref,
const DRAWBOT_Rect32 *in_rectPR);
GetClipBoundsGet clip bounds.
 GetClipBounds(
DRAWBOT_SurfaceRef in_surface_ref,
DRAWBOT_Rect32 *out_rectPR);
IsWithinClipBoundsChecks whether a rect is within the clip bounds.
 IsWithinClipBounds(
DRAWBOT_SurfaceRef in_surface_ref,
const DRAWBOT_Rect32 *in_rectPR,
DRAWBOT_Boolean *out_withinPB);
TransformTransform the last surface state.
 Transform(
DRAWBOT_SurfaceRef in_surface_ref,
const DRAWBOT_MatrixF32 *in_matrixP);
DrawStringDraw 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
DrawImageDraw 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);
FlushFlush 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

FunctionPurpose
MoveToMove to a point.
 MoveTo(
DRAWBOT_PathRef in_path_ref,
float in_x,
float in_y);
LineToAdd a line to the path.
 LineTo(
DRAWBOT_PathRef in_path_ref,
float in_x,
float in_y);
BezierToAdd 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);
AddRectAdd a rect to the path.
 AddRect(
DRAWBOT_PathRef in_path_ref,
const DRAWBOT_RectF32 *in_rectPR);
AddArcAdd 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);
CloseClose 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

FunctionPurpose
PF_GetPreferredForegroundColorGet the preferred foreground color.
 PF_GetPreferredForegroundColor(
DRAWBOT_ColorRGBA *foreground_colorP);
PF_GetPreferredShadowColorGet the preferred shadow color.
 PF_GetPreferredShadowColor(
DRAWBOT_ColorRGBA *shadow_colorP);
PF_GetPreferredStrokeWidthGet the preferred foreground & shadow stroke width.
 PF_GetPreferredStrokeWidth(
float *stroke_widthPF);
PF_GetPreferredVertexSizeGet the preferred vertex size.
 PF_GetPreferredVertexSize(
float *vertex_sizePF);
PF_GetPreferredShadowOffsetGet the preferred shadow offset.
 PF_GetPreferredShadowOffset(
A_LPoint *shadow_offsetP);
PF_StrokePathStroke 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_FillPathFills 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_FillVertexFills 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);