Chars in C (PI5): Unterschied zwischen den Versionen
Die Seite wurde neu angelegt: „== Zeichnen von Zeichen auf dem Raspberry Pi == Nachdem wir eine Funktion zum Setzen einzelner Pixel implementiert haben, möchten wir nun dem Raspberry Pi beibringen, Text auf dem Bildschirm anzuzeigen. Texte bestehen aus Schriftzeichen, die der Computer nicht von Natur aus kennt. Ähnlich wie ein Mensch muss der Computer zunächst "lernen", wie jedes einzelne Zeichen aussieht, bevor er es darstellen kann. Diese Zeichen sind in einem bestimmten Code defi…“ |
|||
| (8 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 11: | Zeile 11: | ||
! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! | ! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! | ||
|- | |- | ||
! !! | ! !! 0x0 !! 0x1 !! 0x2 !! 0x3 !! 0x4 !! 0x5 !! 0x6 !! 0x7 !! 0x8 !! 0x9 !! 0xA !! 0xB !! 0xC !! 0xD !! 0xE !! 0xF | ||
|- | |- | ||
! 0x0 | ! 0x0 | ||
| Zeile 60: | Zeile 60: | ||
! 0xF | ! 0xF | ||
| ≡ || ± || ≥ || ≤ || ⌠ || ⌡ || ÷ || ≈ || ° || • || · || √ || ⁿ || ² || ■ || | | ≡ || ± || ≥ || ≤ || ⌠ || ⌡ || ÷ || ≈ || ° || • || · || √ || ⁿ || ² || ■ || | ||
|} | |||
== Erstellen einer Schriftart (Font) == | |||
Um den Computer in die Lage zu versetzen, Zeichen darzustellen, müssen wir ihm zeigen, wie jedes Zeichen aussieht. Dazu erstellen wir eine Art Datenbank, in der jedes Zeichen als ein 8x8-Pixel-Muster beschrieben wird. | |||
Beispielsweise könnte die Datei, die diese Zeichen beschreibt, folgendermaßen aussehen: | |||
<syntaxhighlight lang="C"> | |||
/* 8x8 FONT by Satyria */ | |||
/* Dimension */ | |||
#define FONT_WIDTH 8 | |||
#define FONT_HEIGHT 8 | |||
#define FONT_MAX 256 | |||
unsigned char font[256][8] = { | |||
// Data | |||
// 0 NULL | |||
{ | |||
0b00000000, | |||
0b00000000, | |||
0b00000000, | |||
0b00000000, | |||
0b00000000, | |||
0b00000000, | |||
0b00000000, | |||
0b00000000 | |||
}, | |||
... Weitere Zeichen | |||
{ | |||
// 65 A | |||
0b00011000, | |||
0b00111100, | |||
0b00111100, | |||
0b01100110, | |||
0b01111110, | |||
0b11000011, | |||
0b11000011, | |||
0b00000000 | |||
},{ | |||
// 66 B | |||
0b11111100, | |||
0b01100110, | |||
0b01100110, | |||
0b01111100, | |||
0b01100110, | |||
0b01100110, | |||
0b11111100, | |||
0b00000000 | |||
}, | |||
... | |||
</syntaxhighlight> | |||
In diesem Beispiel wird das Zeichen "A" als ein 8x8-Pixel großes Muster beschrieben, wobei jedes Byte eine Zeile des Musters darstellt. Jedes Bit in diesem Byte steht für einen Pixel: Ein gesetztes Bit (1) bedeutet, dass der Pixel in der Vordergrundfarbe gezeichnet wird, während ein nicht gesetztes Bit (0) bedeutet, dass der Pixel in der Hintergrundfarbe gezeichnet wird. | |||
Mein Beispiel für die Schriftart habe ich als "ms8x8font.fon" im Includeverzeichnis abgelegt. | |||
== Zeichnen von Zeichen auf dem Bildschirm: DrawChar-Funktion == | |||
Die Funktion DrawChar zeichnet ein einzelnes Zeichen an einer bestimmten Position auf dem Bildschirm. Hier ist der vollständige Code der Funktion: | |||
<syntaxhighlight lang="C"> | |||
void DrawChar(char c, u32 x0, u32 y0) | |||
{ | |||
unsigned char *sym = font[(unsigned char)c]; | |||
for (u32 i = 0; i < FONT_HEIGHT; i++) | |||
{ | |||
for (u32 j = 0; j < FONT_WIDTH; j++) | |||
{ | |||
u32 check = (sym[i] >> (7 - j)) & 1; | |||
if (check == 1) | |||
{ | |||
DrawColor = FrontColor; | |||
} | |||
else | |||
{ | |||
DrawColor = BackColor; | |||
} | |||
DrawPixel(x0 + j, y0 + i); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
== Erklärung der Funktion == | |||
'''Funktionskopf''': | |||
<syntaxhighlight lang="C"> | |||
void DrawChar(char c, u32 x0, u32 y0) | |||
</syntaxhighlight> | |||
* <syntaxhighlight lang="C" inline>void</syntaxhighlight> bedeutet, dass die Funktion keinen Wert zurückgibt. | |||
* <syntaxhighlight lang="C" inline>char c</syntaxhighlight> ist das Zeichen, das gezeichnet werden soll. | |||
* <syntaxhighlight lang="C" inline>u32 x0</syntaxhighlight> und <syntaxhighlight lang="C" inline>u32 y0</syntaxhighlight> sind die x- und y-Koordinaten auf dem Bildschirm, an denen das Zeichen beginnen soll. | |||
'''Zeiger auf das Zeichen im Font-Array''': | |||
<syntaxhighlight lang="C"> | |||
unsigned char *sym = font[(unsigned char)c]; | |||
</syntaxhighlight> | |||
* <syntaxhighlight lang="C" inline>unsigned char *sym</syntaxhighlight> ist ein Zeiger auf das 8x8-Pixel-Muster des Zeichens. | |||
* <syntaxhighlight lang="C" inline>font[(unsigned char)c]</syntaxhighlight> greift auf das entsprechende Zeichenmuster im font-Array zu. Jedes Zeichen wird durch ein 8x8-Pixel-Muster dargestellt. | |||
'''Äußere Schleife: Zeilen durchlaufen''': | |||
<syntaxhighlight lang="C"> | |||
for (u32 i = 0; i < FONT_HEIGHT; i++) | |||
</syntaxhighlight> | |||
* Diese Schleife durchläuft jede Zeile des 8x8-Pixel-Musters. | |||
* <syntaxhighlight lang="C" inline>u32 i</syntaxhighlight> ist die aktuelle Zeile im Pixel-Muster (von 0 bis 7). | |||
'''Innere Schleife: Spalten durchlaufen''': | |||
<syntaxhighlight lang="C"> | |||
for (u32 j = 0; j < FONT_WIDTH; j++) | |||
</syntaxhighlight> | |||
* Diese Schleife durchläuft jede Spalte der aktuellen Zeile. | |||
* <syntaxhighlight lang="C" inline>u32 j</syntaxhighlight> ist die aktuelle Spalte im Pixel-Muster (von 0 bis 7). | |||
'''Prüfen, ob das Bit gesetzt ist''': | |||
<syntaxhighlight lang="C"> | |||
u32 check = (sym[i] >> (7 - j)) & 1; | |||
</syntaxhighlight> | |||
* <syntaxhighlight lang="C" inline>sym[i]</syntaxhighlight> lädt das Byte der aktuellen Zeile. | |||
* <syntaxhighlight lang="C" inline>>> (7 - j)</syntaxhighlight> verschiebt die Bits nach rechts, sodass das Bit, das wir prüfen wollen, an der niedrigsten Stelle steht. | |||
* <syntaxhighlight lang="C" inline>& 1</syntaxhighlight> maskiert alle anderen Bits außer dem niedrigsten Bit. Das Ergebnis ist entweder 1 (Bit gesetzt) oder 0 (Bit nicht gesetzt). | |||
'''Setzen der Zeichenfarbe''': | |||
<syntaxhighlight lang="C"> | |||
if (check == 1) | |||
{ | |||
DrawColor = FrontColor; | |||
} | |||
else | |||
{ | |||
DrawColor = BackColor; | |||
} | |||
</syntaxhighlight> | |||
* Wenn <syntaxhighlight lang="C" inline>check</syntaxhighlight> 1 ist, bedeutet das, dass das Bit gesetzt ist, und wir setzen die Zeichenfarbe (<syntaxhighlight lang="C" inline>DrawColor</syntaxhighlight>) auf die Vordergrundfarbe (<syntaxhighlight lang="C" inline>FrontColor</syntaxhighlight>). | |||
* Wenn <syntaxhighlight lang="C" inline>check</syntaxhighlight> 0 ist, setzen wir die Zeichenfarbe auf die Hintergrundfarbe (<syntaxhighlight lang="C" inline>BackColor</syntaxhighlight>). | |||
'''Zeichnen des Pixels''': | |||
<syntaxhighlight lang="C"> | |||
DrawPixel(x0 + j, y0 + i); | |||
</syntaxhighlight> | |||
* <syntaxhighlight lang="C" inline>DrawPixel</syntaxhighlight> zeichnet den Pixel an der Position <syntaxhighlight lang="C" inline>(x0 + j, y0 + i)</syntaxhighlight>. | |||
* <syntaxhighlight lang="C" inline>x0 + j</syntaxhighlight> gibt die x-Koordinate des aktuellen Pixels an. | |||
* <syntaxhighlight lang="C" inline>y0 + i</syntaxhighlight> gibt die y-Koordinate des aktuellen Pixels an. | |||
== Zusammenfassung == | |||
Die <syntaxhighlight lang="C" inline>DrawChar</syntaxhighlight>-Funktion durchläuft das 8x8-Pixel-Muster eines Zeichens und zeichnet jeden Pixel an der entsprechenden Position auf dem Bildschirm. Die Farbe des Pixels hängt davon ab, ob das entsprechende Bit im Pixel-Muster gesetzt ist oder nicht. | |||
Du kannst den Source-Code als ZIP-Datei mit folgenden Link downloaden: https://www.satyria.de/arm/sources/C/chars.zip | |||
----- | |||
{| style="width: 100%; | |||
| style="width: 33%;" | [[Grafik in C (PI5)|< Zurück (Grafik in C (PI5))]] | |||
| style="width: 33%; text-align:center;" | [[Hauptseite|< Hauptseite >]] | |||
| style="width: 33%; text-align:right;" | [[Das Terminal in C (PI5)|Weiter (Das Terminal in C (PI5)) >]] | |||
|} | |} | ||
Aktuelle Version vom 22. Februar 2025, 11:27 Uhr
Zeichnen von Zeichen auf dem Raspberry Pi
Nachdem wir eine Funktion zum Setzen einzelner Pixel implementiert haben, möchten wir nun dem Raspberry Pi beibringen, Text auf dem Bildschirm anzuzeigen. Texte bestehen aus Schriftzeichen, die der Computer nicht von Natur aus kennt. Ähnlich wie ein Mensch muss der Computer zunächst "lernen", wie jedes einzelne Zeichen aussieht, bevor er es darstellen kann. Diese Zeichen sind in einem bestimmten Code definiert, den der Computer versteht. Einer der am weitesten verbreiteten Codes ist der ANSI-Zeichencode.
Der ANSI-Zeichencode
Der ANSI-Zeichencode, den wir hier verwenden, ist eine Erweiterung des ursprünglichen ASCII-Codes. Während ASCII ursprünglich nur 7-Bit pro Zeichen verwendete, erweitert ANSI dies auf 8-Bit, was einem Byte entspricht. Der ANSI-Code wurde entwickelt, als Computer über Netzwerke kommunizieren mussten und sicherstellen wollten, dass beide Seiten dieselben Zeichen verwenden. Die ersten 128 Zeichen im ANSI-Code stimmen mit dem ASCII-Code überein, aber die Zeichen 128 bis 255 können je nach verwendeter Codepage variieren.
Wir verwenden hier die "Codepage 437", die ursprünglich von IBM für MS-DOS-Rechner entwickelt wurde und auch heute noch in der Windows-Kommandozeile verwendet wird.
| 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 | 0x7 | 0x8 | 0x9 | 0xA | 0xB | 0xC | 0xD | 0xE | 0xF | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0x0 | NULL | ☺ | ☻ | ♥ | ♦ | ♣ | ♠ | • | ◘ | ○ | ◙ | ♂ | ♀ | ♪ | ♫ | ☼ |
| 0x1 | ► | ◄ | ↕ | ‼ | ¶ | § | ▬ | ↨ | ↑ | ↓ | → | ← | ∟ | ↔ | ▲ | ▼ |
| 0x2 | Space | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / |
| 0x3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
| 0x4 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
| 0x5 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
| 0x6 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
| 0x7 | p | q | r | s | t | u | v | w | x | y | z | { | } | ~ | DEL | |
| 0x8 | Ç | ü | é | â | ä | à | å | ç | ê | ë | è | ï | î | ì | Ä | Å |
| 0x9 | É | æ | Æ | ô | ö | ò | û | ù | ÿ | Ö | Ü | ¢ | £ | ¥ | ₧ | ƒ |
| 0xA | á | í | ó | ú | ñ | Ñ | ª | º | ¿ | ⌐ | ¬ | ½ | ¼ | ¡ | « | » |
| 0xB | ░ | ▒ | ▓ | │ | ┤ | ╡ | ╢ | ╖ | ╕ | ╣ | ║ | ╗ | ╝ | ╜ | ╛ | ┐ |
| 0xC | └ | ┴ | ┬ | ├ | ─ | ┼ | ╞ | ╟ | ╚ | ╔ | ╩ | ╦ | ╠ | ═ | ╬ | ╧ |
| 0xD | ╨ | ╤ | ╥ | ╙ | ╘ | ╒ | ╓ | ╪ | ┘ | ┌ | █ | ▄ | ▌ | ▐ | ▀ | |
| 0xE | α | ß | Γ | π | Σ | σ | µ | τ | Φ | Θ | Ω | δ | ∞ | φ | ε | ∩ |
| 0xF | ≡ | ± | ≥ | ≤ | ⌠ | ⌡ | ÷ | ≈ | ° | • | · | √ | ⁿ | ² | ■ |
Erstellen einer Schriftart (Font)
Um den Computer in die Lage zu versetzen, Zeichen darzustellen, müssen wir ihm zeigen, wie jedes Zeichen aussieht. Dazu erstellen wir eine Art Datenbank, in der jedes Zeichen als ein 8x8-Pixel-Muster beschrieben wird.
Beispielsweise könnte die Datei, die diese Zeichen beschreibt, folgendermaßen aussehen:
/* 8x8 FONT by Satyria */
/* Dimension */
#define FONT_WIDTH 8
#define FONT_HEIGHT 8
#define FONT_MAX 256
unsigned char font[256][8] = {
// Data
// 0 NULL
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
},
... Weitere Zeichen
{
// 65 A
0b00011000,
0b00111100,
0b00111100,
0b01100110,
0b01111110,
0b11000011,
0b11000011,
0b00000000
},{
// 66 B
0b11111100,
0b01100110,
0b01100110,
0b01111100,
0b01100110,
0b01100110,
0b11111100,
0b00000000
},
...
In diesem Beispiel wird das Zeichen "A" als ein 8x8-Pixel großes Muster beschrieben, wobei jedes Byte eine Zeile des Musters darstellt. Jedes Bit in diesem Byte steht für einen Pixel: Ein gesetztes Bit (1) bedeutet, dass der Pixel in der Vordergrundfarbe gezeichnet wird, während ein nicht gesetztes Bit (0) bedeutet, dass der Pixel in der Hintergrundfarbe gezeichnet wird.
Mein Beispiel für die Schriftart habe ich als "ms8x8font.fon" im Includeverzeichnis abgelegt.
Zeichnen von Zeichen auf dem Bildschirm: DrawChar-Funktion
Die Funktion DrawChar zeichnet ein einzelnes Zeichen an einer bestimmten Position auf dem Bildschirm. Hier ist der vollständige Code der Funktion:
void DrawChar(char c, u32 x0, u32 y0)
{
unsigned char *sym = font[(unsigned char)c];
for (u32 i = 0; i < FONT_HEIGHT; i++)
{
for (u32 j = 0; j < FONT_WIDTH; j++)
{
u32 check = (sym[i] >> (7 - j)) & 1;
if (check == 1)
{
DrawColor = FrontColor;
}
else
{
DrawColor = BackColor;
}
DrawPixel(x0 + j, y0 + i);
}
}
}
Erklärung der Funktion
Funktionskopf:
void DrawChar(char c, u32 x0, u32 y0)
voidbedeutet, dass die Funktion keinen Wert zurückgibt.char cist das Zeichen, das gezeichnet werden soll.u32 x0undu32 y0sind die x- und y-Koordinaten auf dem Bildschirm, an denen das Zeichen beginnen soll.
Zeiger auf das Zeichen im Font-Array:
unsigned char *sym = font[(unsigned char)c];
unsigned char *symist ein Zeiger auf das 8x8-Pixel-Muster des Zeichens.font[(unsigned char)c]greift auf das entsprechende Zeichenmuster im font-Array zu. Jedes Zeichen wird durch ein 8x8-Pixel-Muster dargestellt.
Äußere Schleife: Zeilen durchlaufen:
for (u32 i = 0; i < FONT_HEIGHT; i++)
- Diese Schleife durchläuft jede Zeile des 8x8-Pixel-Musters.
u32 iist die aktuelle Zeile im Pixel-Muster (von 0 bis 7).
Innere Schleife: Spalten durchlaufen:
for (u32 j = 0; j < FONT_WIDTH; j++)
- Diese Schleife durchläuft jede Spalte der aktuellen Zeile.
u32 jist die aktuelle Spalte im Pixel-Muster (von 0 bis 7).
Prüfen, ob das Bit gesetzt ist:
u32 check = (sym[i] >> (7 - j)) & 1;
sym[i]lädt das Byte der aktuellen Zeile.>> (7 - j)verschiebt die Bits nach rechts, sodass das Bit, das wir prüfen wollen, an der niedrigsten Stelle steht.& 1maskiert alle anderen Bits außer dem niedrigsten Bit. Das Ergebnis ist entweder 1 (Bit gesetzt) oder 0 (Bit nicht gesetzt).
Setzen der Zeichenfarbe:
if (check == 1)
{
DrawColor = FrontColor;
}
else
{
DrawColor = BackColor;
}
- Wenn
check1 ist, bedeutet das, dass das Bit gesetzt ist, und wir setzen die Zeichenfarbe (DrawColor) auf die Vordergrundfarbe (FrontColor). - Wenn
check0 ist, setzen wir die Zeichenfarbe auf die Hintergrundfarbe (BackColor).
Zeichnen des Pixels:
DrawPixel(x0 + j, y0 + i);
DrawPixelzeichnet den Pixel an der Position(x0 + j, y0 + i).x0 + jgibt die x-Koordinate des aktuellen Pixels an.y0 + igibt die y-Koordinate des aktuellen Pixels an.
Zusammenfassung
Die DrawChar-Funktion durchläuft das 8x8-Pixel-Muster eines Zeichens und zeichnet jeden Pixel an der entsprechenden Position auf dem Bildschirm. Die Farbe des Pixels hängt davon ab, ob das entsprechende Bit im Pixel-Muster gesetzt ist oder nicht.
Du kannst den Source-Code als ZIP-Datei mit folgenden Link downloaden: https://www.satyria.de/arm/sources/C/chars.zip
| < Zurück (Grafik in C (PI5)) | < Hauptseite > | Weiter (Das Terminal in C (PI5)) > |