A rectangle's rounded corners could only be set by typing a Corner
Radius in Properties. As in Premiere, a selected rectangle now shows
four small circles just inside its corners: dragging one towards the
middle rounds all four corners (Corner Radius is one value), dragging it
back out squares them, and the radius stops at half the shorter side,
where the renderer caps it too.
The circles sit on each corner's diagonal at the radius, at least 12
points in, and show only on rectangles at least four times that across
on screen. While dragging, a white outline of the rounded rectangle
previews the result; the radius is set on release with graphics.set, one
undo step per drag. Automation ids: program.layer.<clip>.<layer>.corner.<n>.
Tests: graphics_handles_ui (the circles round all four corners, clamp
and undo; ellipses and tiny rectangles have none).
Dragging a handle of a rectangle, ellipse or polygon in the Program
monitor changed the layer's Scale, and a corner scaled width and height
alike, so a shape could not be made wider or taller from a corner.
As in Premiere, the handles now change the shape's Size (Premiere's
Path) and leave Scale alone: the dragged side or corner follows the
pointer, the opposite one stays, and the anchor point is renumbered so
that it and Position stay on the same spot of the picture. A corner
moves freely; Shift keeps the proportions. A path has no Size, so it
still stretches (and its corners follow the same Shift rule).
The paragraph-text box and the shape box share the side-dragging code
(drag_sides).
Tests: graphics_handles_ui (a shape's handles change its Size and Shift
keeps the ratio; a polygon's handles keep the opposite corner).
graphics.newShape, newRectangle, newEllipse and newPolygon already take
`seconds`, `track` and `time` through place_video_clip, as graphics.newText
does. Their parameter docs (what command_list shows) and the table in
docs/graphics.md listed only position, size and clip; they now list all of
them and say that position is the shape's centre.
place_video_clip takes the id of the command that called it for its errors.
It named graphics.newText in every placement error (V3 is not free here),
whether a shape, a file, a template or an upgraded caption had asked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stops were mixed in encoded sRGB, and any run with its own fill turned the whole layer into a solid colour. The ramp now blends in linear light, turns with the layer, and leaves a per-character fill solid.
Appearance › Fill Type paints a ramp across the layer bounds, and the ramp turns with the layer. A per-character fill colour still paints those characters as a solid.
Every layer of the selected graphic was outlined on the Program monitor,
so a box stayed after its layer was deselected, and a layer whose
visibility was off kept its box and could still be clicked and dragged.
As in Premiere Pro 26: a layer has a box only while it is selected (or
typed into), and a layer whose visibility is off is not on the monitor
at all: no box, no handles, no click target.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A text layer is now one of two types, each with Premiere Pro 26's handles:
- Point text (Type tool click): every handle scales the layer about its
anchor point, both axes alike; the font size is untouched.
- Paragraph text (Type tool drag): the dragged rectangle is a box the text
wraps in. Handles move that side or corner of the box, the opposite side
stays, the text re-wraps at the same size. Lines below the box are not
shown and the bottom-right handle turns into a red plus.
- The anchor point can be dragged with the Selection tool; the layer stays.
It is picked before anything under it, so a shape dragged by its exact
centre moves its anchor.
- Properties > Text > wrench opens Text Properties, where Text Layer Type
switches a layer between the two (graphics.setTextType); the text stays
where it is.
Shapes keep stretching away from their opposite side.
New: text layer parameter box_height, graphics.newText `box`, and
textType / box / overflow / anchor / scale in graphics.list. A layer saved
before a parameter existed can now be given it with graphics.set.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vertical text layout in the text engine (one line per character, columns right to left).
All edits are undoable engine commands; engine tests cover each menu group.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Program monitor overlay for graphic clips: Type tool click creates a text layer (in the
selected graphic under the playhead or a new clip) and edits it in place with a caret,
selection highlight, arrows/word/line navigation, Shift-select, Cmd+A/C/X/V, Return,
Backspace/Delete, Esc; typing is one undo step. Selection tool selects, moves and scales
layers (bounding box, handles, anchor); double-click edits text. Rectangle/Ellipse tools
drag out shapes; Pen tool places a closed path. Automation ids program.layer.*.
- Properties (when a graphic is selected) and Essential Graphics: Layers list, Align and
Transform (align / distribute), Text (source text, font family + style incl. system fonts,
size, paragraph alignment, tracking, leading, baseline shift, box width, faux bold/italic,
caps, underline, kerning/ligatures), Shape, Appearance (fill, 2 strokes, background,
shadow). Automation ids graphics.*.
- Headless UI test (egui_kittest) drives the whole flow through the control channel; with
FILMCRAFT_UI_SHOTS it renders PNGs via wgpu (works with a locked screen).
- docs/graphics.md; architecture, ROADMAP, ATTRIBUTION (code-drawn glyphs) updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>