tags:

views:

35

answers:

0

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;
    }
    }
}