code umwandeln

Gast #1921872
Lesenswert?

Hallo,
ich würd euch gern mal fragen wie ihr folgende Code-Zeile ohne PGM_P und 
pgm_read_byte umschreiben würdet.

1
//load pointer to width table
2
inline PGM_P font_widthtable(FONT_P charset) 
3
{
4
  PGM_P tmp;
5
  
6
  if (sizeof(tmp) == 2)
7
    tmp = (PGM_P)pgm_read_word(&(charset.widthtable));
8
  else
9
    memcpy_P((char*)&tmp,&(charset.widthtable),sizeof(tmp));
10
  
11
  return tmp;
12
}
Gast #1921896
Lesenswert?

so ...

1
//load pointer to width table
2
inline font_widthtable(FONT_P charset) 
3
{
4
  tmp;
5
  
6
  if (sizeof(tmp) == 2)
7
    tmp = ()pgm_read_word(&(charset.widthtable));
8
  else
9
    memcpy_P((char*)&tmp,&(charset.widthtable),sizeof(tmp));
10
  
11
  return tmp;
12
}
Gast #1921899
Lesenswert?

nee so geht ja schon gar nicht, weil PGM_P meines erachtens ein Zeiger 
ist oder liege ich da falsch.
Hintergrund des ganzen ist, dass der Code für einen ATMEGA geschrieben 
ist ich ihm aber für einen LPC1768  benötige es also keine pgmspace.h 
mehr gibt folglich alle damit verbundenen Variablen ersetzt werden 
müssen.
Gast #1921909
Lesenswert?

man sollte code nicht 1:1 umschreiben, man soll verstehen was der code 
macht und dann umschreiben. Man müsste dazu wissen wo die Daten denn 
herkommen sollen die bis jetzt über pgm_read_word gelesen wurden - woher 
sollen wir das wissen?
#1921936
Lesenswert?

Peter schrieb:
> man sollte code nicht 1:1 umschreiben, man soll verstehen was der code
> macht und dann umschreiben.

@TO
Da hat Peter recht.

Wenn dann noch ein bischen Wissen über typische C-Abläufe dazukommt, 
dann schreibt sich dieser Code fast von alleine. Einziges Problem: er 
hängt von genauen Aufbau der Font Strkutur ab.
Seine Aufgabe: er liefert aus diesr Fontstruktur den widthtable Pointer, 
also charset->widthtable. Mehr tut er nicht.
Gast #1922016
Lesenswert?

alles klar ich bin schon dabei, jedoch habe ich eine Zeile die ich nicht 
verstehe, da ich so was noch nie gesehen habe:

if(table)

also eine if-Anweisung ohne für mich ersichtliche Bedingung, ich wette 
das steckt was ganz einfaches hinter ich komme aber nicht darauf.

table ist ein Zeiger der die Adresse auf ein Array enthält

danke =)
#1922027
Lesenswert?

Tom schrieb:

> if(table)
>
> also eine if-Anweisung ohne für mich ersichtliche Bedingung, ich wette
> das steckt was ganz einfaches hinter

Das 'ganz einfache' besteht aus 2 Teilen

* dem if ist es schnurzegal was da in der Klammer steht. Es will
  einfach nur einen Ausdruck sehen, der ausgewertet entweder 0 ist
  oder nicht 0 ist

* auch ein Vergleich oder eine Zuweisung sind in C nichts anderes
  als Ausdrücke die einen Wert liefern

  a < b  ist ein arithmetischer Ausdruck, so wie es auch a + b ist.
  a + b liefert die Summe aus a und b, a < b liefert 0 wenn die
  Bedingung falsch ist und 1 wenn sie wahr ist.
  In C ist das hier
     d = 2 * ( a < b );
  absolut zulässig und völlig korrektes C.
  C unterscheidet nicht zwischen Bedinungen und sonstigen arithmetischen
  Ausdrücken, so das Bedingungen irgendetwas besonderes wären. Ein <
  ist genauso wie ein + oder ein * (Multiplikation) einfach nur eine
  Operation, die ihren linken Operanden mit ihrem rechten Operanden
  verwurschtet und daraus ein Ergebnis generiert, mit welchem weiter
  gerechnet werden kann.
  Wenn dieses Ergebnis (0 oder 1) dem if als Entscheidungskriterium
  vorgeworfen wird wie es weitergehen soll, dann ist das dem if recht.
  Aber das if besteht nicht darauf, dass da eine Bedingung steht. Das
  interessiert sich nur dafür ob der Ausdruck in der Klammer 0 oder
  nicht 0 ergibt, wenn man ihn auswertet.


Mit der Einführung von 'bool' in C99 haben sich die Regeln zwar ein 
bischen geändert, aber die Quintessenz bleibt immer noch die gleiche.
Gast #1922083
Lesenswert?

vielen dank bis hierher =)

ich bin nun auch schon ein bisschen weiter und versuche gerade den 
folgenden ausdruck auszuwerten:

*font_prop_24px_data + 0xFF -0x20 +1

so hinter dem font... versteckt sich ein Array welches einen Zeichensatz 
enthält nun zeigt da ein Zeiger drauf, ich habe mir schon einiges über 
Zeiger durchgelesen jedoch die oeben aufgeschriebene Notation nie 
gefunden, kennt ihr so etwas?
Ich kenn das nur wenn alles in klammern stehen würde und somit der 
Pointer verändert wird sprich das Feld auf das er zeigt ein anderes ist.
Gast #1922084
Lesenswert?

