~aleteoryx/muditaos

ref: 97bd1178684ed9da607dde251b27497df82d040e muditaos/module-gui/gui/core/Context.cpp -rw-r--r-- 4.4 KiB
97bd1178 — Dawid Wojtas [BH-1577][BH-1578] New Power Nap layout 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

/*
 * Context.cpp
 *
 *  Created on: 6 maj 2019
 *      Author: robert
 */

#include <ios>
#include <cstring>

#include "BoundingBox.hpp"
#include "Context.hpp"

namespace gui
{

    Context::Context() : x{0}, y{0}, w{0}, h{0}, data{nullptr}
    {}

    Context::Context(uint16_t width, uint16_t height) : x{0}, y{0}, w{width}, h{height}, data(new uint8_t[w * h])
    {
        memset(data, 15, w * h);
    }

    Context::~Context()
    {
        if (data != nullptr)
            delete[] data;
    }

    Context *Context::get(int16_t gx, int16_t gy, uint16_t width, uint16_t height)
    {
        Context *retContext = new Context(width, height);

        retContext->x = gx;
        retContext->y = gy;

        // create bounding boxes for the current context and return context
        BoundingBox currentBox = BoundingBox(0, 0, w, h);
        BoundingBox newBox     = BoundingBox(gx, gy, width, height);
        BoundingBox resultBox;

        // if boxes overlap copy part defined by result from current context to the new context.
        if (BoundingBox::intersect(currentBox, newBox, resultBox)) {
            Length sourceOffset = resultBox.y * w + resultBox.x;
            Length destOffset   = (resultBox.y - gy) * width + (resultBox.x - gx);
            for (Length h = 0; h < resultBox.h; h++) {
                memcpy(retContext->data + destOffset, data + sourceOffset, resultBox.w);
                sourceOffset += w;
                destOffset += width;
            }
        }
        // else just return context filled with white colour.

        return retContext;
    }

    void Context::insert(int16_t ix, int16_t iy, Context *context)
    {
        // create bounding boxes for the current context and return context
        BoundingBox currentBox = BoundingBox(0, 0, w, h);
        BoundingBox insertBox  = BoundingBox(ix, iy, context->w, context->h);
        BoundingBox resultBox;

        // if boxes overlap copy part defined by result from current context to the new context.
        if (BoundingBox::intersect(currentBox, insertBox, resultBox)) {
            Length sourceOffset = (resultBox.y - iy) * context->w + (resultBox.x - ix);
            Length destOffset   = (resultBox.y) * w + (resultBox.x);
            for (Length h = 0; h < resultBox.h; h++) {
                memcpy(data + destOffset, context->data + sourceOffset, resultBox.w);
                sourceOffset += context->w;
                destOffset += w;
            }
        }
    }

    void Context::insertArea(
        int16_t ix, int16_t iy, int16_t iareaX, int16_t iareaY, int16_t iareaW, int16_t iareaH, Context *context)
    {
        // create bounding boxes for the current context and return context
        BoundingBox currentBox = BoundingBox(0, 0, w, h);
        BoundingBox insertBox  = BoundingBox(ix, iy, iareaW, iareaH);
        BoundingBox resultBox;

        // if boxes overlap copy part defined by result from current context to the new context.
        if (BoundingBox::intersect(currentBox, insertBox, resultBox)) {
            int16_t xBoxOffset = 0;
            int16_t yBoxOffset = 0;
            if (iareaX < 0)
                xBoxOffset = iareaX;
            if (iareaY < 0)
                yBoxOffset = iareaY;
            Length sourceOffset = (resultBox.y - iy - yBoxOffset) * context->w + (resultBox.x - ix - xBoxOffset);
            Length destOffset   = (resultBox.y) * w + (resultBox.x);
            for (Length h = 0; h < resultBox.h; h++) {
                memcpy(data + destOffset, context->data + sourceOffset, resultBox.w);
                sourceOffset += context->w;
                destOffset += w;
            }
        }
    }

    void Context::fill(uint8_t colour)
    {
        if (data) {
            memset(data, colour, w * h);
        }
        //	uint32_t size = 480*600;
        //	memset( data, colour, size );
    }

    std::ostream &operator<<(std::ostream &out, const Context &c)
    {
        out << "x:" << c.x << "y:" << c.y << "w:" << c.w << "h:" << c.h << std::endl;

        uint32_t offset = 0;
        for (uint32_t y = 0; y < c.h; y++) {
            for (uint32_t x = 0; x < c.w; x++) {
                uint32_t value = *(c.data + offset);
                std::cout << std::hex << value;
                offset++;
            }
            std::cout << std::endl;
        }
        return out;
    }

} /* namespace gui */