close-circle
Close
0%
0%

Rpi, Writing own Fonts to Headless Framebuffer

Copy Bitmap Rawdata from Ram to Framebuffer without X.

Similar projects worth following
close
76 views
0 comments
0 followers
likes
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