Forum: Compiler & IDEs GLCD Font Probleme (wahrscheinlich Pointer)


von N. G. (newgeneration) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo Forum,

ich schreibe gerade an einer Lib für ein GLCD (128x64).
Eigentlich funktioniert schon alles, aber:
ich will eine Funktion, die die aktuelle Schriftart auswählt, sodass ich 
insgesamt mehrere verschiedene Fonts haben kann.

Anbei mal der aktuelle Code (nicht aufgeräumt).
Ich vermute es liegt an der Funktion setFont, bzw. der Pointer-Operation 
darin.

Hier noch die mMn kritischen Stellen (für die die nicht alles anschauen 
wollen):

In fonts.h habe ich einen typedef für die verschiedenen Fonts und die 
Deklarationen von den Schriftarten:
1
typedef struct {
2
  const uint8_t width;
3
  const uint8_t height;
4
  const uint8_t text[]; //macht das das was ich will?
5
} font_t;
6
7
extern const __flash font_t dogm_font_6x8;
8
extern const __flash font_t dogm_font_4x6;

Die Font-Files sehen so aus:
1
const __flash font_t dogm_font_6x8 = {  //font 6x8 normal
2
    .width = 6,
3
    .height = 8,
4
    .text = { //font data
5
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //die einzelnen Zeichen
6
        ...
7
        }};

und in der Haupt-Display-Datei:
1
static const font_t *currentFont;
2
3
void dogm_setFont(const font_t font) {
4
  currentFont = &font; //hier koennte das Problem sein
5
}
6
7
void dogm_setPos(uint8_t x, uint8_t y) {
8
  uint8_t i = 0;
9
  if (x > 127)
10
    dogm_setPos(0, y +          // hier die beiden moeglichkeiten: 
11
      currentFont->height);     //funktioniert nicht
12
      //dogm_font_6x8.height);  //funktioniert
13
  else {
14
    currentPosX = x;
15
    currentPosY = y + (i *      //hier die beiden moeglichkeiten: 
16
      currentFont->height);     //funktioniert nicht
17
      //dogm_font_6x8.height);  //funktioniert
18
  }
19
}
20
21
void dogm_putc(uint8_t c) {
22
  if (currentFont == 0) {
23
    return;
24
  }
25
  uint8_t width = currentFont->width;    //funktioniert nicht
26
  //uint8_t width = dogm_font_6x8.width; //funktioniert
27
  if (currentPosX + width > 127)
28
    dogm_setPos(currentPosX + width, currentPosY);
29
  for (uint8_t i = 0; i < width; i++)
30
    disp_ram[(currentPosY >> 3) + ((currentPosX + i) << 3)] =
31
      currentFont->text[c * width + i]; //funktioniert nicht
32
      //dogm_font_6x8.text[c*width+i];  //funktioniert
33
  dogm_setPos(currentPosX + width, currentPosY);
34
}

Also es wäre schön wenn jemand mal einen Blick riskieren könnte und 
schauen ob es überhaupt so geht wie ich will.

Ohne diesen Schriftartenwechsel geht alles einwandfrei (okay, man kann 
über den Shadow-RAM streiten, aber aktuell geht es ;) )

Danke im Vorraus
N.G.

von Stefan E. (sternst)


Lesenswert?

1
void dogm_setFont(const font_t font) {
2
  currentFont = &font; //hier koennte das Problem sein
3
}
Einen globalen Pointer auf eine funktions-lokale Variable, die nach dem 
Ende der Funktion gar nicht mehr existiert, zeigen zu lassen, ist in der 
Tat eine ziemlich schlechte Idee.

von N. G. (newgeneration) Benutzerseite


Lesenswert?

Hallo Stefan,

Stefan E. schrieb:
> Einen globalen Pointer auf eine funktions-lokale Variable, die nach
> dem Ende der Funktion gar nicht mehr existiert, zeigen zu lassen, ist in
> der Tat eine ziemlich schlechte Idee.

Du meinst die Zuweisung ist schon richtig, aber bei Verlassen der 
Funktion wird die lokale Variable zerstört und der Pointer zeigt auf nix 
sinnvolles mehr?
Habe davon noch nie etwas gehört, aber ist ja irgendwie auch logisch...
So nun zum Quick-Fix:
Wie umgehen ich das? Mit einem Pointer als Parameter? Oder ganz anders?

Danke schon mal

von Karl H. (kbuchegg)


Lesenswert?

Da gibts noch ein paar mehr 'Probleme'.

Was willst du denn effektiv erreichen? Im Endeffekt soll doch alles 
darauf hinauslaufen, dass es zb auf ein
1
  currentFont = &dogm_font_6x8;

