Hallo Leute,
vielleicht hat jemand spontan eine Idee, wie ich mit die Füll-Byte bei folgendem 5x8 Pixel-Font sparen kann.
1
staticconstuint8_tfont[]PROGMEM={
2
2,0x00,0x00,0x00,0x00,0x00,// space
3
2,0x5f,0x00,0x00,0x00,0x00,// !
4
3,0x07,0x00,0x07,0x00,0x00,// "
5
5,0x14,0x7f,0x14,0x7f,0x14,// #
6
5,0x24,0x2a,0x7f,0x2a,0x12,// $
7
5,0x62,0x64,0x08,0x13,0x23,// %
8
5,0x36,0x49,0x55,0x22,0x50,// &
9
...}
Das erste Byte jeder Zeile gibt an, wie breit das Zeichen ist. Danach folgen entsprechend viele sichtbare Bytes, und dann ggf. Füllbytes. Um ein char c darzustellen, gehe ich so vor:
1
size_tindex=((c-32)*6)&0xFFFF;
2
uint_fast8_tn=pgm_read_byte(&font[index]);
Danach gebe ich n Bytes ab font[index+1] aus.
Nun würde ich mir gerne die Füllbytes sparen, wenn das mit vertretbarem Aufwand machbar ist. Allerdings habe ich keinen Plan, wie ich dann den Index zügig ermitteln kann.
Hallo Leute,
vielleicht hat jemand spontan eine Idee, wie ich mit die Füll-Byte bei
folgendem 5x8 Pixel-Font sparen kann.
Und wozu? Wieviele GB willst du damit sparen?
Nun würde ich mir gerne die Füllbytes sparen, wenn das mit vertretbarem
Aufwand machbar ist. Allerdings habe ich keinen Plan, wie ich dann den
Index zügig ermitteln kann.
Dann musst du die Infos in ein getrenntes Array legen. Und die Startpunkte der Zeichen mit variabler Länge in ein getrenntes Array, quasi ein Index.
Nun würde ich mir gerne die Füllbytes sparen, wenn das mit vertretbarem
Aufwand machbar ist.
Ist es nicht. Du bräuchtest eine zusätzliche Indextabelle. Die kostet mit einiger Wahrscheinlichkeit mehr Speicher, als du durch das Wegfallen des Padding einsparst, gerade bei so winzigen Fonts, wo die meisten Zeichen eh' die ganze Breite ausnutzen (müssen).
Aaaber: Bei dem Umfang der Texte, die man üblicherweise auf µC verwendet, kann man den Index auch einsparen. Alle nötige Information steckt ja bereits in den Längenbytes. Statt also einfach per Index zuzugreifen, muss man dann für jedes Zeichen über die Tabelle iterieren. Das kostet natürlich Rechenzeit.
Insgesamt also der übliche tradeoff: Speicherbedarf vs. Geschwindigkeit.
Was machst du mit 100 gesparten BYTEs im Flash?
Dafür gibt es keine Geld zurück.
War nur so eine fixe Idee, weil es AVR mit nur 1 kB Flash gibt. Allerdings würde man daran wohl eh kein solches Grafikdisplay anschließen, solange man noch alle Tassen im Schrank hat.
Wenn fast alle Zeichen eine Breite von 5 Pixel haben, würde ich fast dazu neigen, einfach die Ausnahmen mit entsprechendem Test isolieren und die Zeichenbreiten Bytes wegzulassen, rät mir mein "einfach denkendes Gehirn". Wie viele nicht "5er" Zeichen gibt es? Wahrscheinlich nur ein paar wie "Ii.," u.ä. Ein einfacher Test jann dann die Breiten Daten liefern.
so eben fiel mir aber noch eine Möglichkeit ein. Wie wäre es die Ascii Längen Information der Zeichen in 32bit long ints zu speichern und dann als Ascii Nummer auswerten. Allerdings brauchst Du dann sprintf oder ä.
Z.B. in Deiner Tabelle fängt es mit 22355... an. Wenn Du jetzt diese Sequenz als long int speicherst, z.B. ascii "23555555355"(0x8C66ECCF)dann komprimierst Du die Nummer der notwendigen Bytes. Mit einem pointer kann man dann bequem auf jede Ascii Nummer zugreifen und durch Subtraktion in einen uint8_t verwandeln. Wäre nicht zu aufwendig. Mit dieser Methode lässt sich also viel Platz sparen. In dem obigen Beispiel können 11 Zeichen mit 4Bytes Speicher auskommen. Wenn Du dann die Zeichen Codierung in einem Array speicherst, dann kannst Du mit einem Pointer sofort auf die Bewertung zugreifen, was schnell geht.
Mit 6 Long ints könntest Du 64 Zeichen unterstützen.
Wenn fast alle Zeichen eine Breite von 5 Pixel haben
Das ist der Fall, nur wenige Zeichen sind schmaler.
Dann könnte ein einfacher Test der betreffenden Zeichen ausreichen.
Nein. Dieser Ansatz löst natürlich garnix. Es stimmen dann auch alle Indizes für die "höheren" Zeichen nicht mehr. Eine Abwandlung davon würde allerdings funktionieren: eine zusätzliche Tabelle mit den Ausnahmen. Auch über die müsste für jedes auszugebende Zeichen iteriert werden, aber sie wäre immerhin sehr viel kürzer als die "Haupttabelle", die Iteration wäre also rechenzeitmäßig deutlich billiger.
Man könnte aber jeweils das unterste bit in jeder Spalte als Längenkodierung mißbrauchen, wenn man sich auf 5x7 Matrix beschränkt und das letzte Bit einfach ANDen.
Man könnte aber jeweils das unterste bit in jeder Spalte als
Längenkodierung mißbrauchen, wenn man sich auf 5x7 Matrix beschränkt und
das letzte Bit einfach ANDen.
Ich dachte gerade an etwas ähnliches. Ich könnte anstelle der Längenbytes einen reservierten Wert (der sonst nicht vorkommt) als Ende-Markierung nutzen.
Man könnte aber jeweils das unterste bit in jeder Spalte als
Längenkodierung mißbrauchen, wenn man sich auf 5x7 Matrix beschränkt und
das letzte Bit einfach ANDen.
Ich dachte gerade an etwas ähnliches. Ich könnte anstelle der
Längenbytes einen reservierten Wert (der sonst nicht vorkommt) als
Ende-Markierung nutzen.
Es sieht so aus, daß diese Richtung sich praktisch bewähren könnte.
Vielleicht könnte man bei Microchip Geld zurück verlangen. Oder eine Ehrenurkunde für den besten Speichersparer bekommen. Die bekommt man aber nur, wenn der notwendige zusätzliche Code den Speichergewinn nicht wieder auffrisst.
eine zusätzliche Tabelle mit den
Ausnahmen. Auch über die müsste für jedes auszugebende Zeichen iteriert
werden, aber sie wäre immerhin sehr viel kürzer als die "Haupttabelle",
die Iteration wäre also rechenzeitmäßig deutlich billiger.
Dieser Ansatz ist auch insofern geil, weil in der "Haupttabelle" das Längenbyte entfallen könnte. Da könnte man also tatsächlich deutlich Speicher sparen und auch der Mehraufwand an Rechenzeit wäre relativ gering.
Ich habe nachgezählt, es geht um 59 Füllbytes und 102 Längenbytes.
Du hast den eigentlichen Knackpunkt nicht erkannt, nämlich:
Wie viele von deinen 102 unterstützten Zeichen haben die volle Breite und wie viele wären dementsprechend Ausnahmen. DAS sind die entscheidenden Kenngrößen. Damit kann man nämlich unmittelbar den Speicherbedarf und den (mittleren) Rechenzeitbedarf einer jeden denkbaren (einfachen *) Lösung ermitteln.
(*) Sachen wie Komprimierung sind bei dieser Sache natürlich aussen vor. Der Codeaufwand würde den Speicherplatzbedarf für die Konstanten-Tabellen sicher mehr als auffressen.
Wenn die unterste Pixelreihe (MSb) ohnehin unbenutzt ist, dann lohnt es sich vielleicht doch noch, diese Ressource für die Zeichen Breitenerkennung auszunutzen. Der Code Overhead würde sich in Grenzen halten und ist einfachst machbar. Je weniger kompliziert, desto besser.
Wenn die unterste Pixelreihe (MSb) ohnehin unbenutzt ist, dann lohnt es
sich vielleicht doch noch, diese Ressource für die Zeichen
Breitenerkennung auszunutzen. Der Code Overhead würde sich in Grenzen
halten und ist einfachst machbar. Je weniger kompliziert, desto besser.
Nein. Es ist selten bis nie sinnvoll, Metadaten in potentiellen Inhalten unterzubringen. Spätestens der erste Zeichensatz mit Unterlängen zeigt das dann...
Ich habe mir einen (sonst ungenutzten) Wert als Füllbyte festgelegt. Die Längenangaben entfallen dadurch, was immerhin 100 Bytes ausmacht. Für jedes Zeichen werden nun immer 5 Bytes ausgegeben, oder weniger wenn er dabei auf ein Füllbyte stößt.