/* Hier mal ein Beispiel um auf der 7025 Texte auf den Framebuffer zu zaubern, ist alles nicht weltbewegendes und ein Grossteil der Routinen (Libfreetype) wurden von Tuxcom/Tuxtxt geklaut und eben auf den 32 Bit Framebuffer angepasst, da die urpsrünglichen Routinen im 8 Bit Modus arbeiteten. Ich hab versucht das ganze ein wenig durch zu kommentieren, so das man weiss das ganze relativ einfach in eigenen Programmen einsetzen kann. Für die Libfreetype hab ich die IFDEFs dringelassen, so dass dies sowohl mit der libfreetype 2.1 als auch mit der 2.0 funktioniert. Zwischen 2.0 und 2.1 hatte sich da einiges in der lib geändert. Vielleicht kanns jemand brauchen. Grüsse @all, Seddi*/ #include #include #include #include #include #include #include #include #include #include #include FT_FREETYPE_H #include FT_CACHE_H #include FT_CACHE_SMALL_BITMAPS_H // Schriftdatei setzen #define FONT "/usr/share/fonts/md_khmurabi_10.ttf" enum {LEFT, CENTER, RIGHT}; enum {VERY_SMALL, SMALL, BIG}; // Schriftgrössen festlegen #define FONTHEIGHT_VERY_SMALL 16 #define FONTHEIGHT_SMALL 32 #define FONTHEIGHT_BIG 40 // Libfreetype Zeugs FT_Error error; FT_Library library; FTC_Manager manager; FTC_SBitCache cache; FTC_SBit sbit; #if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0 FTC_Image_Desc desc; #else FTC_ImageTypeRec desc; #endif FT_Face face; FT_UInt prev_glyphindex; FT_Bool use_kerning; FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface); // Framebuffer Zeugs unsigned char *lfb; int StartX; int StartY; int fb; struct fb_fix_screeninfo fix_screeninfo; struct fb_var_screeninfo var_screeninfo; // ************************************************************************************************************** // Renderroutinen für Text und einfache Boxen // ************************************************************************************************************** // Freetype - MyFaceRequester FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface) { FT_Error result; result = FT_New_Face(library, face_id, 0, aface); if(!result) printf("Freetype \n", (char*)face_id); else printf("Freetype \n", (char*)face_id); return result; } // Freetype - RenderChar int RenderChar(FT_ULong currentchar, int sx, int sy, int ex, unsigned char *color) { if (currentchar == 32) return; int row, pitch, bit, x = 0, y = 0; FT_UInt glyphindex; FT_Vector kerning; FT_Error error; int tmpcolor; if(!(glyphindex = FT_Get_Char_Index(face, currentchar))) { printf("Freetype fuer Zeichen %x \"%c\" fehlgeschlagen\n", (int)currentchar,(int)currentchar); return 0; } #if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0 if((error = FTC_SBit_Cache_Lookup(cache, &desc, glyphindex, &sbit))) #else FTC_Node anode; if((error = FTC_SBitCache_Lookup(cache, &desc, glyphindex, &sbit, &anode))) #endif { printf("Freetype fuer Zeichen %x \"%c\" fehlgeschlagen. Fehler: 0x%.2X>\n", (int)currentchar,(int)currentchar, error); return 0; } if(use_kerning) { FT_Get_Kerning(face, prev_glyphindex, glyphindex, ft_kerning_default, &kerning); prev_glyphindex = glyphindex; kerning.x >>= 6; } else kerning.x = 0; if(sx + sbit->xadvance >= ex) return -1; for(row = 0; row < sbit->height; row++) { for(pitch = 0; pitch < sbit->pitch; pitch++) { for(bit = 7; bit >= 0; bit--) { if(pitch*8 + 7-bit >= sbit->width) break; /* render needed bits only */ if((sbit->buffer[row * sbit->pitch + pitch]) & 1<left + kerning.x + x)*4 + fix_screeninfo.line_length*(StartY + sy - sbit->top + y), color, 4); } x++; } } x = 0; y++; } return sbit->xadvance + kerning.x; } // Freetype - Stringlaenge int GetStringLen(const char *string, int size) { int stringlen = 0; switch (size) { case VERY_SMALL: desc.font.pix_width = desc.font.pix_height = FONTHEIGHT_VERY_SMALL; break; case SMALL : desc.font.pix_width = desc.font.pix_height = FONTHEIGHT_SMALL ; break; case BIG : desc.font.pix_width = desc.font.pix_height = FONTHEIGHT_BIG ; break; } prev_glyphindex = 0; while(*string != '\0') { stringlen += RenderChar(*string, -1, -1, -1, ""); string++; } return stringlen; } // Freetype - Render String void RenderString(const char *string, int sx, int sy, int maxwidth, int layout, int size, unsigned char *color) { int stringlen, ex, charwidth; switch (size) { case VERY_SMALL: desc.font.pix_width = desc.font.pix_height = FONTHEIGHT_VERY_SMALL; break; case SMALL : desc.font.pix_width = desc.font.pix_height = FONTHEIGHT_SMALL ; break; case BIG : desc.font.pix_width = desc.font.pix_height = FONTHEIGHT_BIG ; break; } if(layout != LEFT) { stringlen = GetStringLen(string, size); switch(layout) { case CENTER: if(stringlen < maxwidth) sx += (maxwidth - stringlen)/2; break; case RIGHT: if(stringlen < maxwidth) sx += maxwidth - stringlen; } } prev_glyphindex = 0; ex = sx + maxwidth; while(*string != '\0' && *string != '\n') { if((charwidth = RenderChar(*string, sx, sy, ex, color)) == -1) return; /* string > maxwidth */ sx += charwidth; string++; } } // Render Box void RenderBox(int sx, int sy, int ex, int ey, unsigned char *color) { int loop; int tx; for(; sy <= ey; sy++) { for(tx=0; tx <= (ex-sx); tx++) { memcpy(lfb + StartX*4 + sx*4 + (tx*4) + fix_screeninfo.line_length*(StartY + sy),color,4); } } } // ************************************************************************************************************** // Hauptroutine // ************************************************************************************************************** main(argc,argv) int argc; char *argv[]; { // Setze Offsets (Startpunkt links oben), der Framebuffer hat 720x576pixel, // danke Overscan der TV Geräte meist nur ca. 640x480 nutzbar StartX=60; StartY=60; // Framebuffer oeffnen fb=open("/dev/fb/0", O_RDWR); if (fb == -1) { printf("Framebuffer failed\n"); return; } // Framebuffer initialisieren und Infos auslesen if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1) { printf("Framebuffer: \n"); return; } if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1) { printf("Framebuffer: \n"); return; } // Framebuffermodus auf 720x576 und 32 Bit initialisieren var_screeninfo.yres=var_screeninfo.yres_virtual=576; var_screeninfo.xres=var_screeninfo.xres_virtual=720; var_screeninfo.bits_per_pixel=32; if(ioctl(fb, FBIOPUT_VSCREENINFO, &var_screeninfo) == -1) { printf("Framebuffer: \n"); return; } if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1) { printf("Framebuffer: \n"); return; } // Framebuffer in Speicher mappen if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0))) { printf("Framebuffer: \n"); return; } // Freetype initialisieren if((error = FT_Init_FreeType(&library))) { printf("Freetype ", error); munmap(lfb, fix_screeninfo.smem_len); return; } if((error = FTC_Manager_New(library, 1, 2, 0, &MyFaceRequester, NULL, &manager))) { printf("Freetype \n", error); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return; } if((error = FTC_SBitCache_New(manager, &cache))) { printf("Freetype \n", error); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return; } if((error = FTC_Manager_Lookup_Face(manager, FONT, &face))) { printf("Freetype \n", error); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return; } else desc.font.face_id = FONT; use_kerning = FT_HAS_KERNING(face); #if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0 desc.image_type = ftc_image_mono; #else desc.flags = FT_LOAD_MONOCHROME; #endif // Screen leeren, der komplette Speicherbereich wird mit 0 beschrieben, was beim 32Bit // Framebuffer der 7025 der Farbe schwarz mit 100% transparent entspricht, sprich man // sieht das dahinter liegende Bild des MPEG Decoders memset(lfb, 0, var_screeninfo.yres*fix_screeninfo.line_length); // Hier zeichnen wir eine schwarze Box in den Framebuffer, die StartX/StartY Werte werden // dabei berücksichtigt. // Für die Farbe wird ein 32 Bit Wert übergeben, dass dem Format BGRA entspricht, sprich // das erste Byte ist der Blauwert, das 2. Grün und das 3. Rot. Der vierte Wert bestimmt den // Alphawert, wobei bei der 7025 xFF (255) für nicht transparent und x00 (0) für 100% Transparenz // steht. // x,y,x1 ,y1 ,farbe RenderBox(0,0,600,456,"\x00\x00\x00\xFF"); // Nun geben wir einen Text an der Position x=20,y=20 (StartX/StartY kommt automatisch hinzu) // und sagen dass der String nicht breiter sein darf als 400 Pixel. Benötigt der Text mehr Platz, // wird er abgeschnitten. // Für die Ausrichtung gibt es LEFT, RIGHT und CENTER und bestimmt die Ausrichtung des Textes // innerhalb der angegebenen Breite (hier 400 Pixel). Für die Schriftgrösse stehen VERY_SMALL, SMALL // und BIG zur Verfügung. Die (Pixel)Grössen dafür wurden weiter oben definiert. Die Farbangabe // entspricht der Farbangabe der RenderBox Funktion (siehe oben). // text ,x ,y ,breite, ausrichtung, grösse, farbe RenderString("Hallo !, 20, 20, 400, LEFT, BIG, "\xFF\xFF\xFF\xFF"); // Warte 10 Sekunden sleep(10); // Programmende // Libfreetype aufräumen FTC_Manager_Done(manager); FT_Done_FreeType(library); // Framebuffer wieder leeren (Transparent machen), Speicher freigeben, // Framebufefr Device schliessen memset(lfb, 0, var_screeninfo.yres*fix_screeninfo.line_length); munmap(lfb, fix_screeninfo.smem_len); close(fb); exit(0); }