Tiny graphics library for STM32F746G-DISCO board

Dependents:   RadarDemo 3DDemo RadarDemoT

Canvas.cpp

Committer:
karpent
Date:
2016-11-11
Revision:
3:1ddc4aa1e5cb
Parent:
2:02b7b78e8510

File content as of revision 3:1ddc4aa1e5cb:

//
// Canvas.cpp - Simple canvas.
//

#include "Canvas.h"
#include "stdlib.h"

Canvas::Canvas(void)
{
    Reset();
}


Canvas::Canvas(uint16_t width, uint16_t height)
{
    Reset();
    SetSize(width, height);
}


Canvas::~Canvas()
{
    free(_planeBitmap);
}


void Canvas::Reset()
{
    _width = 0;
    _height = 0;

    _planeBitmap = (uint8_t *)NULL;
    _planeBitmapSize = 0;

    _drawColor = 0xFFFFFFFF;
    _clearColor = 0xFF000000;
}


uint16_t Canvas::DisplayWidth()
{
    return _width;
}


uint16_t Canvas::DisplayHeight()
{
    return _height;
}

void Canvas::SetDrawColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
{
    _drawColor = alpha;
    _drawColor = (_drawColor << 8) | red;
    _drawColor = (_drawColor << 8) | green;
    _drawColor = (_drawColor << 8) | blue;
}


uint32_t Canvas::GetDrawColor()
{
    return _drawColor;
}


void Canvas::SetClearColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
{
    _clearColor = alpha;
    _clearColor = (_clearColor << 8) | red;
    _clearColor = (_clearColor << 8) | green;
    _clearColor = (_clearColor << 8) | blue;
}


uint32_t Canvas::GetClearColor()
{
    return _clearColor;
}


void Canvas::DrawPoint(int posX, int posY, uint32_t colorMask)
{
    if ((posX >= 0) && (posX < DisplayWidth()) && (posY >= 0) && (posY < DisplayHeight())) {

        uint32_t shift = posX % PLANE_BITMAP_ELEMENT_BITS;
        uint32_t col = posX / PLANE_BITMAP_ELEMENT_BITS;

        uint32_t colsNum = DisplayWidth() / PLANE_BITMAP_ELEMENT_BITS;
        if ((DisplayWidth() % PLANE_BITMAP_ELEMENT_BITS) > 0) {
            colsNum++;
        }

        uint32_t position = posY * colsNum + col;

        if (colorMask)
            _planeBitmap[position] |= 1 << shift;
        else
            _planeBitmap[position] &= ~(1 << shift);
    }
}


bool Canvas::SetSize(uint16_t width, uint16_t height)
{
    _width = width;
    _height = height;

    int cols = _width / PLANE_BITMAP_ELEMENT_BITS;
    if ((_width % PLANE_BITMAP_ELEMENT_BITS) != 0) {
        cols++;
    }

    _planeBitmapSize = cols * _height;

    if ((_planeBitmap = IsSet() ? (uint8_t *)realloc((void *)_planeBitmap, _planeBitmapSize) : (uint8_t *)malloc(_planeBitmapSize)) == NULL) {
        Reset();
        return false;
    }

    Clear();

    return true;
}


void Canvas::Clear(void)
{
    memset(_planeBitmap, 0, _planeBitmapSize);
}


uint8_t* Canvas::GetBitmap(void)
{
    return _planeBitmap;
}


bool Canvas::IsSet()
{
    return _planeBitmapSize != NULL;
}


void Canvas::DrawChar(int posX, int posY, char ch)
{
    if (ch < 32)
        return;

    const sFONT *font = _selectedFont.GetSystemFont();
    const uint8_t rowLen = font->Width/8 + 1;
    const uint8_t *pByte = font->table + (ch-32) * font->Height * rowLen;

    for (int rowY = 0; rowY < font->Height; rowY++) {
        for (int bx = 0; bx < rowLen; bx++) {
            for (int shift = 0; shift < 8; shift++) {
                DrawPoint(
                    posX + bx * 8 + shift,
                    posY + rowY, 
                    *pByte & (0x80 >> shift)
                );
            }

            // Get next byte
            pByte++;
        }
    }
}


void Canvas::DrawText(int posX, int posY, char * str)
{
    // Draw text horizontaly
    int x = posX;

    for (int i = 0; i < strlen(str); i++) {
        DrawChar(x, posY, str[i]);
        x += _selectedFont.GetSystemFont()->Width;
    }
}