Forum: Projekte & Code Font tool von Christian R. verbessert


von Stephan K. (dustpuppy)


Lesenswert?

Hi zusammen,
ich weiss ja nicht, ob die Sache noch aktuell ist und irgend Wen noch 
interessiert. Es geht um diesen Beitrag: 
Beitrag "GLCD T6963C Font-Tool"
Erst mal muss ich sagen, ich finde das Fonttool richtig gut.
Nu kommt das Aber.
Da die Zeichen Pixel fuer Pixel geschrieben werden, ist die Ausgabe 
meiner Meinung nach etwas sehr langsam. Also hab ich mir mal die Muehe 
gemacht das Ganze komplett um zu kloeppeln. Ich schreibe die Daten byte 
weise auf das Display. Dafuer musste ich die Positionierung mit ein 
bisschen shifterei korrigieren, weil beim schreiben eines Bytes sonst 
das Zeichen immer verschoben war. Ausserdem musste ich auf das Inverse 
verzichten. Da bastel ich noch dran. Dafuer ist die Ausgabe jetzt aber 
transparent und ca. 8 mal schneller. Das Ganze laeuft ueber einen 
Puffer.
"lcd_char" gibt nur 1 Zeichen an der angegeben Position aus.
"lcd_print" geht durch den String durch und nutzt dann "lcd_char" um ihn 
anzuzeigen. "strlenght" ist nur eine Hilfe, weil es weniger Speicher 
braucht, als strlen.
Fuer Kritik bin ich immer offen. Wer eine Idee hat, wie man die inverse 
Darstellung hin bekommt, kann sich auch gerne melden.
1
uint8_t lcd_char(unsigned char x,unsigned char y, char in, const struct FONT_DEF *strcut1, unsigned char invers)
2
{
3
  uint8_t map;
4
  uint8_t width;
5
  uint16_t offset;
6
  uint8_t height;
7
  unsigned char buffer[glcd_BYTES_PER_ROW];
8
  
9
  uint8_t spalte,zeile;
10
  uint8_t counter=0;
11
  uint8_t buffer_counter=0;
12
  uint8_t pixel=0,bc;
13
  uint8_t o;
14
  
15
  map = in;                  // Index des Zeichens
16
  map = pgm_read_byte(&strcut1->mapping_table[map]);
17
  width = pgm_read_byte(&strcut1->width_table[map]);        // Breite des Zeichens
18
  offset = pgm_read_word(&strcut1->offset_table[map]);        // Die Startadresse, wo das Zeichen anfaengt
19
  height = strcut1->glyph_height;            // Die Hoehe des Fonts
20
  
21
  for(zeile=0;zeile<=height;zeile++)            // Zeilenweise lesen wir das Zeichen
22
  {
23
    glcd_goto(x,y+zeile);              // Zur Position auf dem Screen gehen
24
    for(spalte=0;spalte<((width-1)/8)+1;spalte++)        // Wir lesen pro Spalte nur soviel bytes, wie benoetigt
25
    {
26
      buffer[buffer_counter]=pgm_read_byte(&strcut1->glyph_table[offset+counter]);// Ein Byte lesen
27
      counter++;                // Zaehler erhoehen
28
      buffer_counter++;
29
      buffer[buffer_counter]=0;              // das naechste buffer byte loeschen, sonst steht muell drin
30
    }
31
    
32
    for(pixel=0;pixel<x-((x/8)*8);pixel++)          // Um soviel bits muessen wir das Zeichen nach rechts verschieben
33
    {
34
      for(bc=buffer_counter;bc>0;bc--)            // Rueckwaerts zaehlen, bis die Anzahl der gelesenen Bytes um 1 bit verschoben ist
35
      {
36
        buffer[bc]>>=1;                // Buffer um 1 bit nach rechts shiften
37
        buffer[bc]|=(buffer[bc-1] & 1<<0)<<7;          // Ueberlauf bit vom vorherigen byte holen
38
      }
39
      buffer[0]>>=1;                // Buffer 0 muss nur geshiftet werden, hier gibt's keinen Ueberlauf
40
    }
41
42
    glcd_goto(x,y+zeile);              // Zur Position auf dem Screen gehen
43
    for(o=0;o<=buffer_counter;o++)            // Alle bytes + 1 durchzaehlen
44
    {
45
      
46
      glcd_cput(0xC5);                // 0xC5 = Lese Display ohne adresse zu aendern
47
      buffer[o]|=glcd_dget();              // Hintergrund-byte mit buffer-byte zusammenfuegen
48
      glcd_dput(buffer[o]);              // Den buffer ausgeben
49
      glcd_cput(0xC0);                // 0xC0 = Schreibe und erhoehe die adresse +1
50
    }
51
52
    buffer_counter=0;
53
54
  }
55
  
56
  return width;                  // Rueckgabewert ist die Breite des Zeichens
57
}
58
/****************************************************************************
59
*
60
* Gives lenght of string
61
*
62
****************************************************************************/
63
uint8_t strlenght(const char *string) {
64
  const char *s;
65
66
  s = string;
67
  while (*s)
68
    s++;
69
  return s - string-1;
70
}
71
72
void lcd_print(unsigned char x, unsigned char y, const char *in,  const struct FONT_DEF *strcut1, unsigned char invers)
73
{
74
  unsigned int z;
75
  int width=x;
76
  for(z=0;z<=strlenght(in);z++)
77
  {
78
    width+=lcd_char(width,y,in[z],strcut1,invers);
79
      width--;
80
  }
81
    //glcd_box(s,y+2,s+width,y+h-1,TRUE);
82
}