ich glaube du solltes erstmal dich genauer mit C beschäften. Wenn es auf 
beiden seiten ein C compiler ist, dann kannst du die anweisung doch 
einfach stehen lassen, warum willst du sie umschreiben?


a[2] == *(a+2) == 2[a]
#1922090
Lesenswert?

Tom schrieb:

> *font_prop_24px_data + 0xFF -0x20 +1
>
> so hinter dem font... versteckt sich ein Array welches einen Zeichensatz
> enthält nun zeigt da ein Zeiger drauf, ich habe mir schon einiges über
> Zeiger durchgelesen jedoch die oeben aufgeschriebene Notation nie
> gefunden, kennt ihr so etwas?

Jeder C Programmierer kennt sowas.
Er kennt sowas, weil er weiß, dass in C

   a[d]

vom Compiler sofort umgeformt wird zu

   *(a + d)

und damit ist dann

   a[0]

identisch zu

   *( a + 0 )

und das ist wiederrum identisch zu

   *a


Eventuell solltest du erst mal deine C Kentnisse soweit 
vervollständigen, dass du zumindest das erste Drittel eines ordinären C 
Buches soweit intus hast, dass du die Dinge erkennst wenn du sie siehst.
Von dem was dann in den restlichen 2/3 des C-Buchs alles zu finden ist, 
reeden wir erst mal gar nicht.
Gast #1922093
Lesenswert?

ich will den teil nicht umschreiben ich will ihn verstehen ob 
*font_prop_24px_data + 0xFF - 0x20 + 1 das selbe ist wie 
*(font_prop_24px_data + 0xFF - 0x20 + 1)
sprich ob bei dieser Funktion einfach der Zeiger erhöht wird und nun auf 
ein neues element zeigt
Gast #1922096
Lesenswert?

Tom schrieb:
> ich will den teil nicht umschreiben ich will ihn verstehen ob
> *font_prop_24px_data + 0xFF - 0x20 + 1 das selbe ist wie
> *(font_prop_24px_data + 0xFF - 0x20 + 1)
> sprich ob bei dieser Funktion einfach der Zeiger erhöht wird und nun auf
> ein neues element zeigt

es wird nirgends etwas zugewiesen als kann auch kein Zeiger erhöht 
werden!
#1922114
Lesenswert?

Tom schrieb:
> ich will den teil nicht umschreiben ich will ihn verstehen ob
> *font_prop_24px_data + 0xFF - 0x20 + 1 das selbe ist wie
> *(font_prop_24px_data + 0xFF - 0x20 + 1)

Ach komm.
Das sind doch einfache Grundlagen der Operatoren Reihenfolge (Operator 
Precedence).

Der Dereferenzier-* bindet stärker als das +

http://www.difranco.net/cop2220/op-prec.htm


Daher: Nein, das ist nicht dasselbe
#1922217
Lesenswert?

Tom schrieb:
> soweit war ich auch also das es nicht das selbe sein kann.
> Aber kann mir jemand auf die Sprünge helfen was dort passiert, also was
> das +0xFF-0x20+1 mit dem Zeiger anstellen.

Du hast es immer noch nicht.
Mit dem Zeiger passiert dort überhaupt nichts mehr.

Es wird der Wert geholt, auf den der Zeiger zeigt

  *font_prop_24px_data   -> ergibt einen Wert

und mit diesem Wert wird dann weiter gerechnet

   dieser Wert + 0xFF - 0x20 + 1

wozu auch immer das gut sein soll. Die 0x20 könnten wieder mal der 
Versuch sein, seinen Code als besonders schlau zu verkaufen, indem da 
der ASCII Code eines Leerzeichens eingesetzt wird. Das ist aber nur eine 
Vermutung basierend darauf, dass es hier um Fonts geht und in 
Fonttabellen die Pixeldaten gerne erst beim ASCII-Zeichen ' ' anfangen 
um damit etwas Platz zu sparen.
Gast #1923536
Lesenswert?

so so so hab mir nun alles mal ganz genau angeschaut und auch verstanden 
was der Code tun soll, habe mich nun ans Umschreiben gemacht und stoße 
dabei auf folgendes Problem.
Und zwar geht es um den folgenden Abschnitt:
1
//load pointer to data table
2
inline PGM_P font_data(FONT_P charset) 
3
{
4
  PGM_P tmp;
5
  tmp = (PGM_P)pgm_read_word(&(charset->data));
6
  return tmp;
7
}

Hierbei soll aus einer Struktur der Teil data herausgelesen werden und 
die Anfangsadresse der Daten mit tmp zurückgegeben werden in der Strukur 
steht an der Stelle data folgendes :
1
char*)font_proportional_16px_data+0xFC-0x21+1

Hierbei wird der Zeiger verschoben sodass er auf dem Datenteil der Table 
von font_proportional_16pc_data steht.
So da ich ja mit einem anderen Controller arbeite habe ich den Code 
folgendermaßen verändert
1
const char* font_data(FONT_P charset) 
2
{
3
  const char* tmp;
4
  tmp = (charset.data);
5
  return tmp;
6
}