hinausläuft.
Denn dann ist currentFont ja als Zeiger so eingerichtet, dass er die 
Adresse des Fonts enthält derr benutzt werden soll.

Dazu müssen aber die Datentypen stimmen.
dogm_font_6x8 hat welchen Datentyp?
1
...   const __flash font_t dogm_font_6x8;
2
      ********************

Und worauf kann currentFont zeigen?
1
  ... const font_t *currentFont;
2
3
      ************

tja. Fast. dogm_font_6x8  hat noch die Attributierung '__flash' und es 
ist auch wichtig, dass die nicht verloren geht!
D.h. aber auch: dein Pointer muss auch in der Lage sein, auf etwas zu 
zeigen, was im Flash residiert.
1
  ... const __flash font_t *currentFont;

so, jetzt tut er das.

Wenn das Ziel darin besteht, dass letzten Endes der Effekt von
1
  currentFont = &dogm_font_6x8;

sich ergeben soll UND du das ganze über eine Funktion abwickeln willst, 
dann wirst du wohl nicht umhin kommen, dass der ganze rechte Teil der 
Zuweisung als Funktionsargument an eine Funktion übergeben wird.

D.h. du willst deinen Aufruf so gestalten
1
...
2
   dogm_setFont( &dogm_font_6x8 );
3
...

damit das möglich ist, muss daher die Funktions Argument Schnittstelle 
wie aussehen?

von N. G. (newgeneration) Benutzerseite


Lesenswert?

D.h. ich muss die Methode so abändern?
1
static const __flash font_t *currentFont;
2
3
void dogm_setFont(const __flash font_t *font) {
4
  currentFont = font; // kann ich das dann einfach so zuweisen?
5
}

Danke schon mal für die ausführliche Erklärung

von N. G. (newgeneration) Benutzerseite


Lesenswert?

Okay, danke an alle, mit den obigen Änderungen geht es jetzt thumbs up

von Eric B. (beric)


Lesenswert?

N. G. schrieb:
1
> typedef struct {
2
>   const uint8_t width;
3
>   const uint8_t height;
4
>   const uint8_t text[]; //macht das das was ich will?
5
> } font_t;
6
> 
7
> extern const __flash font_t dogm_font_6x8;
8
> extern const __flash font_t dogm_font_4x6;

N. G. schrieb:
> Okay, danke an alle, mit den obigen Änderungen geht es jetzt thumbs up

Sicher?  Beschwert sich der Compiler nicht an der Stelle wo du schreibst 
"macht das das was ich will?" ??

von Karl H. (kbuchegg)


Lesenswert?


von W.S. (Gast)


Lesenswert?

N. G. schrieb:
> ich schreibe gerade an einer Lib für ein GLCD (128x64).
> Eigentlich funktioniert schon alles, aber:
> ich will eine Funktion, die die aktuelle Schriftart auswählt, sodass ich
> insgesamt mehrere verschiedene Fonts haben kann.

Soweit ich das in deinen geposteten Dateien sehen kann, bist du 
ausgesprochen wirr an die ganze Sache herangegangen. Ich rate dir 
deshalb dringendst, das Ganze in die Tonne zu hauen und nochmal ganz von 
vorn anzufangen.

Du brauchst etwas, das man ein grafisches Frontend oder GDI nennen 
könnte, was all die Funktionen enthält, die man eben so zum Benutzen 
eines GLCD's braucht. Also Punkte setzen, Linien zeichnen, Blöcke 
einfärben, Text an beliebigen Positionen zeichnen und so. OK, du 
brauchst dazu auch Fonts.

Mein Rat: guck dir gdi.c, gdi.h und die fonts in der Lernbetty hier im 
Forum an, da ist bereits fast alles enthalten, was du brauchst. All 
dieses arbeitet auf einem RAM-internen Bildspeicher, der nach 
"Beschmutzung" sprich Modifilation anschließend ins Display geschaufelt 
wird. Ich glaub, ich hatte das sogar selektiv getan aus 
Geschwindigkeitsgründen.

Einen kleinen Fontcompiler hat's dazu auch, wo du dir quasi 
symbolgrafisch einen Font nach deinem Gusto kreieren kannst. Selbst ein 
kleiner Bilder-Compiler ist dabei (Bild-->Cquelle).

Nochwas zu Fonts: Es verstehen viele Leute den Umstand nicht, daß man 
beim Anwenden von Fonts Ascent und Descent beachten sollte, also die 
Quasi-Schreiblinie in einer Zeile gleichhalten sollte - sonst sieht's 
doof aus. Dazu braucht es aber die entsprechenden Angaben im Font - und 
sowas vermisse ich bei deinen Dateien komplett.

W.S.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.