LCD4Linux has some code where it inserts "errors" into some data regarding status bars. Character LCDs are usually limited to 8 special characters that are basically 7x8 pixel fonts, and you can draw on each font with whatever shapes you want within that space.
Anyone know where I can find information on similar algorithms?
Here's the related code.
static int drv_generic_text_bar_segment_error(const int i, const int j)
{
int res;
int i1, i2, j1, j2;
if (i == j)
return 65535;
if (!(Segment[i].dir & Segment[j].dir))
return 65535;
if (Segment[i].style != Segment[j].style)
return 65535;
res = Segment[i].dir & (DIR_EAST | DIR_WEST) ? XRES : YRES;
i1 = Segment[i].val1;
if (i1 > res)
i1 = res;
i2 = Segment[i].val2;
if (i2 > res)
i2 = res;
j1 = Segment[j].val1;
if (j1 > res)
j1 = res;
j2 = Segment[j].val2;
if (j2 > res)
j2 = res;
/* do not replace empty with non-empty */
if (i1 == 0 && j1 != 0)
return 65535;
if (i2 == 0 && j2 != 0)
return 65535;
/* do not replace full with non-full */
if (i1 == res && j1 < res)
return 65535;
if (i2 == res && j2 < res)
return 65535;
/* do not replace start line */
/* but only if there are at least some chars available */
if (CHARS - ICONS > 0) {
if (i1 == 1 && j1 != 1 && i2 > 0)
return 65535;
if (i2 == 1 && j2 != 1 && j1 > 0)
return 65535;
}
/* do not replace equal length with non-equal length */
if (i1 == i2 && j1 != j2)
return 65535;
return (i1 - j1) * (i1 - j1) + (i2 - j2) * (i2 - j2);
}
static void drv_generic_text_bar_pack_segments(void)
{
int i, j, n, min;
int pack_i, pack_j;
int pass1 = 1;
int error[nSegment][nSegment];
if (nSegment <= fSegment + CHARS - ICONS) {
return;
}
for (i = 0; i < nSegment; i++) {
for (j = 0; j < nSegment; j++) {
error[i][j] = drv_generic_text_bar_segment_error(i, j);
/* debug ("[%d][%d] = %d", i, j, error[i][j]); */
}
}
while (nSegment > fSegment + CHARS - ICONS) {
min = 65535;
pack_i = -1;
pack_j = -1;
for (i = fSegment; i < nSegment; i++) {
if (pass1 && Segment[i].used)
continue;
for (j = 0; j < nSegment; j++) {
if (error[i][j] < min) {
min = error[i][j];
pack_i = i;
pack_j = j;
}
}
}
if (pack_i == -1) {
if (pass1) {
pass1 = 0;
continue;
} else {
error("unable to compact bar characters");
error("nSegment=%d fSegment=%d CHARS=%d ICONS=%d", nSegment, fSegment, CHARS, ICONS);
error("Segment[0].val1=%d val2=%d", Segment[0].val1, Segment[0].val2);
error("Segment[1].val1=%d val2=%d", Segment[1].val1, Segment[1].val2);
error("Segment[2].val1=%d val2=%d", Segment[2].val1, Segment[2].val2);
nSegment = CHARS - ICONS;
break;
}
}
#if 0
debug("pack_segment: n=%d i=%d j=%d min=%d", nSegment, pack_i, pack_j, min);
debug("Pack_segment: i1=%d i2=%d j1=%d j2=%d\n", Segment[pack_i].val1, Segment[pack_i].val2,
Segment[pack_j].val1, Segment[pack_j].val2);
#endif
nSegment--;
Segment[pack_i] = Segment[nSegment];
for (i = 0; i < nSegment; i++) {
error[pack_i][i] = error[nSegment][i];
error[i][pack_i] = error[i][nSegment];
}
for (n = 0; n < LROWS * LCOLS; n++) {
if (BarFB[n].segment == pack_i)
BarFB[n].segment = pack_j;
if (BarFB[n].segment == nSegment)
BarFB[n].segment = pack_i;
}
}
}