diese Funktion wird nun in einem Teil für die genaue Position des 
Zeichens in der Datentabelle benötigt
1
return (font_data(charset))+ret*font_get_height_bytes(charset);
Hierbei wird der Zeiger der Tabelle soweit verschoben bis er man 
richtigen Punkt angelangt ist. ret wird vorher erzeiugt und die 
height_bytes sind für jedes Zeichen gleich und in meinem Fall sind dies 
2.

Nun ist mein Problem, dass der Compiler in eben dieser Zeile mir 
ausgibt:
warning: return makes integer from pointer without a cast

meiner meinung nach hängt dies mit dem data zusammen weil ich ja hier 
über einen Zeiger auf eine Struktur zugreife, ich weiß aber nicht was 
falsch ist.

Wenn jemand Ahnung hat immer her damit =)
Gast #1923572
Lesenswert?

naja ich dachte es ist so einfacher wenn ich das schritt für schritt 
mache dann eben so
erstmal der alte Text
1
//load pointer to data table
2
inline PGM_P font_data(FONT_P charset) 
3
{
4
  PGM_P tmp;
5
  
6
  if (sizeof(tmp) == 2)
7
    tmp = (PGM_P)pgm_read_word(&(charset->data));
8
  else
9
    memcpy_P((char*)&tmp,&(charset->data),sizeof(tmp));
10
  
11
  return tmp;
12
}
13

14

15
//load pointer to width table
16
inline PGM_P font_widthtable(FONT_P charset) 
17
{
18
  PGM_P tmp;
19
  
20
  if (sizeof(tmp) == 2)
21
    tmp = (PGM_P)pgm_read_word(&(charset->widthtable));
22
  else
23
    memcpy_P((char*)&tmp,&(charset->widthtable),sizeof(tmp));
24
  
25
  return tmp;
26
}
27
  
28
//load height of font in bytes
29
inline uint8_t font_get_height_bytes(FONT_P charset) 
30
{
31
  uint8_t t = pgm_read_byte(&charset->height);
32
   
33
  return ((t-1)/8+1);
34
}
35

36
//is additional space needed to the right of the character?
37
inline uint8_t font_get_add_space(FONT_P charset, unsigned char character) 
38
{
39
  PGM_P type = font_widthtable(charset);
40
  
41
  if ( type != 0 ) //if there is a width table, then it's a proportional font
42
    return 1;
43
  else
44
    return 0;
45
}
46

47
//get character number in charset
48
inline int16_t font_get_char_number(FONT_P charset, unsigned char character) 
49
{
50
  uint8_t first = pgm_read_byte(&charset->firstchar);
51
  uint8_t last  = pgm_read_byte(&charset->lastchar);
52
  
53
  if (character < first || character > last) return -1;
54
    else return character - first;
55
}
56

57
//get width of character
58
inline uint8_t font_get_char_width(FONT_P charset, unsigned char character) 
59
{
60
  PGM_P table = font_widthtable(charset);
61
  
62
  if (table)
63
    return pgm_read_byte(table+font_get_char_number(charset,character));
64
  else
65
    return pgm_read_byte(&charset->width);
66
}
67

68
//find position of character in flash
69
PGM_P font_get_char_position(FONT_P charset, unsigned char character) 
70
{
71
  uint16_t ret         = 0;
72
  int16_t  charnum_ret = font_get_char_number(charset, character);
73
  uint8_t  charnum     = charnum_ret;
74
  PGM_P    base        = font_widthtable(charset);
75

76
  if (charnum_ret < 0)          //char not found
77
    return 0;
78
  
79
  if(base == 0)            //fixed width
80
    return font_data(charset) + (uint16_t)charnum * (uint8_t)(font_get_height_bytes(charset) * font_get_char_width(charset,character));
81
  
82
  if (charnum)             //proportional width
83
    while(charnum--)
84
    ret += pgm_read_byte(base++);
85
    return (font_data(charset))+ret*font_get_height_bytes(charset);
86
}
87

88
//for double-height fonts: double all bits of a upper or lower nibble
89
inline unsigned char double_bits(uint8_t part, unsigned char c) 
90
{
91
  unsigned char t = 0;
92

93
  if (part) c >>= 4;
94
  if (c & 0x08) t |= 0xC0;
95
  if (c & 0x04) t |= 0x30;
96
  if (c & 0x02) t |= 0x0C;
97
  if (c & 0x01) t |= 0x03;
98
  
99
  return t;
100
}
101

102

