Close
0%
0%

Rpi, Writing own Fonts to Headless Framebuffer

Copy Bitmap Rawdata from Ram to Framebuffer without X.

Similar projects worth following
Easy draw Bitmap Chars and other Stuff to Framebuffer for Rpi Custom Displays.

I create my own Font in Gimp as Raw Bitmapfiles and sorting the Filenumbers to same order as ASCII Character map.

I concatenate all Files to one Raw Image and load it to RAM as Array so we can acces Single Characters with "Startadress=CharsetStartAddress+ASCIIcode*width*high" like own Charmap.

  • 1
    Step 1
    //#include "font.h"
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <linux/fb.h>
    #include <sys/mman.h>
    #include <sys/ioctl.h>
    #include <string.h>
    #include <fstream>
    using namespace std;
    unsigned int BinToNum(char* b, int bytes)
    {
        unsigned int tmpx = 0;
        unsigned int pw = 1;
        for (int i = 0; i < bytes; i++)
        {
            tmpx += ((unsigned char)b[i] * pw);
            pw = pw * 256;
        }
        return tmpx;
    }
    int width = 320;
    int height = 240;
    int ColorBits = 16;
    int size = 0;
    unsigned short int* matrix;
    char* fbp = 0;
    int x = 0, y = 0;
    long int location = 0;
    int fbfd = 0;
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    long int screensize = 0;
    
    // Read MultiImageFile to Array, Font in different Sizes, sorted as Asciimap
    int Open(const char* path)
    {
        int pad = 0;
        unsigned int sof = 0;
        unsigned int tx = 0;
        char tmp[4] = { 0, 0, 0, 0 };
        fstream file;
        file.open(path, ios::in);
        if (file.fail())
        {
            width = height = ColorBits = size = 0;
            return -1;
        }
        else
        {
            printf("The Filesizen");
            file.seekg(0, file.end);
            size = file.tellg();
            // Initialize Matrix//
            printf("The Filematrixn");
            matrix = new (unsigned short int[size / 2]);
            sof = 0;
            int counter = 0;
            while (sof < size)
            {
                file.seekg(sof, ios::beg);
                file.read(tmp, (int)(ColorBits / 8));
                tx = BinToNum(tmp, (int)(ColorBits / 8));
                matrix[counter] = tx;
                sof += (int)(ColorBits / 8);
                counter++;
            }
            file.close();
            return 1;
        }
    }
    // Try Scrolling as copy buffer line by line
    int blockcpfb(int source_x, int source_y, int width, int height, int dest_x, int dest_y)
    {
        for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++)
            {
                location = (source_x + x) * (vinfo.bits_per_pixel / 8) + (source_y + y) * 640;
    
                unsigned short int t = *((unsigned short int*)(fbp + location));
                location = (dest_x + x) * (vinfo.bits_per_pixel / 8) + (dest_y + y) * 640;
                *((unsigned short int*)(fbp + location)) = t;
            }
    }
    // Copy Char to Framebuffer
    int blockcp(int start, int width, int height, int dest_x, int dest_y)
    {
        for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++)
            {
                location = (dest_x + x) * (vinfo.bits_per_pixel / 8) + (dest_y + y) * 640;
                unsigned short int t = matrix[(y * width) + start + x];
    
                *((unsigned short int*)(fbp + location)) = t;
            }
    }
    //Clipping from Rawimage for BAckground or Real Pics
    int blockcpclipping(int start, int width, int height, int dest_x, int dest_y, int clipx, int clipy,
        int clipwidth, int clipheight)
    {
        for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++)
            {
                if (x > clipx && y > clipy && x < clipx + clipwidth && y < clipy + clipheight)
                {
                    location = (dest_x + x) * (vinfo.bits_per_pixel / 8) + (dest_y + y) * 640;
                    unsigned short int t = matrix[(y * width) + start + x];
    
                    *((unsigned short int*)(fbp + location)) = t;
                }
            }
    }
    
    // munmap(fbp, screensize);
    int main()
    {
        // Open the file for reading and writing
        fbfd = open("/dev/fb1", O_RDWR);
        if (fbfd == -1)
        {
            perror("Error: cannot open framebuffer device");
            exit(1);
        }
        printf("The framebuffer device was opened successfully.n");
        // Get fixed screen information
        if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1)
        {
            perror("Error reading fixed information");
            exit(2);
        }
        // Get variable screen information
        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1)
        {
            perror("Error reading variable information");
            exit(3);
        }
        printf("%dx%d, %dbppn", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
        // Figure out the size of the screen in bytes
        screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
        // Map the device to memory
        fbp = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
        if ((int)fbp == -1)
        {
            perror("Error: failed to map framebuffer device to memory");
            exit(4);
        }
        printf("The framebuffer device was mapped to memory successfully.n");
        x = 320;
        y = 240;
        // Where we are going to put the pixel
        // Figure out where in memory to put the pixel
        if (Open("font.bin") == 1)
        {
        }
    
        string s = " Guns n Roses ";
        int z = 0;
    
        for (int c = 0; c <= ((int)s.length() - 4); c++)
        {
            string tmp = s.substr(c, 4);
            string::iterator i;
    
            for (i = tmp.begin(); i != tmp.end(); i++)
            {
                // calculate Ascii Code
                blockcp((8330 * (((int)*i) - 32)), 70, 119, 40 + z * 70, 0);
                z++;
            }
        }
        int charspalte = 1;
        int mychar = 0;
        z = 70;
        char tmp = s.at(mychar);
        while (1)
        {
            blockcpfb(1, 0, 319, 119, 0, 0);
            //Fail Try for line by line scrolling, ondoing, never Finish
            // blockcpclipping( (8330*(((int)tmp)-32)),70, 119,320,
            // 0,charspalte,0,1,119);
    
            if (z == 70)
            {
                char tmp = s.at(mychar);
                blockcp((8330 * (((int)tmp) - 32)), 70, 119, 320 - 70, 0);
                z = 0;
                mychar++;
                charspalte = 1;
                if (mychar == s.length())
                {
                    mychar = 0;
                }
            }
            else
            {
                charspalte++;
                z++;
            }
        }
    
        close(fbfd);
        return 0;
    }

View all instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates