|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Viewport state machine for the tap-to-zoom image viewer (#478). More...
#include "zoom.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_ui.h"#include "zoom_internal.h"Go to the source code of this file.
Enumerations | |
| enum | zoom_step_t : uint8_t { k_zoom_overlap_div = 8U , k_zoom_scale_dbl = 2U } |
| Pan-step geometry and the ladder multiplier (no magic numbers). More... | |
Functions | |
| void | priv_zoom_axis (int32_t anchor, int32_t extent, int32_t scale, int32_t src_dim, zoom_axis_t *out) |
| Resolve one viewport axis against the image at the current magnification. | |
| static bool | internal_dim_ok (uint32_t dim) |
| Whether a source dimension is inside the engine's addressable range. | |
| static int32_t | internal_sat_add (int32_t a, int32_t b) |
| Saturating signed addition (never wraps at the int32 boundary). | |
| static int32_t | internal_clamp_anchor (int32_t anchor, int32_t plane, int32_t extent) |
| Clamp one anchor against the magnified plane and the viewport extent. | |
| static void | internal_reclamp (zoom_view_t *v) |
| Re-clamp both anchors against the current source, scale and viewport. | |
| static void | internal_touch (zoom_view_t *v, uint32_t now_ms) |
| Record an interactive viewport change and schedule the flush it owes. | |
| static ra8_err_t | internal_cfg_ptrs_ok (const zoom_view_cfg_t *cfg) |
| Validate every pointer a configuration must carry. | |
| static ra8_err_t | internal_cfg_extent_ok (const zoom_view_cfg_t *cfg) |
| Validate the viewport extent and the source extent. | |
| static ra8_err_t | internal_cfg_scratch_ok (const zoom_view_cfg_t *cfg, uint16_t *out_strip_rows) |
| Derive the strip height from the scratch budget and check every capacity. | |
| static ra8_err_t | internal_cfg_ladder_ok (const zoom_view_cfg_t *cfg, uint8_t *out_scale, uint8_t *out_ceiling) |
| Resolve and validate the magnification ladder a configuration asks for. | |
| ra8_err_t | zoom_source_init (zoom_source_t *out, zoom_read_fn read, void *ctx, uint32_t width, uint32_t height) |
| Bind a gray8 sub-rectangle reader and its extent as a magnifiable source. | |
| static ra8_err_t | internal_cfg_ok (const zoom_view_cfg_t *cfg, uint16_t *out_strip_rows, uint8_t *out_scale, uint8_t *out_ceiling) |
| Run every configuration check, in the order they depend on each other. | |
| static void | internal_view_adopt (zoom_view_t *v, const zoom_view_cfg_t *cfg, uint8_t opening, uint8_t ceiling, uint16_t strip_rows) |
| Publish a validated configuration into a view and open it. | |
| ra8_err_t | zoom_view_open (zoom_view_t *v, const zoom_view_cfg_t *cfg) |
| Open a viewport onto a source, centred on a source-pixel focus. | |
| ra8_err_t | zoom_view_rebind (zoom_view_t *v, const zoom_source_t *src, uint32_t now_ms) |
| Point an open view at a different source, keeping zoom and position. | |
| ra8_err_t | zoom_view_invalidate (zoom_view_t *v, uint32_t now_ms) |
| Declare the viewport's pixels stale for a reason the engine cannot see. | |
| ra8_err_t | zoom_view_close (zoom_view_t *v) |
| Close a view; it stops owing the panel anything. | |
| bool | zoom_view_active (const zoom_view_t *v) |
| Whether a view is open. | |
| uint8_t | zoom_scale_cycle (uint8_t scale, uint8_t min, uint8_t max) |
| Next magnification on the doubling ladder, wrapping back to the minimum. | |
| ra8_err_t | zoom_view_set_scale (zoom_view_t *v, uint8_t scale, int32_t focus_x, int32_t focus_y, uint32_t now_ms) |
| Set the magnification, keeping a panel point fixed under the finger. | |
| ra8_err_t | zoom_view_pan (zoom_view_t *v, int32_t dx, int32_t dy, uint32_t now_ms) |
| Pan the viewport by a destination-pixel delta. | |
| ra8_err_t | zoom_view_pan_dir (zoom_view_t *v, zoom_pan_t dir, uint32_t now_ms) |
| Pan by a discrete step in one direction (the tap-band interaction). | |
| ra8_err_t | zoom_view_window (const zoom_view_t *v, ra8_ui_rect_t *out) |
| The source rectangle currently visible, in source pixels. | |
| bool | zoom_view_tick (zoom_view_t *v, uint32_t now_ms) |
| Advance the settle timer; promote a bi-level view to full quality. | |
| ra8_err_t | zoom_view_present (zoom_view_t *v, zoom_present_t *out) |
| Take the pending flush plan, clearing it. | |
Variables | |
| static const char *const | s_tag = "zoom" |
| Component tag for RA8_CHECK_* log lines. | |
Viewport state machine for the tap-to-zoom image viewer (#478).
Implements the non-rendering half of zoom.h: opening a viewport onto a source, the integer magnification ladder, anchor clamping in the magnified plane, discrete pan steps, and the dirty/waveform bookkeeping the reader turns into a display flush. Pure integer arithmetic with no MMIO and no allocation, so it behaves identically on the unit-test host, in ra8_emulator and on silicon. The strip composite lives in zoom_render.c.
[Ring 4 / Domain] {World: NS}
Definition in file zoom.c.
| enum zoom_step_t : uint8_t |
Pan-step geometry and the ladder multiplier (no magic numbers).
One discrete pan step moves the viewport by its own extent less extent / k_zoom_overlap_div, so a strip of the previous view stays on screen and the reader never loses their place. Expressed as a divisor rather than a pixel count so it scales with the viewport: a 320 px loupe keeps 40 px, a 1024 px full-screen view keeps 128 px.
| Enumerator | |
|---|---|
| k_zoom_overlap_div | Viewport fraction retained across a pan step. |
| k_zoom_scale_dbl | Ladder multiplier (doubling, not increment). |
|
static |
Validate the viewport extent and the source extent.
Runs after the pointer check and before the scratch sizing, which divides by the viewport width: an empty viewport has to be rejected first. The source bound is what makes the magnified-plane arithmetic overflow-free downstream.
| [in] | cfg | Candidate configuration (already known non-NULL). |
| k_ra8_ok | Both extents are usable. |
| k_ra8_err_invalid_arg | An extent is empty, or the source is too large. |
cfg is non-NULL. cfg. Definition at line 277 of file zoom.c.
References zoom_view_cfg_t::dst, ra8_ui_rect_t::h, zoom_source_t::height, internal_dim_ok(), k_ra8_err_invalid_arg, k_ra8_ok, ra8_log_error, s_tag, zoom_view_cfg_t::src, ra8_ui_rect_t::w, and zoom_source_t::width.
Referenced by internal_cfg_ok().
|
static |
Resolve and validate the magnification ladder a configuration asks for.
Resolves the two "0 means default" fields before validating them, so an all-zero configuration opens at 1:1 with the engine ceiling instead of being rejected, while an out-of-range explicit value still fails closed.
| [in] | cfg | Candidate configuration (already known non-NULL). |
| [out] | out_scale | Receives the opening magnification. |
| [out] | out_ceiling | Receives the effective ladder ceiling. |
| k_ra8_ok | Both values are on the engine ladder. |
| k_ra8_err_invalid_arg | The ceiling or the opening scale is off it. |
cfg is non-NULL. out_scale and out_ceiling address writable storage. Definition at line 352 of file zoom.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_zoom_scale_max, k_zoom_scale_min, ra8_log_error, s_tag, zoom_view_cfg_t::scale, and zoom_view_cfg_t::scale_max.
Referenced by internal_cfg_ok().
|
static |
Run every configuration check, in the order they depend on each other.
The order is not stylistic. Pointers first, because the extent check reads through them; extents second, because the scratch sizing divides by the viewport width; the ladder last, because it is the only check with no dependency on the others. Split out of zoom_view_open so that function is "check, then adopt".
| [in] | cfg | Candidate configuration (already known non-NULL). |
| [out] | out_strip_rows | Receives the resolved composite strip height. |
| [out] | out_scale | Receives the resolved opening magnification. |
| [out] | out_ceiling | Receives the resolved ladder ceiling. |
| k_ra8_ok | Every check passed; all three outputs are resolved. |
| k_ra8_err_* | The first failing check's code, verbatim. |
cfg is non-NULL. Definition at line 418 of file zoom.c.
References internal_cfg_extent_ok(), internal_cfg_ladder_ok(), internal_cfg_ptrs_ok(), internal_cfg_scratch_ok(), RA8_RETURN_ON_ERROR, and s_tag.
Referenced by zoom_view_open().
|
static |
Validate every pointer a configuration must carry.
Split out of zoom_view_open so each validation stage stays inside the project's function-size bar, and so a missing pointer is rejected before any sizing arithmetic reads through it.
| [in] | cfg | Candidate configuration (already known non-NULL). |
| k_ra8_ok | Every required pointer is present. |
| k_ra8_err_null_ptr | One is missing; the log line names it. |
cfg is non-NULL. cfg into a view. Definition at line 250 of file zoom.c.
References k_ra8_ok, zoom_scratch_t::packed, RA8_CHECK_NULL_PTR, zoom_source_t::read, zoom_scratch_t::row, s_tag, zoom_view_cfg_t::scratch, zoom_view_cfg_t::src, and zoom_scratch_t::strip.
Referenced by internal_cfg_ok().
|
static |
Derive the strip height from the scratch budget and check every capacity.
Derives the strip height from the strip budget rather than taking it as a parameter, so the caller tunes the composite by sizing a buffer and cannot ask for a strip its packed buffer could not hold. The height is capped by the module maximum and by the viewport itself.
| [in] | cfg | Candidate configuration (already known non-NULL). |
| [out] | out_strip_rows | Destination rows one composite strip can hold. |
| k_ra8_ok | out_strip_rows holds a workable strip height. |
| k_ra8_err_no_mem | A buffer is too small for this viewport width. |
cfg passed internal_cfg_extent_ok, so dst.w > 0. out_strip_rows addresses writable storage. Definition at line 309 of file zoom.c.
References zoom_view_cfg_t::dst, ra8_ui_rect_t::h, k_ra8_err_no_mem, k_ra8_ok, k_zoom_strip_rows_max, zoom_scratch_t::packed_cap, ra8_log_error, zoom_scratch_t::row_cap, s_tag, zoom_view_cfg_t::scratch, zoom_scratch_t::strip_cap, and ra8_ui_rect_t::w.
Referenced by internal_cfg_ok().
|
static |
Clamp one anchor against the magnified plane and the viewport extent.
Two regimes, decided by whether the magnified image is bigger than the viewport. Bigger: the anchor is held inside [0, plane - extent] so the viewport never shows past an edge. Smaller: the image is centred and the anchor goes negative, which the render reads as a letterbox rather than as an error.
| [in] | anchor | Proposed magnified-plane coordinate at viewport offset 0. |
| [in] | plane | Magnified plane extent on this axis (src_dim * scale). |
| [in] | extent | Viewport extent on this axis, destination pixels. |
| negative | The image is smaller than the viewport: the centring offset. |
| [0, plane - extent] | Otherwise, the in-range anchor. |
extent is positive (validated at open). plane is src_dim * scale for the same axis. Definition at line 167 of file zoom.c.
Referenced by internal_reclamp().
|
static |
Whether a source dimension is inside the engine's addressable range.
The single place the engine's addressable range is decided. Both bounds matter: zero has no pixels to magnify, and a dimension past the cap could overflow the magnified plane at maximum zoom.
| [in] | dim | Candidate width or height in pixels. |
| true | The dimension is usable. |
| false | Zero, or large enough that the magnified plane could overflow. |
dim is a pixel count, not a byte count. Definition at line 111 of file zoom.c.
References k_zoom_dim_max.
Referenced by internal_cfg_extent_ok(), zoom_source_init(), and zoom_view_rebind().
|
static |
Re-clamp both anchors against the current source, scale and viewport.
Called after anything that can invalidate an anchor – a scale change, a pan, a rebind onto a differently-sized page – so the clamp invariant is re-established in exactly one place instead of at every mutation site.
| [in,out] | v | Open view whose anchors may be out of range. |
v is non-NULL and open. Definition at line 199 of file zoom.c.
References zoom_view_t::anchor_x, zoom_view_t::anchor_y, zoom_view_t::dst, ra8_ui_rect_t::h, zoom_source_t::height, internal_clamp_anchor(), zoom_view_t::scale, zoom_view_t::src, ra8_ui_rect_t::w, and zoom_source_t::width.
Referenced by internal_view_adopt(), zoom_view_pan(), zoom_view_rebind(), and zoom_view_set_scale().
|
static |
Saturating signed addition (never wraps at the int32 boundary).
A pan delta is caller-supplied and may be arbitrary, so the anchor addition is done in 64 bits and clamped rather than allowed to wrap – a wrapped anchor would clamp to the wrong edge.
| [in] | a | First addend. |
| [in] | b | Second addend. |
| INT32_MAX | The true sum overflowed positive. |
| INT32_MIN | The true sum overflowed negative. |
a and b are valid signed integers. Definition at line 134 of file zoom.c.
Referenced by zoom_view_pan().
|
static |
Record an interactive viewport change and schedule the flush it owes.
The one place the dirty flag and the waveform class are set, so the policy is applied uniformly: under the responsive policy an interactive change owes a fast (bi-level) flush and arms the settle timer; under the quality policy it owes a full 16-level flush and arms nothing.
| [in,out] | v | Open view. |
| [in] | now_ms | Current millisecond timestamp. |
v is non-NULL and open. now_ms comes from a monotonic millisecond source. Definition at line 224 of file zoom.c.
References k_zoom_policy_responsive, k_zoom_refresh_fast, k_zoom_refresh_quality, zoom_view_t::last_input_ms, zoom_view_t::pending, zoom_view_t::pending_kind, zoom_view_t::policy, and zoom_view_t::settle_armed.
Referenced by zoom_view_invalidate(), zoom_view_pan(), zoom_view_rebind(), and zoom_view_set_scale().
|
static |
Publish a validated configuration into a view and open it.
The last step of zoom_view_open, split out so the open path reads as "validate, validate, validate, adopt" rather than as one long function. Nothing here can fail: every value has already been checked, so this is assignment plus the initial clamp. The anchor is derived from the focus point in SOURCE pixels – scaled into the magnified plane, then backed off by half a viewport so the focus lands in the middle rather than the corner.
| [out] | v | View to populate (its previous contents are discarded). |
| [in] | cfg | The validated configuration. |
| [in] | opening | Resolved opening magnification. |
| [in] | ceiling | Resolved ladder ceiling. |
| [in] | strip_rows | Resolved composite strip height. |
cfg passed every ::zoom_cfg_* check. opening, ceiling and strip_rows are their resolved values. Definition at line 458 of file zoom.c.
References zoom_view_t::active, zoom_view_t::anchor_x, zoom_view_t::anchor_y, zoom_view_cfg_t::dst, zoom_view_t::dst, zoom_view_cfg_t::focus_x, zoom_view_cfg_t::focus_y, ra8_ui_rect_t::h, internal_reclamp(), k_zoom_refresh_quality, k_zoom_settle_ms_default, zoom_view_t::last_input_ms, zoom_view_t::pending, zoom_view_t::pending_kind, zoom_view_cfg_t::policy, zoom_view_t::policy, zoom_view_t::scale, zoom_view_t::scale_max, zoom_view_cfg_t::scratch, zoom_view_t::scratch, zoom_view_t::settle_armed, zoom_view_cfg_t::settle_ms, zoom_view_t::settle_ms, zoom_view_cfg_t::src, zoom_view_t::src, zoom_view_t::strip_rows, and ra8_ui_rect_t::w.
Referenced by zoom_view_open().
| void priv_zoom_axis | ( | int32_t | anchor, |
| int32_t | extent, | ||
| int32_t | scale, | ||
| int32_t | src_dim, | ||
| zoom_axis_t * | out ) |
Resolve one viewport axis against the image at the current magnification.
The single definition of the viewer's geometry. Destination offset d maps to magnified-plane coordinate anchor + d and therefore to source index (anchor + d) / scale; the covered span is where that plane coordinate lies inside [0, src_dim * scale). Both the render (which columns to fill, which source row segment to read) and zoom_view_window (which source pixels are live) are views onto this one result. The division is only ever performed on a non-negative plane coordinate, so it never depends on the implementation of signed truncation.
| [in] | anchor | Magnified-plane coordinate shown at viewport offset 0. |
| [in] | extent | Viewport extent on this axis, destination pixels (> 0). |
| [in] | scale | Integer magnification (>= 1). |
| [in] | src_dim | Source extent on this axis, pixels (>= 1). |
| [out] | out | Receives the resolved axis. |
out is always fully populated.out is non-NULL (callers are inside this module and hold storage). Definition at line 60 of file zoom.c.
References zoom_axis_t::count, zoom_axis_t::d0, zoom_axis_t::d1, and zoom_axis_t::s0.
Referenced by zoom_view_render(), and zoom_view_window().
|
nodiscard |
Next magnification on the doubling ladder, wrapping back to the minimum.
The tap-to-zoom cycle every reader in this tree uses: min -> 2*min -> 4*min -> ... -> max -> min. Doubling rather than incrementing because a 1x -> 2x step is a visible change and a 7x -> 8x step is not. The last rung is max exactly even when max is not a power of two, so a ceiling of 3 gives 1 -> 2 -> 3 -> 1.
| [in] | scale | Current magnification. |
| [in] | min | Ladder floor (0 is read as k_zoom_scale_min). |
| [in] | max | Ladder ceiling (below min is read as min). |
| min | scale was already at or above max. |
| 2 * scale or max | Otherwise, whichever is smaller. |
min and max are magnifications, not plane coordinates. Definition at line 539 of file zoom.c.
References k_zoom_scale_dbl, k_zoom_scale_min, and min.
Referenced by ez_scene_tap().
|
nodiscard |
Bind a gray8 sub-rectangle reader and its extent as a magnifiable source.
Validates the reader and the extent once, here, so nothing downstream has to re-check them: the engine's plane arithmetic is overflow-free precisely because width and height passed k_zoom_dim_max at this seam.
| [out] | out | Source descriptor to populate. |
| [in] | read | gray8 sub-rectangle reader (non-NULL). |
| [in] | ctx | Opaque context handed back to read (may be NULL). |
| [in] | width | Full-resolution source width, [1, k_zoom_dim_max]. |
| [in] | height | Full-resolution source height, [1, k_zoom_dim_max]. |
| k_ra8_ok | out describes the source. |
| k_ra8_err_null_ptr | out or read is NULL. |
| k_ra8_err_invalid_arg | width or height is 0 or exceeds the cap. |
out addresses writable storage for one zoom_source_t. read remains valid for the lifetime of every view bound to this source. out is set and out->read != NULL. out is left untouched.Definition at line 375 of file zoom.c.
References zoom_source_t::ctx, zoom_source_t::height, internal_dim_ok(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, zoom_source_t::read, s_tag, and zoom_source_t::width.
|
nodiscard |
Whether a view is open.
| [in] | v | View to query (NULL reads as closed). |
| true | v is non-NULL and open. |
| false | v is NULL or closed. |
v, if non-NULL, addresses a zoom_view_t. Definition at line 534 of file zoom.c.
References zoom_view_t::active.
|
nodiscard |
Close a view; it stops owing the panel anything.
| [in,out] | v | View to close (may already be closed). |
| k_ra8_ok | The view is closed. |
| k_ra8_err_null_ptr | v is NULL. |
v addresses writable storage for one zoom_view_t. Definition at line 525 of file zoom.c.
References zoom_view_t::active, k_ra8_ok, zoom_view_t::pending, RA8_CHECK_NULL_PTR, s_tag, and zoom_view_t::settle_armed.
|
nodiscard |
Declare the viewport's pixels stale for a reason the engine cannot see.
The engine marks itself dirty when it changes the view, and deliberately does not when nothing moved – a pan clamped against an edge owes the panel nothing, which is what stops an e-ink refresh per tap. That is exactly right for the engine's own state and exactly wrong for everything a compositor does around it: drawing a loupe over the viewport, lifting one off it, or repainting chrome that overlaps it all invalidate pixels the engine has no way to know about.
Without this the reader hits a silent class of bug that a continuously-scanned LCD hides completely: the framebuffer is correct, no flush is ever requested, and on an e-ink panel the change simply never appears. Call it whenever something outside the engine has damaged the viewport.
| [in,out] | v | Open view. |
| [in] | now_ms | Current millisecond timestamp for the settle timer. |
| k_ra8_ok | A flush of the whole viewport is now owed. |
| k_ra8_err_null_ptr | v is NULL. |
| k_ra8_err_invalid_state | v is not open. |
v was opened by zoom_view_open. Definition at line 514 of file zoom.c.
References zoom_view_t::active, internal_touch(), k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, and s_tag.
Referenced by ez_scene_tap(), and ez_selftest_lens().
|
nodiscard |
Open a viewport onto a source, centred on a source-pixel focus.
Derives everything the engine needs and never re-derives it: the strip height from the scratch capacity, the effective ladder ceiling, the settle window, and the initial anchor from cfg->focus_x / focus_y clamped to the image. The view opens owing a k_zoom_refresh_quality flush regardless of policy – the first frame a reader sees must be the good one.
| [out] | v | View to open (overwritten wholesale). |
| [in] | cfg | Configuration; see zoom_view_cfg_t. |
| k_ra8_ok | The view is open and owes a quality flush. |
| k_ra8_err_null_ptr | v, cfg, cfg->src.read, or a scratch pointer is NULL. |
| k_ra8_err_invalid_arg | Empty viewport, out-of-range scale, or a bad source extent. |
| k_ra8_err_no_mem | A scratch buffer is too small for this viewport width. |
cfg->src was populated by zoom_source_init or an adapter binder. cfg outlives the view. v is not left half-open: v->active is false.Definition at line 482 of file zoom.c.
References zoom_view_t::active, internal_cfg_ok(), internal_view_adopt(), k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by ez_open_views().
|
nodiscard |
Pan the viewport by a destination-pixel delta.
Moves the anchor and re-clamps it. Because the anchor lives in the magnified plane the delta is in destination pixels at every zoom, so a one-pixel pan is one pixel of panel movement whether the view is at 1:1 or 8x. A delta that would leave the image is clamped rather than rejected, and a clamped-to-no-movement pan owes no flush – panning into an edge does not cost an e-ink refresh.
| [in,out] | v | Open view. |
| [in] | dx | Horizontal movement in destination pixels (+ moves content left). |
| [in] | dy | Vertical movement in destination pixels (+ moves content up). |
| [in] | now_ms | Current millisecond timestamp for the settle timer. |
| k_ra8_ok | The anchor moved, or was already against the edge. |
| k_ra8_err_null_ptr | v is NULL. |
| k_ra8_err_invalid_state | v is not open. |
v was opened by zoom_view_open. dx and dy are destination pixels, not source pixels. Definition at line 595 of file zoom.c.
References zoom_view_t::active, zoom_view_t::anchor_x, zoom_view_t::anchor_y, internal_reclamp(), internal_sat_add(), internal_touch(), k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, and s_tag.
Referenced by zoom_view_pan_dir().
|
nodiscard |
Pan by a discrete step in one direction (the tap-band interaction).
One step is zoom_view_t::dst minus a one-eighth overlap on the moving axis, so consecutive taps keep a strip of the previous view on screen and the reader never loses their place. The overlap is a fraction of the viewport rather than a constant so it scales with the lens size in loupe mode.
| [in,out] | v | Open view. |
| [in] | dir | Direction; k_zoom_pan_none is a no-op. |
| [in] | now_ms | Current millisecond timestamp for the settle timer. |
| k_ra8_ok | The step was applied (possibly clamped to nothing). |
| k_ra8_err_null_ptr | v is NULL. |
| k_ra8_err_invalid_state | v is not open. |
v was opened by zoom_view_open. dir is a zoom_pan_t enumerator. Definition at line 614 of file zoom.c.
References zoom_view_t::active, zoom_view_t::dst, ra8_ui_rect_t::h, k_ra8_err_invalid_state, k_zoom_overlap_div, k_zoom_pan_down, k_zoom_pan_left, k_zoom_pan_none, k_zoom_pan_right, k_zoom_pan_up, RA8_CHECK_NULL_PTR, ra8_log_error, s_tag, ra8_ui_rect_t::w, and zoom_view_pan().
Referenced by ez_apply_pan(), and ez_selftest_pan().
|
nodiscard |
Take the pending flush plan, clearing it.
The consume half of the dirty-tracking pair: it reports what the panel owes and immediately marks it paid, so a caller that ignores the plan simply drops a frame rather than flushing the same rectangle forever. Call it after zoom_view_render, not before.
| [in,out] | v | Open view. |
| [out] | out | Receives the plan; out->present is false when none is owed. |
| k_ra8_ok | out holds the plan (possibly present == false). |
| k_ra8_err_null_ptr | v or out is NULL. |
| k_ra8_err_invalid_state | v is not open. |
v was opened by zoom_view_open. Definition at line 684 of file zoom.c.
References zoom_view_t::active, zoom_view_t::dst, k_ra8_err_invalid_state, k_ra8_ok, zoom_view_t::pending, zoom_view_t::pending_kind, zoom_present_t::present, RA8_CHECK_NULL_PTR, ra8_log_error, zoom_present_t::rect, zoom_present_t::refresh, and s_tag.
Referenced by ez_scene_present().
|
nodiscard |
Point an open view at a different source, keeping zoom and position.
The page-turn path, and a deliberate product choice: turning the page while magnified keeps the magnification and the viewport anchor rather than dropping back to the whole page. A reader who zoomed in because the text is small wants the next page at the same magnification; the alternative (a turn exits zoom) is strictly less capable and is recoverable by calling zoom_view_close instead. The anchor is re-clamped to the new extent, so a shorter page simply pins to its bottom edge rather than showing past it.
| [in,out] | v | Open view. |
| [in] | src | New source (validated as at open). |
| [in] | now_ms | Current millisecond timestamp for the settle timer. |
| k_ra8_ok | The view now reads src. |
| k_ra8_err_null_ptr | v or src is NULL, or src->read is NULL. |
| k_ra8_err_invalid_arg | src has a zero or oversized extent. |
| k_ra8_err_invalid_state | v is not open. |
v was opened by zoom_view_open. src outlives the view. src. Definition at line 495 of file zoom.c.
References zoom_view_t::active, zoom_source_t::height, internal_dim_ok(), internal_reclamp(), internal_touch(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, zoom_source_t::read, s_tag, zoom_view_t::src, and zoom_source_t::width.
|
nodiscard |
Set the magnification, keeping a panel point fixed under the finger.
Tap-to-zoom, literally: the plane point currently displayed at (focus_x, focus_y) – framebuffer coordinates, i.e. where the user tapped – is the point that stays put. The plane coordinate is rescaled by new_scale / old_scale and the anchor is recomputed so that the same image feature lands under the same pixel, then clamped. A focus outside the viewport still works and simply pulls that off-screen feature toward the tapped edge.
Setting the scale it already has is a no-op and owes no flush, so a reader can call this unconditionally from a tap handler.
| [in,out] | v | Open view. |
| [in] | scale | Requested magnification, [k_zoom_scale_min, v->scale_max]. |
| [in] | focus_x | Framebuffer column to keep fixed. |
| [in] | focus_y | Framebuffer row to keep fixed. |
| [in] | now_ms | Current millisecond timestamp for the settle timer. |
| k_ra8_ok | The scale is now scale (or already was). |
| k_ra8_err_null_ptr | v is NULL. |
| k_ra8_err_invalid_state | v is not open. |
| k_ra8_err_out_of_range | scale is outside the ladder. |
v was opened by zoom_view_open. scale is on the integer ladder (fractional zoom is not representable). Definition at line 556 of file zoom.c.
References zoom_view_t::active, zoom_view_t::anchor_x, zoom_view_t::anchor_y, zoom_view_t::dst, internal_reclamp(), internal_touch(), k_ra8_err_invalid_state, k_ra8_err_out_of_range, k_ra8_ok, k_zoom_scale_min, RA8_CHECK_NULL_PTR, ra8_log_error, s_tag, zoom_view_t::scale, zoom_view_t::scale_max, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.
Referenced by ez_scene_tap(), and ez_selftest_zoom().
| bool zoom_view_tick | ( | zoom_view_t * | v, |
| uint32_t | now_ms ) |
Advance the settle timer; promote a bi-level view to full quality.
Call once per main-loop iteration. Under k_zoom_policy_responsive an interactive change leaves the view armed; once zoom_view_t::settle_ms of input silence have passed this arms a k_zoom_refresh_quality repaint of the same rectangle and disarms itself, so the reader repaints once and not per tick. The elapsed-time comparison is unsigned, so a millisecond counter that wraps produces one early settle rather than a hang.
| [in,out] | v | View (NULL is accepted and answers false). |
| [in] | now_ms | Current millisecond timestamp. |
| true | The caller should re-render and present. |
| false | Nothing to do this tick. |
now_ms comes from a monotonic millisecond source. v is unmodified.Definition at line 664 of file zoom.c.
References zoom_view_t::active, k_zoom_refresh_quality, zoom_view_t::last_input_ms, zoom_view_t::pending, zoom_view_t::pending_kind, zoom_view_t::settle_armed, and zoom_view_t::settle_ms.
Referenced by ez_scene_tick().
|
nodiscard |
The source rectangle currently visible, in source pixels.
The residency question in one call: these are exactly the pixels the next zoom_view_render will read, so a tiled adapter can turn it into a tile rectangle and prove that nothing outside it is pinned. The rectangle is clipped to the image, so a letterboxed view reports the image's own extent rather than the viewport's.
| [in] | v | Open view. |
| [out] | out | Receives the visible source rectangle. |
| k_ra8_ok | out holds the visible source rectangle. |
| k_ra8_err_null_ptr | v or out is NULL. |
| k_ra8_err_invalid_state | v is not open. |
v was opened by zoom_view_open. out addresses writable storage for one ra8_ui_rect_t. Definition at line 645 of file zoom.c.
References zoom_view_t::active, zoom_view_t::anchor_x, zoom_view_t::anchor_y, zoom_axis_t::count, zoom_view_t::dst, ra8_ui_rect_t::h, zoom_source_t::height, k_ra8_err_invalid_state, k_ra8_ok, priv_zoom_axis(), RA8_CHECK_NULL_PTR, ra8_log_error, zoom_axis_t::s0, s_tag, zoom_view_t::scale, zoom_view_t::src, ra8_ui_rect_t::w, zoom_source_t::width, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.
Referenced by ez_apply_pan().