103
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
104
// ### lcd_draw_char(...) ###                                               
105
//
106
// Gibt ein Zeichen auf dem Display an der aktuellen Cursorposition aus
107
//
108
//   @parameter:  FONT_P charset         (gewünschter Zeichensatz; z.B. FONT_PROP_8)
109
//            uint8_t size           (gewünschte Schriftgröße; NORMAL_SIZE, DOUBLE_HEIGHT, DOUBLE_WIDTH oder DOUBLE_SIZE)
110
//            uint8_t u8_Style        (gewünschter Style; NORMAL_STYLE oder INVERTED_STYLE)
111
//            unsigned char character    (auszugebendes Zeichen)
112
// ...
113
//    @return   :  keine
114
//   
115
void lcd_draw_char(FONT_P charset, uint8_t u8_Style, unsigned char character, uint8_t u8_x_pos, uint8_t u8_y_pos, uint8_t u8_Brightness) 
116
{
117
  int8_t  i;
118
  uint8_t row = 0; //current row of char
119
  uint8_t tmp;
120

121
  //load information about character
122
  uint8_t char_width    = font_get_char_width(charset,character); 
123
  uint8_t font_height   = font_get_height_bytes(charset);
124
  PGM_P   tableposition = font_get_char_position(charset,character);
125

126
  //final size of character
127
  uint8_t char_final_height = font_height; 
128
  
129
  uint8_t u8_ColCount = 0;
130

131
   //write chracter
132
  do 
133
  {
134
    for( i = (row) ; i < char_width * font_height ; i += font_height) 
135
    {
136
        
137
      if (character != 0x20)
138
      {
139
        tmp = pgm_read_byte(tableposition+i);
140
      }
141
      else
142
      {
143
        tmp = 0;
144
      }
145
      
146
      // Ausgabefenster setzen
147
      lcd_set_window( (u8_x_pos + u8_ColCount) , (u8_x_pos + u8_ColCount) ,u8_y_pos+(8*row),u8_y_pos+8+(8*row));
148

149
      lcd_send_byte(CMD, 0x2C);      
150

151
      for (uint8_t u8_col = 0 ; u8_col <= 7 ; u8_col++)
152
      {
153
        if (u8_Style == NORMAL_STYLE)
154
        {
155
          if (tmp & _BV(u8_col))
156
          {
157
            lcd_send_byte(PARA, u8_Brightness);
158
            lcd_send_byte(PARA, u8_Brightness);
159
          }
160
          else
161
          {
162
            lcd_send_byte(PARA, 0x00);
163
            lcd_send_byte(PARA, 0x00);
164
          }
165
        }
166
        else
167
        {
168
          // -> Invertierte Darstellung
169
          if (!(tmp & _BV(u8_col)))
170
          {
171
            lcd_send_byte(PARA, u8_Brightness);
172
            lcd_send_byte(PARA, u8_Brightness);
173
          }
174
          else
175
          {
176
            lcd_send_byte(PARA, 0x00);
177
            lcd_send_byte(PARA, 0x00);
178
          }
179
        }
180
      }
181

182
      u8_ColCount++;      
183

184
    }
185

186
    u8_ColCount = 0;
187
  } 
188
  while (++row < char_final_height);
189

190
}

und hier in der neuen Variante wo aber wie gesagt etwas nciht stimmt 
beim font_data undfont_widthtable
1
//  FUNKTIONEN (Textausgabe)
2
// --------------------------
3

4
//load pointer to data table
5
const char* font_data(FONT_P charset) 
6
{
7
  const char* tmp;
8
  tmp = (charset.data);
9
  return tmp;
10
}
11

12

13
//load pointer to width table
14
const char* font_widthtable(FONT_P charset) 
15
{
16
  const char* tmp;
17
  tmp =(charset.widthtable);
18
  return tmp;
19
}
20
  
21
//load height of font in bytes
22
uint8_t font_get_height_bytes(FONT_P charset) 
23
{
24
  uint8_t t = (charset.height);
25
   
26
  return ((t-1)/8+1);
27
}
28

29
//is additional space needed to the right of the character?
30
uint8_t font_get_add_space(FONT_P charset, unsigned char character) 
31
{
32
  const char* type = font_widthtable(charset);
33
  
34
  if ( type != 0 ) //if there is a width table, then it's a proportional font
35
    return 1;
36
  else
37
    return 0;
38
}
39

40
//get character number in charset
41
inline int16_t font_get_char_number(FONT_P charset, unsigned char character) 
42
{
43
  uint8_t first = charset.firstchar;
44
  uint8_t last  = charset.lastchar;
45
  
46
  if (character < first || character > last) return -1;
47
    else return (character - first);
48
}
49

50
//get width of character
51
uint8_t font_get_char_width(FONT_P charset, unsigned char character) 
52
{
53
  const char* table = font_widthtable(charset);
54
  
55
  if (table)
56
    return (table+font_get_char_number(charset,character));
57
  else
58
    return (charset.width);
59
}
60

61
//find position of character in flash
62
char* font_get_char_position(FONT_P charset, unsigned char character) 
63
{
64
  uint16_t      ret         = 0;
65
  int16_t       charnum_ret = font_get_char_number(charset, character);
66
  uint8_t       charnum     = charnum_ret;
67
  const char*   base        = font_widthtable(charset);
68

69
  if (charnum_ret < 0)          //char not found
70
    return 0;
71
  
72
  if(base == 0)            //fixed width
73
    return font_data(charset) + (uint16_t)charnum * (uint8_t)(font_get_height_bytes(charset) * font_get_char_width(charset,character));
74
  
75
  if (charnum)             //proportional width
76
    while(charnum--)
77
    ret += (base++);
78
    return (font_data(charset))+ret*font_get_height_bytes(charset);
79
}
80

81
//for double-height fonts: double all bits of a upper or lower nibble
82
inline unsigned char double_bits(uint8_t part, unsigned char c) 
83
{
84
  unsigned char t = 0;
85

86
  if (part) c >>= 4;
87
  if (c & 0x08) t |= 0xC0;
88
  if (c & 0x04) t |= 0x30;
89
  if (c & 0x02) t |= 0x0C;
90
  if (c & 0x01) t |= 0x03;
91
  
92
  return t;
93
}
94

