www.mikrocontroller.net

Forum: Compiler & IDEs Fonts in Array übergeben mit offset


Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo


Ich habe ein array mit Fontdaten.

Will zum bsp eine 0 ausgaben das offset liegt bei 360.


wenn ich die daten übergebe mache ich es so


&font_data,X,Y,width,height,layer

wenn ich nur die null in font_data habe geht es

aber wenn ich  &font_data+360 mache geht es nicht


wie kann ich den Zeiger auf die Position bringen???


Danke

gibt es auch irgendwie eine möglich keit den Text mit sprintf()
den kompletten text als einheit auszugeben.


Danke

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Stephan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne jetzt mehr von Deinem Code gesehen zu haben, brauchst Du wohl so 
was hier:

(&(font_data+360)),X,Y,width,height,layer

Man korrigiere mich bitte, wenn ich falsch liege (nachdem mehr Code 
gepostet wurde).
Stephan.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schwer zu sagen. Aber ich denke du liegst falsch.

Gemeint war wohl tatsächlich das hier
  &font_data[360]

was dem ürspünglichen

  &font_data+360

entspricht.

Aber ohne mehr Code, bzw. überhaupt mal Code, ist das praktisch nicht zu 
entscheiden.

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ja das mit den &font_data[offset] klappt.

ich habe ja da problm das ich immer nur 8 bit breite schreiben kann.#

Ich habe aber fonts mit 4 bit und mehr.

Ich habe mir gedacht das ich ein sprintf(buffer,"Wert1:%d\0",wert);

der buffer hat dann ja den inhalt Wert:12\0

diesen müsste ich dann auslesen

buffer[0]=W
buffer[1]=e
usw.

in meiner tabelle müsste ich dann schauen wo w liegt und wie breit w 
ist.

dann müsste ich ein mehrdimensionales arraymachen


[char(W),offset,width,height=imer gleich]

dann muß ich meine standart routine zum schreiben umändern


void GLCD_char(char * bmp, int x, int y, int width, int height,unsigned 
int layer)
{
unsigned int i, j;
for(i = 0; i < height ; i++)
  {
  GLCD_GraphicGoTo_pix(x, y+i,layer);
  GLCD_WriteCommand(SED1335_MWRITE);


  for(j = 0; j < width/8; j++)
    GLCD_WriteData(GLCD_ReadByteFromROMMemory(bmp+j+(i*(width/8))));
  }
}

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

habe mal probiert

ich schreibe zuerst den gesammten string mit den fontdaten in ein 
buffer.
es ist dann wie ein Bild.

dieses will ich dann ausgeben.
Leider sürzt mir den AVR ab (Speicherüberlauf).



void GLCD_chartext(char * text, unsigned int x, unsigned int y,unsigned 
int height,unsigned int layer)
{
uint32_t offset=0;
uint8_t index=0;
uint16_t width=0;
char *buffer;
unsigned int i=0, j,o;
for (int t=0;t<sizeof(text);t++)
{
  index =index_table[text[t]];
  offset=offset_table[index];
  width+=width_table[index];
  for (o=offset;o<offset_table[index+1];o++)
  {

  *buffer=&data_table[o];
  i++;


  }


}

if (width<8)width=8;
if (width>8 && width<16)width=16;
if (width>16 && width<24)width=24;

for(i = 0; i < height ; i++)
  {
  GLCD_GraphicGoTo_pix(x, y+i,layer);
  GLCD_WriteCommand(SED1335_MWRITE);



  for(j = 0; j < width/8; j++)
  {

    GLCD_WriteData(GLCD_ReadByteFromROMMemory(buffer+j+(i*(width/8))));
  }
}

}


Gruß

ANdy

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Herrmann schrieb:
> aber wenn ich  &font_data+360 mache geht es nicht

Entweder &font_data[360] oder font_data+360 gibt dir die Adresse des 
361. Elements von font_data.

Das ist aber nicht unbedingt das 361. Byte von font_data, wenn das deine 
Absicht ist. Additionen auf Zeiger funktionieren in Einheiten von der 
Größe des Datentypen, auf den gezeigt wird. Eine Addition gibt also nur 
dann ein Byte-Offset, wenn der Datentyp genau ein Byte groß ist.

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

habe es geschaft jetzt mache ich es set pixel weise ohne 8 bit 
beschränkung keine lästigen 8bit lücken mehr.

Aufruf
char buffer[20];
sprintf(buffer,"SAT in use:%d\0",3);

GLCD_chartext(&buffer,70,200,20,1);

//Funktion
void GLCD_chartext(char* text, unsigned int x, unsigned int y,unsigned 
int height,unsigned int layer)
{
uint32_t offset=0;
uint8_t index=0;
uint8_t width=0,width1;
unsigned char c;
unsigned int i=0, j,o=0,x1=0,p=0;
for (p=0;p<strlen(text);p++)
{

  index =index_table[text[p]];
  offset=offset_table[index];
  width=width_table[index];
  width1=width;




  if (width<8)width=8;
if (width>8 && width<16) width=16;
if (width>16 && width<24) width=24;


for(j=0;j<height;j++)
{
x1=x;
for(o=0;o<width/8;o++)
{
c=pgm_read_byte(&data_table[offset+o+(j*(width/8))]);
for(i=0;i<8;i++)
{

  if (c&(128>>i))
  {
GLCD_SetPixel(x1+i,y+j,1,1);
}
else
{
GLCD_SetPixel(x1+i,y+j,0,1);
}


}

x1+=8;
}
}
  x+=width1;
}
}


