#pragma once #include #include "esp_err.h" /* 5 fixed regions (manage QR, battery indicator, location, date, share * QR) plus up to MANAGE_FACE_LABELS_MAX arbitrary-position named-face * labels (see manage_face_label_t below). MANAGE_FACE_LABELS_MAX is * capped small deliberately, not arbitrarily -- each label is its own * malloc'd buffer, and the fixed regions alone already use a meaningful * chunk of the ESP32-C6's limited RAM; this keeps worst-case overlay * memory well clear of what the WiFi/HTTP stack needs alongside it. */ #define MANAGE_FACE_LABELS_MAX 4 #define MANAGE_OVERLAY_MAX_REGIONS (5 + MANAGE_FACE_LABELS_MAX) typedef struct { uint8_t *buf; /* malloc'd (w/2)*h bytes, packed 2px/byte; owned by the region */ int x0, y0; /* top-left corner, panel pixel coordinates (x0 is always even) */ int w, h; /* pixel dimensions (w is always even) */ } manage_overlay_region_t; typedef struct { manage_overlay_region_t regions[MANAGE_OVERLAY_MAX_REGIONS]; int count; } manage_overlay_set_t; typedef struct { char name[16]; int x, y; /* anchor point (bottom-center of the face), panel pixel coordinates */ } manage_face_label_t; typedef struct { const char *management_url; /* top-right QR + "SCAN TO"/"MANAGE" caption -- always shown */ const char *location_line1; /* top-left text, line 1 (city); NULL/empty skips this region */ const char *location_line2; /* top-left text, line 2 (state/country); NULL/empty is fine if line1 is set */ const char *taken_at; /* bottom-right text; NULL/empty skips this region */ const char *share_url; /* bottom-left QR + "SCAN TO"/"DOWNLOAD" caption; NULL/empty skips this region */ const manage_face_label_t *face_labels; /* named-face labels ("level 2" menu); NULL/empty count skips these */ int face_label_count; /* clamped to MANAGE_FACE_LABELS_MAX internally */ int battery_percent; /* 0-100 shows an icon + percent below the manage QR; -1 skips it */ } manage_overlay_content_t; /** * Renders the manage-button overlay: always a "scan to manage" QR in the * top-right corner, plus whichever of location_line1/taken_at/share_url * are non-NULL/non-empty in their own corners (top-left, bottom-right, * bottom-left respectively), plus one region per entry in face_labels * (positioned near that face rather than a fixed corner -- see * render_face_label_region() in the .c file for the clamping logic). * Each region is its own separately malloc'd small buffer (not a full * EPD_FRAME_BYTES frame). A failure rendering the top-right region fails * the whole call; a failure rendering any other region just skips that * region and keeps going. Caller must call manage_overlay_free() on out * regardless of the return value (out->count reflects however many * regions were actually populated). */ esp_err_t manage_overlay_render(const manage_overlay_content_t *content, manage_overlay_set_t *out); /** Frees every populated region's buffer in overlay. */ void manage_overlay_free(manage_overlay_set_t *overlay);