Montag, 11. Februar 2008

Runde Ecken in Neutrino

Wie erstellt man runde Ecken in Neutrino???

Als erstes muss wohl die Framebufferklasse von Neutrino angepasst werden.
Dazu habe ich zwei neue Funktionen integriert.
Eine Funktion dient dazu normale und die andere gefüllte Kreise zu zeichnen.

Die Funktionen für die framebuffer.cpp sind:

void CFrameBuffer::paintCircleFilled(int sx, int sy, int radius, const fb_pixel_t col, int type)
{
if (!getActive())
return;

int F = 1 - radius;
int ddF_x = 0;
int ddF_y = -2*radius;
int x = 0;
int y = radius;
bool paint_extraline = true;

while ( x <>= 0) {
y -= 1;
ddF_y += 2;
F += ddF_y;
}

x += 1;
ddF_x += 2;
F += ddF_x + 1;

switch (type)
{
case 0: // Full Circle
paintHLineRel(sx - x, (sx - (sx - x)) * 2, sy - y, col);
paintHLineRel(sx - y, (sx - (sx - y)) * 2, sy - x, col);
if (paint_extraline) {
paintHLineRel(sx - y, (sx - (sx - y)) * 2, sy + x - 1, col);
paint_extraline = false;
}
paintHLineRel(sx - x, (sx - (sx - x)) * 2, sy + y, col);
paintHLineRel(sx - y, (sx - (sx - y)) * 2, sy + x, col);
break;
case 1: // Left Upper Corner
paintHLineRel(sx - x, sx - (sx - x), sy - y, col);
paintHLineRel(sx - y, sx - (sx - y), sy - x, col);
break;
case 2: // Right Upper Corner
paintHLineRel(sx, (sx + x) - sx, sy - y, col);
paintHLineRel(sx, (sx + y) - sx, sy - x, col);
break;
case 3: // Left Lower Corner
paintHLineRel(sx - x, sx - (sx - x), sy + y, col);
paintHLineRel(sx - y, sx - (sx - y), sy + x, col);
break;
case 4: // Right Lower Corner
paintHLineRel(sx, (sx + x) - sx, sy + y, col);
paintHLineRel(sx, (sx + y) - sx, sy + x, col);
break;
default: ; /* nothing to do for default */
}
}
}

void CFrameBuffer::paintCircle(int sx, int sy, int radius, const fb_pixel_t col, int type)
{
if (!getActive())
return;

int F = 1 - radius;
int ddF_x = 0;
int ddF_y = -2*radius;
int x = 0;
int y = radius;

while ( x <>= 0) {
y -= 1;
ddF_y += 2;
F += ddF_y;
}
x += 1;
ddF_x += 2;
F += ddF_x + 1;

switch (type)
{
case 0: // Full Circle
paintPixel(sx + x, sy + y, col); paintPixel(sx - x, sy + y, col);
paintPixel(sx + x, sy - y, col); paintPixel(sx - x, sy - y, col);
paintPixel(sx + y, sy + x, col); paintPixel(sx - y, sy + x, col);
paintPixel(sx + y, sy - x, col); paintPixel(sx - y, sy - x, col);
break;
case 1: // Left Upper Corner
paintPixel(sx - x, sy - y, col); paintPixel(sx - y, sy - x, col);
break;
case 2: // Right Upper Corner
paintPixel(sx + x, sy - y, col); paintPixel(sx + y, sy - x, col);
break;
case 3: // Left Lower Corner
paintPixel(sx - x, sy + y, col); paintPixel(sx - y, sy + x, col);
break;
case 4: // Right Lower Corner
paintPixel(sx + x, sy + y, col); paintPixel(sx + y, sy + x, col);
break;
default: ; /* nothing to do for default */
}
}
}


Die Einträge für framebuffer.h

void paintCircle(int sx, int sy, int radius, const fb_pixel_t col, int type);
void paintCircleFilled(int sx, int sy, int radius, const fb_pixel_t col, int type);



Kurz eine Erläuterung zu den Funktionen:
int sx = Startpunkt X
int sy = Startpunkt Y
int radius = Radius
const fb_pixel_t col = Farbe (Linie oder gefüllt)
int type = die Form (Viertel / Voll)

als Typ gibt es folgendes Werte:
0 = Voller Kreis
1 = Viertelkreis als Corner Links/Oben
2 = Viertelkreis als Corner Rechts/Oben
3 = Viertelkreis als Corner Links/Unten
4 = Viertelkreis als Corner Rechts/Unten

Beispiel:
frameBuffer->paintCircleFilled(300, 300, 20, COL_INFOBAR_PLUS_7, 0);

Zeichnet einen Kreis mit einem Durchmesser von 40 Pixel mit Mittelpunkt bei 300x - 300y, mit Weiss gefüllt.

Die Vorgehensweise, so wie ich es immer mache, ist:

Rechteck zeichnen
BackgroundBox zeichnen mit Länge/Höhe vom Radius des Viertelkreises.
Viertelkreis (gefüllt) zeichnen.
Fertig! Wir haben eine runde Ecke...

Beispiel:

 frameBuffer->paintBoxRel(100, 100, 250, 250, COL_INFOBAR_PLUS_0);
frameBuffer->paintBackgroundBox(100, 100, 100 + 20, 100 + 20);
frameBuffer->paintCircleFilled(100 + 20, 100 + 20, 20, COL_INFOBAR_PLUS_0, 1);


Gruß

4 Kommentare:

Anonym hat gesagt…

klasse

Anonym hat gesagt…

Verbesserungs-/Erweiterungsvorschlag:

http://forum.tuxbox.org/forum/viewtopic.php?t=47540

Anonym hat gesagt…

Nettes Blog! Bitte mehr davon! :-D

EcoSys hat gesagt…

Danke für die Komentare ;)

Zum Kommentar: Verbesserungs-/Erweiterungsvorschlag
möchte ich hinzufügen.

Wenn Ihr etwas mit runden Ecken machen wollt, dann besucht den Link und schaut Euch das dort an.
Die Variante dort ist besser als die hier vorgestellte.

Nicht umsonst wirke ich da mit.

Gruß
flasher (EcoSys)