Der code ist sicherlich verbesserungswürdig aber funktioniert.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da es sich hier um eine Basisroutine handelt, die flott laufen soll:

Hände weg von strlen!
Das brauchst du auch nicht.

Wenn du jedes einzelne Zeichen eines Strings bearbeiten willst, dann 
machst du das so
void GLCD_chartext(char* text, unsigned int x, unsigned int y,
                   unsigned int height,unsigned int layer)
{
  ...

  while( *text != '\0' )
  {
    index = index_table[ *text++ ];

    offset = offset_table[index];
    width  = width_table[index];
    width1 = width;

    if( width < 8 )
      width = 8;

    if( width < 16 )
      width = 16;

    for( j = 0; j < height; j++ )
    {
      x1 = x;

      byteOffset = j*(width/8);

      for( o = 0; o < width/8; o++ )
      {
        c = pgm_read_byte( &data_table[ offset + o + byteOffset ] );

        for( i = 0; i < 8; i++ )
        {
          if( c & (128>>i) )
          {
            GLCD_SetPixel( x1+i, y+j, 1, 1 );
          }
          else
          {
            GLCD_SetPixel( x1+i, y+j, 0, 1 );
          }
        }

        x1 += 8;
      }
    }

    x += width1;
  }
}

und achte ein wenig mehr auf eine anständige Code-Formattierung. Sonst 
wirst du irgendwann ganz grauslich auf die Nase fallen.

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl heinz

Vielen Dank

habe den code leich ausprobiert und siehe da es ist bedeutend schneller 
beim aufbau.

Mein Problem ist, ich beschäftige mich zu wenig damit und vorallen mit 
C.


Vielen Dank

Gruß

Andy

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ist noch ein Zeitfresser

     if( c & (128>>i) )

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Da ist noch ein Zeitfresser
>
>      if( c & (128>>i) )

Besser wäre z.B:
uint_fast8_t bitvalue = 128;
for(i=0;i<8;i++)
{

  if (c & bitvalue)
  {
      // ...
  }

  // ...

  bitvalue >>= 1;
}

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Vielen Dank für deine Mühen.

Der Code funktioniert nicht denke es werden alles nullen weil ich nichts 
angezeigt bekomme.


Habe mal eine andere Frage

gibt es eine möglichkeit (Tankanzeige 0-90 grad) einen Kreisbogen der ca 
5 pixel breit zeichen z.b 90Grad = voll 0 grad leer 45 Grad halbvoll.

Wäre super

Vielen Dank

Gruß

Andy

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Herrmann schrieb:
> Hallo
>
> Vielen Dank für deine Mühen.
>
> Der Code funktioniert nicht denke es werden alles nullen weil ich nichts
> angezeigt bekomme.

Welcher Code?

Kann natürlich auch sein, dass du jetzt einen anderen Fehler eingebaut 
hast. :-)


> gibt es eine möglichkeit (Tankanzeige 0-90 grad) einen Kreisbogen der ca
> 5 pixel breit zeichen z.b 90Grad = voll 0 grad leer 45 Grad halbvoll.
>
> Wäre super

zb. Bresenham in der Variante für Kreise bzw Kreisbögen (danach 
googeln).

Da das aber ein Anzeigehintergrund ist, kann man das auch einfach 
mittels der Kreisgleichung machen.
    x^2 + y^2 = r^2
umstellen nach y und x laufen lassen. Die Wurzel ist an dieser Stelle 
auch nicht so sehr das große Problem und Verfahren für Integer Wurzeln 
sind ja auch schon erfunden. Allerdings kann es auch hier passieren, 
dass vor allem am Ende, wenn x sich immer mehr r annähert, Löcher 
entstehen.

Nächste VAriante:
Einen Winkel zb von 0 bis 90 Grad laufen lassen, dann

    x = r * cos( alpha )
    y = r * sin( alpha )

und zwischen sukzessiven Punkten jeweils Linien zeichen. Je feiner man 
den Winkel auflöst, desto weniger sieht man, dass man eigentlich ein 
Vieleck gemalt hat und keinen Kreis. Bei ganz kleinen Winkelinkrementen 
braucht man dann überhaupt nur noch Punkte setzen und kann sich die 
Linien sparen.


Allen gemeinsam ist aber das Problem:
Alle Linienzeichenverfahren bauen immer darauf auf eine 1 Pixel breite 
Linie/Bogen/was auch immer) zu malen.

Natürlich kann man zb 5 Bögen um 1 Pixel versetzt malen. Dann läuft man 
aber Gefahr, dass enizelne Pixel nicht überdeckt werden.

Eine andere Variante besteht darin, gedanklich an der fraglichen 
Position keine Pixel zu setzen, sondern mit einem Stift einen 'Punkt' zu 
malen. Wobei natürlich dann nebeneinanderliegende Punkte viele Pixel 
doppelt und dreifach übermalen. Aber zumindest das Endergebnis stimmt.


PS: Ich würde an deiner Stelle mit

    x = r * cos( alpha )
    y = r * sin( alpha )

arbeiten. Um sin/cos kommst du spätestens beim Zeiger sowieso nicht mehr 
rum und die Funktionen lassen sich wiederrum gut und schnell mittels 
einer Tabelle abbilden, wenn man auf Floating Point verzichten will.

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Habe es doch mit Zeigern gelöst.

geht auch so.

danke

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.