Viel Spass

Dusty

von Erik .. (erik_mit_k)


Lesenswert?

Hab mich noch nicht ganz hineingedacht aber ich denke du musst den aus 
dem Flash gelesenen Block nur bitweise invertieren...
so in etwa:
1
buffer[buffer_counter]= pgm_read_byte(&strcut1->glyph_table[offset+counter]);// Ein Byte lesen
2
3
if(invers > 0) buffer[buffer_counter]= ~buffer[buffer_counter];//bitweises invertieren des Blocks

von Christoph (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

im vorraus vielen Dank für diese Super Funktion.
Ich kam nicht umher, da ich diese auch gern für mein Projekt verwenden 
möchte,
einige kleine Modifikationen durch zu führe. Ich nutze einen Anderen 
Display
Treiber, daher.

Ich nutze den hier:
1
// Graphic LCD with Toshiba T6963 controller
2
// Copyright (c) Radoslaw Kwiecien, 2007r
3
// http://en.radzio.dxp.pl/t6963/

Ich musste also deine Schreib befehle anpassen. Das hat im nachhinein 
auch gut Funktioniert.
Ich habe nur festgestellt, dass wenn ich variablen anzeige, das feld 
überschrieben wird. Es werden also so zu sagen alle Zahlen die mal im
Speicher waren gleichzeitig angeziegt. Ich will nicht anmaßend sein, 
kann
das von diesen Zeilen kommen ?
1
      buffer[o]|=glcd_dget();              // Hintergrund-byte mit buffer-byte zusammenfuegen
2
      glcd_dput(buffer[o]);              // Den buffer ausgeben

Ich hab das mal Spaßeshalber in ein
1
buffer[o]=glcd_dget();              // Hintergrund-byte mit
geändert. Damit zeigt er jetzt auch immer nur den Aktuellen wert an.
Es flimmert nur. Hm..

Ich habe noch ein Bild angehängt, wie die Zeichen bei mir dargestellt 
werden,
auf dem Display. Irgendwie fehlt da nur etwas von den Ziffern.
Hängt das vielleicht mti meinem Treiber zusammen?

Ich hänge mal die ab geänderte Funktion mit an. Vielleicht kann mir wer 
dabei weiterhelfen :)
1
uint8_t GLCD_lcd_char(unsigned char x,unsigned char y, char in, const struct FONT_DEF *strcut1, unsigned char invers)
2
{
3
  uint8_t map;
4
  uint8_t width;
5
  uint16_t offset;
6
  uint8_t height;
7
  unsigned char buffer[GLCD_GRAPHIC_AREA];
8
  
9
  uint8_t spalte,zeile;
10
  uint8_t counter=0;
11
  uint8_t buffer_counter=0;
12
  uint8_t pixel=0,bc;
13
  uint8_t o;
14
  
15
  map = in;                  // Index des Zeichens
16
  map = pgm_read_byte(&strcut1->mapping_table[map]);
17
  width = pgm_read_byte(&strcut1->width_table[map]);        // Breite des Zeichens
18
  offset = pgm_read_word(&strcut1->offset_table[map]);        // Die Startadresse, wo das Zeichen anfaengt
19
  height = strcut1->glyph_height;            // Die Hoehe des Fonts
20
  
21
  for(zeile=0;zeile<=height;zeile++)            // Zeilenweise lesen wir das Zeichen
22
  {
23
    GLCD_GraphicGoTo(x,y+zeile);              // Zur Position auf dem Screen gehen
24
    for(spalte=0;spalte<((width-1)/8)+1;spalte++)        // Wir lesen pro Spalte nur soviel bytes, wie benoetigt
25
    {
26
      buffer[buffer_counter]= pgm_read_byte(&strcut1->glyph_table[offset+counter]);// Ein Byte lesen
27
      if(invers > 0) buffer[buffer_counter]= ~buffer[buffer_counter];//bitweises invertieren des Blocks
28
    counter++;                // Zaehler erhoehen
29
      buffer_counter++;
30
      buffer[buffer_counter]=0;              // das naechste buffer byte loeschen, sonst steht muell drin
31
    }
32
    
33
    for(pixel=0;pixel<x-((x/8)*8);pixel++)          // Um soviel bits muessen wir das Zeichen nach rechts verschieben
34
    {
35
      for(bc=buffer_counter;bc>0;bc--)            // Rueckwaerts zaehlen, bis die Anzahl der gelesenen Bytes um 1 bit verschoben ist
36
      {
37
        buffer[bc]>>=1;                // Buffer um 1 bit nach rechts shiften
38
        buffer[bc]|=(buffer[bc-1] & 1<<0)<<7;          // Ueberlauf bit vom vorherigen byte holen
39
      }
40
      buffer[0]>>=1;                // Buffer 0 muss nur geshiftet werden, hier gibt's keinen Ueberlauf
41
    }
42
43
    GLCD_GraphicGoTo(x,y+zeile);              // Zur Position auf dem Screen gehen
44
    for(o=0;o<=buffer_counter;o++)            // Alle bytes + 1 durchzaehlen
45
    {
46
      
47
      GLCD_WriteCommand(T6963_DATA_READ_AND_NONVARIABLE);        // 0xC5 = Lese Display ohne adresse zu aendern
48
      // Das ist auch noch nicht der Weisheit letzter Schluss
49
    //buffer[o] = GLCD_ReadData();              // Hintergrund-byte mit buffer-byte zusammenfuegen
50
      GLCD_WriteData(buffer[o]);              // Den buffer ausgeben
51
      GLCD_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT);           // 0xC0 = Schreibe und erhoehe die adresse +1
52
    }
53
54
    buffer_counter=0;
55
56
  }
57
  
58
  return width;                  // Rueckgabewert ist die Breite des Zeichens
59
}

Meinen kompletten Display Treiber hänge ich auch mal mit an
Mit meinem Modifikationen. Ist sehr viel gebastel drin bitte nicht all 
zu stren sein :)

von Christoph (Gast)


Lesenswert?

Hallo nochmal

okay ich bin der sache auf die schliche gekommen.

Mein Display arbeitet im 6Bit Modus. Das würde erklären warum 1.
teile der Buchstaben fehlen und 2. die Anordnung nicht passt!

Weis jemand ein Font tool das Zeichen in 6 Bit konvertiert vielleicht?

Grüße
Christoph

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.