95

96
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97
// ### lcd_draw_char(...) ###                                               
98
//
99
// Gibt ein Zeichen auf dem Display an der aktuellen Cursorposition aus
100
//
101
//   @parameter:  FONT_P charset         (gewünschter Zeichensatz; z.B. FONT_PROP_8)
102
//            uint8_t size           (gewünschte Schriftgröße; NORMAL_SIZE, DOUBLE_HEIGHT, DOUBLE_WIDTH oder DOUBLE_SIZE)
103
//            uint8_t u8_Style        (gewünschter Style; NORMAL_STYLE oder INVERTED_STYLE)
104
//            unsigned char character    (auszugebendes Zeichen)
105
// ...
106
//    @return   :  keine
107
//   
108
void lcd_draw_char(FONT_P charset, uint8_t u8_Style, unsigned char character, uint8_t u8_x_pos, uint8_t u8_y_pos, uint8_t u8_Brightness) 
109
{
110
  int8_t  i;
111
  uint8_t row = 0; //current row of char
112
  uint8_t tmp;
113

114
  //load information about character
115
  uint8_t char_width    = font_get_char_width(charset,character); 
116
  uint8_t font_height   = font_get_height_bytes(charset);
117
  char*   tableposition = font_get_char_position(charset,character);
118

119
  //final size of character
120
  uint8_t char_final_height = font_height; 
121
  
122
  uint8_t u8_ColCount = 0;
123

124
   //write chracter
125
  do 
126
  {
127
    for( i = (row) ; i < char_width * font_height ; i += font_height) 
128
    {
129
        
130
      if (character != 0x20)
131
      {
132
        tmp = (tableposition+i);
133
      }
134
      else
135
      {
136
        tmp = 0;
137
      }
138
      
139
      // Ausgabefenster setzen
140
      lcd_set_window( (u8_x_pos + u8_ColCount) , (u8_x_pos + u8_ColCount) ,u8_y_pos+(8*row),u8_y_pos+8+(8*row));
141

142
      lcd_send_byte(CMD, 0x2C);      
143

144
      for (uint8_t u8_col = 0 ; u8_col <= 7 ; u8_col++)
145
      {
146
        if (u8_Style == NORMAL_STYLE)
147
        {
148
          if (tmp & (1<<(u8_col)))
149
          {
150
            lcd_send_byte(PARA, u8_Brightness);
151
            lcd_send_byte(PARA, u8_Brightness);
152
          }
153
          else
154
          {
155
            lcd_send_byte(PARA, 0x00);
156
            lcd_send_byte(PARA, 0x00);
157
          }
158
        }
159
        else
160
        {
161
          // -> Invertierte Darstellung
162
          if (!(tmp & (1<<(u8_col))))
163
          {
164
            lcd_send_byte(PARA, u8_Brightness);
165
            lcd_send_byte(PARA, u8_Brightness);
166
          }
167
          else
168
          {
169
            lcd_send_byte(PARA, 0x00);
170
            lcd_send_byte(PARA, 0x00);
171
          }
172
        }
173
      }
174

175
      u8_ColCount++;      
176

177
    }
178

179
    u8_ColCount = 0;
180
  } 
181
  while (++row < char_final_height);
182

183
}
Gast #1923575
Lesenswert?

hier nocheinmal die Strutkur
1
struct font_info {
2
    uint16_t size;                  //size of data array
3
    uint8_t  width;                 //(maximum) width of character
4
    uint8_t  height;                //height of character
5
    uint8_t  firstchar;             //the number of the first included character (often 0x20)
6
    uint8_t  lastchar;              //the last included character (often 0xFF)
7
    const char* widthtable;    //Pointer to the table holding character widths (NULL for monospaced fonts)
8
    const char* data;          //Pointer to data arrray
9
    };
10
typedef const struct font_info FONT_P;
Gast #1923820
Lesenswert?

okay so ein ganzer Code ist auch doof zu lesen
mal in kurz:
seh ich das richtig

tmp = (PGM_P)pgm_read_word(&(charset->data)); charset->data =pointer

ist das gleiche wie

tmp = charset.data

wobei sich hinter charset.data ein pointer verbirgt und der Rückgabewert 
der Funktion hier auf ein Pointer ist.
Gast #1923906
Lesenswert?

ich habe ihn mir angesehen und ihn auch verstanden was wie wo hin muss 
mir fehlt leider das fahcwissen darüber wie ich z.B. das Array aus der 
Struktur auslese und einen Zeiger auf das erste Feld lege.
ich erhalte mitlerweile von meinem Compiler auch keine warnungen mehr 
jedoch funktioniert das einlesen der Tabelle meiner meinung nach nicht.
#1923914
Lesenswert?

Tom schrieb:

> typedef const struct font_info FONT_P;

Das ist Unsinn.
FONT_P war im Originalcode gedacht als Datentyp für einen Pointer. 
Dieser Pointer auf eine Font Struktur wurde an Funktionen 
weitergereicht, damit die dann Einzelinformationen aus der Struktur auf 
die sie einen Pointer erhalten haben herausholen können.

