rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
gfx_seg.c File Reference

Seven-segment numerals, drawn rather than stored. More...

#include "gfx.h"
#include <math.h>

Macros

#define SEG_A   0x01u
#define SEG_B   0x02u
#define SEG_C   0x04u
#define SEG_D   0x08u
#define SEG_E   0x10u
#define SEG_F   0x20u
#define SEG_G   0x40u
#define SEG_ALL   0x7Fu

Functions

static uint8_t mask_for (char ch)
 The bars ch lights: a digit or '-'; 0 for anything else.
static void span_aa (gfx_canvas_t *c, float x0, float x1, int y, gfx_color_t col)
 One antialiased scanline from x0 to x1 on row y.
static float slant_at (const gfx_seg_style_t *st, float y_from_foot)
 The lean y_from_foot px above the foot, as a fraction of a pixel rather than a whole one – an integer slant is a staircase down the side of every digit, which is exactly the artefact the tapers below are being smoothed to avoid.
static void bar_h (gfx_canvas_t *c, float x, int y, float w, int t, const gfx_seg_style_t *st, int foot, gfx_color_t col)
 A horizontal bar from x, w long, t thick, from row y.
static void bar_v (gfx_canvas_t *c, float x, int y, int h, int t, const gfx_seg_style_t *st, int foot, gfx_color_t col)
 A vertical bar at x, h tall, t thick, from row y; the same hexagon as bar_h() stood on its end.
static bool digit_meets_clip (const gfx_canvas_t *c, int x, int y, const gfx_seg_style_t *st)
 Whether a digit's cell at (x, y) reaches the clip of c: the cell, its slant either way and the pixel a blended edge spills into. A cell wholly outside draws nothing, so its bars are not walked.
static void digit (gfx_canvas_t *c, int x, int y, const gfx_seg_style_t *st, uint8_t segs, gfx_color_t col)
 The bars segs of a digit's cell at (x, y) in col; nothing when the cell lies outside the clip.
static int punct_w (const gfx_seg_style_t *st)
 The cell of a dot or a colon, px. They are not segments, so they get their own cells and their own narrower advance – a full digit cell of whitespace around a decimal point is what makes rendered numbers look spaced by accident.
int gfx_seg_width (const char *s, const gfx_seg_style_t *st)
int gfx_seg_text (gfx_canvas_t *c, int x, int y, const char *s, const gfx_seg_style_t *st, gfx_color_t on, gfx_color_t off)

Detailed Description

Seven-segment numerals, drawn rather than stored.

A bitmap face cannot show the segments that are off, and a segment display has all seven in the glass whether they are lit or not; the faint ghost of an 8 behind every digit is what makes it read as an instrument. The digits are rasterised from their segment masks, so one routine serves every size the bench asks for instead of a table per size.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ SEG_A

#define SEG_A   0x01u

the top bar

◆ SEG_ALL

#define SEG_ALL   0x7Fu

all seven: an 8

◆ SEG_B

#define SEG_B   0x02u

the upper right bar

◆ SEG_C

#define SEG_C   0x04u

the lower right bar

◆ SEG_D

#define SEG_D   0x08u

the bottom bar

◆ SEG_E

#define SEG_E   0x10u

the lower left bar

◆ SEG_F

#define SEG_F   0x20u

the upper left bar

◆ SEG_G

#define SEG_G   0x40u

the middle bar

Function Documentation

◆ bar_h()

void bar_h ( gfx_canvas_t * c,
float x,
int y,
float w,
int t,
const gfx_seg_style_t * st,
int foot,
gfx_color_t col )
static

A horizontal bar from x, w long, t thick, from row y.

Both bar shapes are hexagons: square ends would butt into each other at the corners and read as a rectangle with a notch. The taper is half the thickness at each end, so two bars meeting at a corner leave a clean diagonal gap.

The tapers are 45 degrees and cross the pixel grid diagonally, so their edges are carried in floating point and blended per row; integer steps staircase.

◆ digit_meets_clip()

bool digit_meets_clip ( const gfx_canvas_t * c,
int x,
int y,
const gfx_seg_style_t * st )
static

Whether a digit's cell at (x, y) reaches the clip of c: the cell, its slant either way and the pixel a blended edge spills into. A cell wholly outside draws nothing, so its bars are not walked.

Parameters
cthe canvas
xthe cell's left edge, px
yits top, px
stthe style
Returns
true when some of the cell is inside the clip

◆ gfx_seg_text()

int gfx_seg_text ( gfx_canvas_t * c,
int x,
int y,
const char * s,
const gfx_seg_style_t * st,
gfx_color_t on,
gfx_color_t off )

Draw s as segment digits. Returns the width drawn.

◆ gfx_seg_width()

int gfx_seg_width ( const char * s,
const gfx_seg_style_t * st )

Width s would occupy, without drawing it.

◆ mask_for()

uint8_t mask_for ( char ch)
static

The bars ch lights: a digit or '-'; 0 for anything else.

Parameters
chthe character
Returns
the bars, SEG_A to SEG_G

◆ span_aa()

void span_aa ( gfx_canvas_t * c,
float x0,
float x1,
int y,
gfx_color_t col )
static

One antialiased scanline from x0 to x1 on row y.

The interior goes through gfx_hline unchanged (whole pixels, nothing to blend) and only the two ends, where a fractional edge lands, read the destination back. A segment costs one hline plus two blends per row.