#include #include #include #include #include "parser.h" #include "globals.h" #include "framebuffer.h" const char circle[]={ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,1,1,1,1,1,1,1,1,1,1,1,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 }; Cfb* Cfb::getInstance() { static Cfb* instance = NULL; if(!instance) instance = new Cfb(); return instance; } Cfb::Cfb() { cpars = CParser::getInstance(); memset(&lfb, 0, sizeof(lfb)); memset(&lbb, 0, sizeof(lbb)); } Cfb::~Cfb() { Cleanup(); } int Cfb::init() { FT_Error error; fb = sx = ex = sy = ey = -1; // open Framebuffer fb=open ( "/dev/fb/0", O_RDWR ); // init framebuffer if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1) { printf("[%s] \n",BASENAME); return(2); } if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1) { printf("[%s] \n",BASENAME); return(2); } if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0))) { printf("[%s] \n",BASENAME); return(2); } // init fontlibrary if((error = FT_Init_FreeType(&library))) { printf("[%s] ",BASENAME, error); munmap(lfb, fix_screeninfo.smem_len); return(2); } if((error = FTC_Manager_New(library, 1, 2, 0, &MyFaceRequester, this, &manager))) { printf("[%s] \n",BASENAME, error); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return(2); } if((error = FTC_SBitCache_New(manager, &cache))) { printf("[%s] \n",BASENAME, error); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return(2); } if((error = FTC_Manager_Lookup_Face(manager, (char *)FONT, &face))) { printf("[%s] \n",BASENAME, error); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return(2); } use_kerning = FT_HAS_KERNING(face); desc.face_id = (char *)FONT; desc.flags = FT_LOAD_MONOCHROME; // init backbuffer if(!(lbb = (unsigned char*)malloc(fix_screeninfo.line_length*var_screeninfo.yres))) { printf("[%s] \n",BASENAME); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return(2); } // volle Bildschirmauflösung reservieren (Parameter: buffer, color, size in bytes) memset(lbb, 0, fix_screeninfo.line_length*var_screeninfo.yres); printf("[%s] - init: FB %dx%dx%d stride %d\n",BASENAME, var_screeninfo.xres, var_screeninfo.yres, var_screeninfo.bits_per_pixel, fix_screeninfo.line_length);; cpars->read_neutrino_osd_conf(&ex,&sx,&ey,&sy,NEUTRINOCONF); if((ex == -1) || (sx == -1) || (ey == -1) || (sy == -1)) { sx = 80; ex = var_screeninfo.xres - 80; sy = 80; ey = var_screeninfo.yres - 80; } int mwidth = ex-sx; int mheight = ey-sy; //mwidth = 620; startx = sx + (((ex-sx) - mwidth)/2); starty = sy + (((ey-sy) - mheight)/2); //vyres = var_screeninfo.yres; return(0); } /****************************************************************************** * MyFaceRequester ******************************************************************************/ FT_Error Cfb::MyFaceRequester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface) { FT_Error result; result = FT_New_Face(library, (char *)face_id, 0, aface); if(!result) { printf("[%s] - \n",BASENAME, (char*)face_id); } else { printf("[%s] \n",BASENAME, (char*)face_id); } return result; } /****************************************************************************** * RenderChar ******************************************************************************/ int Cfb::RenderChar(FT_ULong currentchar, int sx, int sy, int ex, int color) { int row, pitch, bit, x = 0, y = 0; FT_Error error; FT_UInt glyphindex; FT_Vector kerning; FTC_Node anode; //load char if(!(glyphindex = FT_Get_Char_Index(face, currentchar))) { printf("[%s] \n",BASENAME, (int)currentchar); return 0; } if((error = FTC_SBitCache_Lookup(cache, &desc, glyphindex, &sbit, &anode))) { printf("[%s] \n",BASENAME, (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; } // render char if(color != -1) /* don't render char, return charwidth only */ { if(sx + sbit->xadvance >= ex) { return -1; /* limit to maxwidth */ } 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 ),cpars->bgra[color],4 ); } x++; } } x = 0; y++; } } // return charwidth return sbit->xadvance + kerning.x; } /****************************************************************************** * GetStringLen ******************************************************************************/ int Cfb::GetStringLen(const char *string) { int stringlen = 0; // reset kerning prev_glyphindex = 0; // calc len while(*string != '\0') { stringlen += RenderChar(*string, -1, -1, -1, -1); string++; } return stringlen; } /****************************************************************************** * RenderString ******************************************************************************/ void Cfb::RenderString(const char *string, int sx, int sy, int maxwidth, int layout, int size, int color) { int stringlen, ex, charwidth; // set size if(size == SMALL) { desc.width = desc.height = 26; } else if(size == NORMAL) { desc.width = desc.height = 32; } else { desc.width = desc.height = 40; } // set alignment if(layout != LEFT) { stringlen = GetStringLen(string); switch(layout) { case CENTER: if(stringlen < maxwidth) { sx += (maxwidth - stringlen)/2; } break; case RIGHT: if(stringlen < maxwidth) { sx += maxwidth - stringlen; } } } // reset kerning prev_glyphindex = 0; // render string ex = sx + maxwidth; while(*string != '\0') { if((charwidth = RenderChar(*string, sx, sy, ex, color)) == -1) { return; /* string > maxwidth */ } sx += charwidth; string++; } } /****************************************************************************** * RenderBox ******************************************************************************/ void Cfb::RenderBox(int sx, int sy, int ex, int ey, int mode, int color) { int loop; if(mode == FILL) { for(; sy <= ey; sy++) { HorLine(sx, sy, ex-sx+1, color); } } else { // hor lines for(loop = sx; loop <= ex; loop++) { SetPixel(loop, sy , color); SetPixel(loop, sy+1, color); SetPixel(loop, ey-1, color); SetPixel(loop, ey , color); } // ver lines for(loop = sy; loop <= ey; loop++) { SetPixel(sx , loop, color); SetPixel(sx+1, loop, color); SetPixel(ex-1, loop, color); SetPixel(ex , loop, color); } } } /****************************************************************************** * RenderCircle ******************************************************************************/ void Cfb::RenderCircle(int sx, int sy, int color) { int x, y; for (y=0; y<15; y++) for (x=0; x<15; x++) if (circle[x+y*15]) { if (circle[x+y*15] == 1) SetPixel(sx + x, sy + y, color); else SetPixel(sx + x, sy + y, (int)circle[x+y*15]); } } /****************************************************************************** * HorLine / SetPixel / PaintIcon ******************************************************************************/ //#define SetPixel(x, y, c) memcpy(lbb + ((startx + (x))<<2) + fix_screeninfo.line_length*(starty + (y)), bgra[c], 4) void Cfb::HorLine(int x, int y, int l, int color) { for (l+=x; xbgra[c], 4); } void Cfb::PaintIcon(unsigned char *icon, int sx, int sy) { struct rawHeader header; uint16_t width, height; int x, y; memcpy(&header, icon, sizeof(struct rawHeader)); width = (header.width_hi << 8) | header.width_lo; height = (header.height_hi << 8) | header.height_lo; icon+=sizeof(struct rawHeader); for (y=0; y> 4; if (pix != header.transp) SetPixel(sx+x, sy+y, pix+1); pix = (*icon++ & 0x0f); if (pix != header.transp) SetPixel(sx+x+1, sy+y, pix+1); } } } void Cfb::FBPaint(void) { memcpy(lfb, lbb, fix_screeninfo.line_length*var_screeninfo.yres); } void Cfb::FBClear(void) { RenderBox(0, 0, ex-sx, ey-sy, FILL, 0); } /****************************************************************************** * Cleanup ******************************************************************************/ void Cfb::Cleanup (void) { FTC_Manager_Done(manager); FT_Done_FreeType(library); free(lbb); munmap(lfb, fix_screeninfo.smem_len); close(fb); }