Verkompliziert wurde das im Original dadurch, dass es sich um keinen 
SRAM Pointer handelte, sondern das der Pointer auf Daten im Flash 
zeigte. Dadurch war es nicht mehr einfach möglich zu sagen

    charset->width

um an die Breite eines Zeichens zu kommen, wie man das normalerweise 
machen würde, sondern man musste den Umweg über die pgm_.... Funktionen 
gehen.

Aber: Die Funktionen sollen nach wie vor einen Pointer auf die 
Fontstuktur bekommen! Du willst doch nicht ständig Strukturen komplett 
umkopieren!
1
typedef const struct font_info * FONT_P;
2

3

4
//load pointer to data table
5
const char* font_data(FONT_P charset) 
6
{
7
  return charset->data;
8
}
9

10

11
//load pointer to width table
12
const char* font_widthtable(FONT_P charset) 
13
{
14
  return charset->widthtable;
15
}
16
  
17
//load height of font in bytes
18
uint8_t font_get_height_bytes(FONT_P charset) 
19
{
20
  uint8_t t = charset->height;
21
  return ((t-1)/8+1);
22
}
23

24
//is additional space needed to the right of the character?
25
uint8_t font_get_add_space(FONT_P charset, unsigned char character) 
26
{
27
  const char* type = font_widthtable(charset);
28
  
29
  if ( type != 0 ) //if there is a width table, then it's a proportional font
30
    return 1;
31
  else
32
    return 0;
33
}
34

35
//get character number in charset
36
inline int16_t font_get_char_number(FONT_P charset, unsigned char character) 
37
{
38
  uint8_t first = charset->firstchar;
39
  uint8_t last  = charset->lastchar;
40
  
41
  if (character < first || character > last) return -1;
42
    else return (character - first);
43
}
44

45
//get width of character
46
uint8_t font_get_char_width(FONT_P charset, unsigned char character) 
47
{
48
  const char* table = font_widthtable(charset);
49
  
50
  if (table)
51
    return table+font_get_char_number(charset,character);
52
  else
53
    return charset->width;
54
}
55

56
//find position of character in flash
57
char* font_get_char_position(FONT_P charset, unsigned char character) 
58
{
59
  uint16_t      ret         = 0;
60
  int16_t       charnum_ret = font_get_char_number(charset, character);
61
  uint8_t       charnum     = charnum_ret;
62
  const char*   base        = font_widthtable(charset);
63

64
  if (charnum_ret < 0)          //char not found
65
    return 0;
66
  
67
  if(base == 0)            //fixed width
68
    return font_data(charset) +
69
           (uint16_t)charnum * (uint8_t)(font_get_height_bytes(charset) * font_get_char_width(charset,character));
70
  
71
  if (charnum)             //proportional width
72
    while(charnum--)
73
      ret += *base++;
74

75
  return font_data(charset) + ret*font_get_height_bytes(charset);
76
}
77

78
//for double-height fonts: double all bits of a upper or lower nibble
79
inline unsigned char double_bits(uint8_t part, unsigned char c) 
80
{
81
  unsigned char t = 0;
82

83
  if (part) c >>= 4;
84
  if (c & 0x08) t |= 0xC0;
85
  if (c & 0x04) t |= 0x30;
86
  if (c & 0x02) t |= 0x0C;
87
  if (c & 0x01) t |= 0x03;
88
  
89
  return t;
90
}
91

92

93
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94
// ### lcd_draw_char(...) ###                                               
95
//
96
// Gibt ein Zeichen auf dem Display an der aktuellen Cursorposition aus
97
//
98
//   @parameter:  FONT_P charset         (gewünschter Zeichensatz; z.B. FONT_PROP_8)
99
//            uint8_t size           (gewünschte Schriftgröße; NORMAL_SIZE, DOUBLE_HEIGHT, DOUBLE_WIDTH oder DOUBLE_SIZE)
100
//            uint8_t u8_Style        (gewünschter Style; NORMAL_STYLE oder INVERTED_STYLE)
101
//            unsigned char character    (auszugebendes Zeichen)
102
// ...
103
//    @return   :  keine
104
//   
105
void lcd_draw_char(FONT_P charset, uint8_t u8_Style, unsigned char character, uint8_t u8_x_pos, uint8_t u8_y_pos, uint8_t u8_Brightness) 
106
{
107
  int8_t  i;
108
  uint8_t row = 0; //current row of char
109
  uint8_t tmp;
110

111
  //load information about character
112
  uint8_t char_width    = font_get_char_width(charset,character); 
113
  uint8_t font_height   = font_get_height_bytes(charset);
114
  char*   tableposition = font_get_char_position(charset,character);
115

116
  //final size of character
117
  uint8_t char_final_height = font_height; 
118
  
119
  uint8_t u8_ColCount = 0;
120

121
   //write chracter
122
  do 
123
  {
124
    for( i = (row) ; i < char_width * font_height ; i += font_height) 
125
    {
126
        
127
      if (character != 0x20)
128
      {
129
        tmp = tableposition[i];
130
      }
131
      else
132
      {
133
        tmp = 0;
134
      }
135
      
136
      // Ausgabefenster setzen
137
      lcd_set_window( (u8_x_pos + u8_ColCount) , (u8_x_pos + u8_ColCount) ,u8_y_pos+(8*row),u8_y_pos+8+(8*row));
138

139
      lcd_send_byte(CMD, 0x2C);      
140

141
      for (uint8_t u8_col = 0 ; u8_col <= 7 ; u8_col++)
142
      {
143
        if (u8_Style == NORMAL_STYLE)
144
        {
145
          if (tmp & (1<<(u8_col)))
146
          {
147
            lcd_send_byte(PARA, u8_Brightness);
148
            lcd_send_byte(PARA, u8_Brightness);
149
          }
150
          else
151
          {
152
            lcd_send_byte(PARA, 0x00);
153
            lcd_send_byte(PARA, 0x00);
154
          }
155
        }
156
        else
157
        {
158
          // -> Invertierte Darstellung
159
          if (!(tmp & (1<<(u8_col))))
160
          {
161
            lcd_send_byte(PARA, u8_Brightness);
162
            lcd_send_byte(PARA, u8_Brightness);
163
          }
164
          else
165
          {
166
            lcd_send_byte(PARA, 0x00);
167
            lcd_send_byte(PARA, 0x00);
168
          }
169
        }
170
      }
171

172
      u8_ColCount++;      
173

174
    }
175

176
    u8_ColCount = 0;
177
  } 
178
  while (++row < char_final_height);
179

180
}

