Wakeup Light with touch user interface, anti-aliased Font, SD card access and RTC usage on STM32F746NG-DISCO board

Dependencies:   BSP_DISCO_F746NG_patch_fixed LCD_DISCO_F746NG TS_DISCO_F746NG FATFileSystem TinyJpgDec_interwork mbed-src

FontX/FontX.cpp

Committer:
the_sz
Date:
2016-02-21
Revision:
14:2044ad5cd3fe
Parent:
13:811a5c5b3fd6

File content as of revision 14:2044ad5cd3fe:

//
// use http://www.eran.io/the-dot-factory-an-lcd-font-and-image-generator/ to create the font definitions
// plus modify output:
//   - char height: in bits
//   - font height: don't display
//   - generate space bitmap
//
//   - remove \ comment from const FONT_CHAR_INFO xxxDescriptors[]
//   - rename fontxxx.c to fontxxx.cpp file
//

#include "FontX.h"

#include "stm32746g_discovery_lcd.h"
#include "debug.h"

#define CHAR_SPACE      2

static bool             useAlias=true;

uint32_t FontX_GetLength(char *Text,const FONT_INFO *pFont)
{
    uint32_t            length;
    uint32_t            index;

    length=0;
    
    while ((*Text)!='\0')
    {
        if (((*Text)>=pFont->StartCharacter) && (((*Text)<=pFont->EndCharacter) || ((pFont->EndCharacter>0x80))))       // mbed used a different character table than TheDotFactory.exe
        {
            index=(*Text)-pFont->StartCharacter;
            length+=pFont->Descriptors[index].Charwidth;
        }

        length+=CHAR_SPACE;

        if (useAlias==true)
            length+=CHAR_SPACE;

        Text++;
    }

    if (useAlias==true)
        length/=2;

    return length;
}

uint32_t FontX_GetHeight(const FONT_INFO *pFont)
{
    uint32_t                height;

    height=pFont->Descriptors[0].Charheight;

    if (useAlias==true)
        height/=2;

    return height;
}

void FontX_DisplayStringAt(uint16_t Xpos,uint16_t Ypos,uint16_t width,char *Text,FONTX_ALIGNMENT_ENUM Alignment,const FONT_INFO *pFont,uint32_t colorText,uint32_t colorBack)
{
    uint32_t xsize = 0; 

    /* get pixel length */
    xsize = FontX_GetLength(Text,pFont);

    switch (Alignment)
    {
        case ALIGN_CENTER:
            Xpos+=(width-xsize)/2;
            break;

        case ALIGN_RIGHT:
            Xpos=width-xsize-Xpos;
            break;

        case ALIGN_LEFT:
        default:
            break;
    }
    
    /* send the string character by character on LCD */
    while ((*Text)!='\0')
    {
        /* display one character on LCD */
        Xpos+=FontX_DisplayChar(Xpos,Ypos,*Text,pFont,colorText,colorBack);

        /* point on the next character */
        Text++;
    }  
}

uint32_t FontX_DisplayChar(uint16_t Xpos,uint16_t Ypos,char Ascii,const FONT_INFO *pFont,uint32_t colorText,uint32_t colorBack)
{
    uint32_t        line;
    uint32_t        line2;
    uint32_t        index;
    uint32_t        offset;
    uint32_t        lineOffset;
    uint32_t        i;
    uint32_t        j;
    uint32_t        bits;
    uint32_t        color;
    uint32_t        red;
    uint32_t        green;
    uint32_t        blue;
    uint32_t        transparency;

    if (Ascii<pFont->StartCharacter)
        return 0;
    if ((Ascii>pFont->EndCharacter) && (pFont->EndCharacter<0x80))      // mbed used a different character table than TheDotFactory.exe
        return 0;

    index=Ascii-pFont->StartCharacter;

    lineOffset=8 * ((pFont->Descriptors[index].Charwidth + 7) / 8) -  pFont->Descriptors[index].Charwidth;

    offset=pFont->Descriptors[index].Offset;

    for (i=0;i<pFont->Descriptors[index].Charheight;i++)
    {
        if (useAlias==true)
        {
            // get average of 2x2 pixel array
            for (j=0;j<pFont->Descriptors[index].Charwidth;j+=2)
            {
                line=pFont->Bitmaps[offset+(j /8)];
                line2=pFont->Bitmaps[offset+(j /8) + ((pFont->Descriptors[index].Charwidth + 7)/8)];

                bits=0;
                if (line & (1 << ((pFont->Descriptors[index].Charwidth - j + lineOffset - 1) % 8)))
                    bits++;
                if (line & (1 << ((pFont->Descriptors[index].Charwidth - (j+1) + lineOffset - 1) % 8)))
                    bits++;
                if (line2 & (1 << ((pFont->Descriptors[index].Charwidth - j + lineOffset - 1) % 8)))
                    bits++;
                if (line2 & (1 << ((pFont->Descriptors[index].Charwidth - (j+1) + lineOffset - 1) % 8)))
                    bits++;

                // alpha blend it to the current screen
                if ((colorBack==0x00000000) || (colorBack==0x00000001))
                    color=BSP_LCD_ReadPixel((Xpos+(j/2)),Ypos);
                else
                    color=colorBack;

                if (colorBack==0x00000000)
                    transparency=255;
                else if (colorBack==0x00000001)
                    transparency=255*bits/4;
                else
                    transparency=255;

                red=((color >> 16) & 0xFF)*(4-bits)/4;
                green=((color >> 8) & 0xFF)*(4-bits)/4;
                blue=(color & 0xFF)*(4-bits)/4;

                red+=(((colorText >> 16) & 0xFF)*bits/4);
                if (red>255)
                    red=255;
                green+=(((colorText >> 8) & 0xFF)*bits/4);
                if (green>255)
                    green=255;
                blue+=((colorText & 0xFF)*bits/4);
                if (blue>255)
                    blue=255;

                // write pixel
                BSP_LCD_DrawPixel((Xpos+(j/2)),Ypos,(transparency << 24) | (red << 16) | (green << 8) | blue);
            }
        }
        else
        {
            for (j=0;j<pFont->Descriptors[index].Charwidth;j++)
            {
                if (line & (1 << (pFont->Descriptors[index].Charwidth - j + lineOffset - 1)))
                {
                    BSP_LCD_DrawPixel((Xpos+j),Ypos,colorText);
                }
                else
                {
                    if ((colorBack!=0x00000000) && (colorBack!=0x00000001))
                        BSP_LCD_DrawPixel((Xpos+j),Ypos,colorBack);
                }
            }
        }

        // fill char space area
        if ((colorBack!=0x00000000) && (colorBack!=0x00000001))
        {
            for (j=0;j<CHAR_SPACE;j++)
                BSP_LCD_DrawPixel((Xpos+(pFont->Descriptors[index].Charwidth/2)+j),Ypos,colorBack);
        }

        Ypos++;

        offset+=((pFont->Descriptors[index].Charwidth + 7)/8);
        if (useAlias==true)
            offset+=((pFont->Descriptors[index].Charwidth + 7)/8);

        if (useAlias==true)
            i++;
    }

    i=pFont->Descriptors[index].Charwidth;

    if (useAlias==true)
        i/=2;

    return i+CHAR_SPACE;
}