Da ich das hier nicht testen kann, bin ich nicht sicher ob das jetzt so 
stimmt, aber soweit dürfte ich nicht daneben liegen
#1923929
Lesenswert?

Tom schrieb:
> ich habe ihn mir angesehen und ihn auch verstanden was wie wo hin muss
> mir fehlt leider das fahcwissen darüber wie ich z.B. das Array aus der
> Struktur auslese und einen Zeiger auf das erste Feld lege.
> ich erhalte mitlerweile von meinem Compiler auch keine warnungen mehr
> jedoch funktioniert das einlesen der Tabelle meiner meinung nach nicht.

Wenn du Datenstrukturen nicht verstehst, dann mal sie dir auf einen 
Zettel auf! Die Technik funktioniert perfekt um sich einen Überblick zu 
verschaffen, wie eine Datenstruktur aufgebaut ist und wie sie benutzt 
werden will.
Aber einfach so nach Gutdünken in einer Datenstruktur herumfuhrwerken 
führt nur zu Fehlern.
Gast #1923956
Lesenswert?

so ich habe das mal eingebunden und in folgenden zeilen
1
return (font_data(charset) + (uint16_t)charnum * (uint8_t)(font_get_height_bytes(charset) * font_get_char_width(charset,character)));
2

3
...
4

5
  return (font_data(charset) + ret*font_get_height_bytes(charset));

noch die Warnung

assignment makes integer from pointer without a cast
#1924020
Lesenswert?

Die erste derartige Warnung kommt hier
1
uint8_t font_get_char_width(FONT_P charset, unsigned char character) 
2
{
3
  const char* table = font_widthtable(charset);
4
  
5
  if (table)
6
    return table+font_get_char_number(charset,character);
7
  else
8
    return charset->width;
9
}

und es muss lauten
1
uint8_t font_get_char_width(FONT_P charset, unsigned char character) 
2
{
3
  const char* table = font_widthtable(charset);
4
  
5
  if (table)
6
    return table[font_get_char_number(charset,character)];
7
  else
8
    return charset->width;
9
}
#1924026
Lesenswert?

Die von dir gezeigten Zeilen bringen die Warnung

 warning: return discards qualifiers from pointer target type

und die Lösung sollte offensichtlich sein, wenn man sich mal den 
Datentyp ansieht, den der Ausdruck beim return generiert und mit dem 
Datentyp des Rückgabewertes der Funktion vergleicht.
Gast #1924036
Lesenswert?

bist du dir da sicher?
ich geh ind er Funktion an die richtige Stelle in dem Datenarray wo 
meine Breite verzeichnet ist und table zeigt auf die erste Zeile und 
font_get_char_number(charset,character) sagt mir wieviele ich 
weiterrutschen muss.

hab da noch ne frage zu deiner änderung von tmp = tableposition+i
zu
tmp = tableposition[i]

an dieser stelle wird meiner meinung nach die position der Datentabelle 
verändert, dann ergibt für mich tableposition[i] keinen sinn
#1924052
Lesenswert?

Tom schrieb:

> an dieser stelle wird meiner meinung nach die position der Datentabelle
> verändert, dann ergibt für mich tableposition[i] keinen sinn

Du hast

    return pgm_read_byte(table+font_get_char_number(charset,character));

zu

    return table+font_get_char_number(charset,character);

übersetzt.
Das ist aber falsch.


Ein

   i = pgm_read_byte( a );

wird zu einem

   i = *a;

denn genau das macht pgm_read_byte. Das Byte holen, welches an der 
Adresse a im Speicher sitzt.

Wenn also im Original das Byte geholt wird, welches vom Tabellenanfang x 
Zeichen entfernt ist

   pgm_rad_byte( table + x );

dann ist das in Nicht-Flash-Schreibweise ganz einfach

   table[x]

Das pgm_read_byte beinhaltet eine implizte Dereferenzierung! Und

  *(table+x)
ist nun mal identisch zu
  table[x]


Du hast bei deiner Übersetzung an manchen Stellen einfach das 
pgm_read_byte unter den Tisch fallen lassen. Das darfst du aber nicht! 
Wenn schon, dann hättest du es mit einem Derferenzier-* ersetzen müssen. 
Und daraus ergeben sich dann natürlich an anderen Stellen Möglichkeiten 
für Vereinfachungen.
Aus
  return pgm_read_byte( &charset->width );
wird dann
  return * &charset->width;

und da die Dereferenzierung eines Ausdrucks von dem man die Adresse 
nimmt, der Ausdruck selber ist, vereinfacht das dann zu

  return charset->width;

Hier ist nicht nur das pgm_read_byte weggefallen sondern auch das &. 
Dies deshalb weil *& eine 0-Operation ist. Nur dort wo du keinen 
Adressoperator im pgm_read_byte hast, kannst du nicht einfach nur das 
pgm_read_byte weglassen, sondern du musst tatsächlich den langen Weg 
gehen und pgm_read_byte durch einen * ersetzten und dann nachehen ob du 
etwas vereinfachen kannst.
#1924068
Lesenswert?

Tom schrieb:
> also ich muss nen zeiger zurückgeben

Du hast nicht einfach nur einen Zeiger.

Auch Zeiger haben Datentypen!
Nämlich den Datentyp des Objektes auf welches sie zeigen!

Ein Zeiger der auf einen int zeigt, ist datentypmässig nicht dasselbe 
wie ein Zeiger der auf einen double zeigt! Auch wenn beides Zeiger sind.

> und habe zur verarbeitung einen
> zeiger plus einem Wert

Also: welche Datentypen hast du?
#1924090
Lesenswert?

Tom schrieb:
> also meine drei hinteren werte sind vom typ int

?
Welche 3 hinteren Werte

> und die Rückgabe der
> Funktion ist const char

?

Hier ist die Funktion

const char* font_data(FONT_P charset)
{
 ...
}


ihr Rückgabetype ist  'const char*'
also ein Pointer auf einen Character und diese Character ist als 
konstant anzusehen, kann also nicht verändert werden.


Damit hast du


 return (font_data(charset) + ret*font_get_height_bytes(charset));
         |                |
         |                |

       Der Teil hier hat den
       Datentyp   const char*


Die Addition zu einem Pointer ergibt wieder einen Pointer (genauso ist 
in C letzten Endes der Arrayzugriff definiert) wobei sich der Datentyp 
des Pointers nicht ändert.
D.h. dieser komplette Ausdruck

     font_data(charset) + ret*font_get_height_bytes(charset));

hat immer noch den Datentyp 'const char*'

und die Funktion in der dieser return steht, sagt von sich selber, das 
sie was zurückliefert?

char* font_get_char_position(FONT_P charset, unsigned char character)
{


Die Funktion liefert einen 'char*'

Ein 'const char*' ist aber nicht dasselbe wie ein 'char*'
Gast #1924936
Lesenswert?

so hab mich mal an die "Fehlersuche" gemacht und zwar mittels LEDs die 
angehen sollen wenn das Programm an bestimmten Punkten angelangt ist.

der erste Punkt des Programmes ist font_get_char_width
1
struct font_info {
2
    uint16_t size;                  //size of data array
3
    uint8_t  width;                 //(maximum) width of character
4
    uint8_t  height;                //height of character
5
    uint8_t  firstchar;             //the number of the first included character (often 0x20)
6
    uint8_t  lastchar;              //the last included character (often 0xFF)
7
    const char* widthtable;    //Pointer to the table holding character widths (NULL for monospaced fonts)
8
    const char* data;          //Pointer to data arrray
9
    };
10

11
#ifdef FONTS_INCLUDE_font_vw_24px
12
  extern  const struct font_info font_vw_24px;
13
  #define FONT_VW_24 &font_vw_24px
14
#endif
15

16
const struct font_info font_vw_24px = {0x80+(0x17<<8),0x15,0x18,0x20,0xFF,font_vw_24px_data,(char*)(font_vw_24px_data+0xFF-0x20+1)};
17

18
//get width of character
19
uint8_t font_get_char_width(FONT_P charset, unsigned char character) 
20
{ LPC_GPIO2->FIODIR |= 0x01; // LED1
21
  const char* table = font_widthtable(charset);
22
  LPC_GPIO2->FIODIR |= 0x04; // LED3
23
  if (table)
24
  { 
25
    return (table[font_get_char_number(charset,character)]);
26
  }
27

28
//*table+font_get_char_number(charset,character);
29
  else
30
  {
31
    return (charset->width);
32
  }
33
}
34

35
//load pointer to width table
36
const char* font_widthtable(FONT_P charset) 
37
{  LPC_GPIO2->FIODIR |= 0x02; // LED2
38
  return charset->widthtable;
39
}

hierbei geht die erste LED an, die zweite geht im  font_widthtable geht 
auch an und die dritte hinter der Funktion bleibt jedoch aus ...
Gast #1925010
Lesenswert?

über lcd_draw_char(font_vw_24px, NORMAL_STYLE,'-',30, 70, 255);

mittlerweile durchläuft er das ganze programm auch und zeigt mir was an 
es sieht den zeichen auch ähnlich jedoch sind ein paar pixel falsch 
angeordnet, sprich irgendwas beim auslesen passt so nicht ganz

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren