• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mcallegari / qlcplus / 11388022654

17 Oct 2024 03:21PM UTC coverage: 31.573% (-0.4%) from 31.983%
11388022654

Pull #1422

github

web-flow
Merge 4147c937e into 5f77fc96f
Pull Request #1422: RgbScript make stage colors available to scripts

56 of 908 new or added lines in 11 files covered. (6.17%)

12 existing lines in 8 files now uncovered.

14057 of 44522 relevant lines covered (31.57%)

26666.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.78
/engine/src/rgbtext.cpp
1
/*
2
  Q Light Controller Plus
3
  rgbtext.cpp
4

5
  Copyright (c) Heikki Junnila
6
                Massimo Callegari
7

8
  Licensed under the Apache License, Version 2.0 (the "License");
9
  you may not use this file except in compliance with the License.
10
  You may obtain a copy of the License at
11

12
      http://www.apache.org/licenses/LICENSE-2.0.txt
13

14
  Unless required by applicable law or agreed to in writing, software
15
  distributed under the License is distributed on an "AS IS" BASIS,
16
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
  See the License for the specific language governing permissions and
18
  limitations under the License.
19
*/
20

21
#include <QXmlStreamReader>
22
#include <QXmlStreamWriter>
23
#include <QPainter>
24
#include <QImage>
25
#include <QDebug>
26

27
#include "rgbtext.h"
28

29
#define KXMLQLCRGBTextContent        QString("Content")
30
#define KXMLQLCRGBTextFont           QString("Font")
31
#define KXMLQLCRGBTextAnimationStyle QString("Animation")
32
#define KXMLQLCRGBTextOffset         QString("Offset")
33
#define KXMLQLCRGBTextOffsetX        QString("X")
34
#define KXMLQLCRGBTextOffsetY        QString("Y")
35

36
RGBText::RGBText(Doc * doc)
19✔
37
    : RGBAlgorithm(doc)
38
    , m_text(" Q LIGHT CONTROLLER + ")
39
    , m_animationStyle(Horizontal)
40
    , m_xOffset(0)
41
    , m_yOffset(0)
19✔
42
{
43
}
19✔
44

45
RGBText::RGBText(const RGBText& t)
4✔
46
    : RGBAlgorithm(t.doc())
47
    , m_text(t.text())
48
    , m_font(t.font())
49
    , m_animationStyle(t.animationStyle())
4✔
50
    , m_xOffset(t.xOffset())
4✔
51
    , m_yOffset(t.yOffset())
8✔
52
{
53
}
4✔
54

55
RGBText::~RGBText()
26✔
56
{
57
}
26✔
58

59
RGBAlgorithm* RGBText::clone() const
3✔
60
{
61
    RGBText* txt = new RGBText(*this);
3✔
62
    return static_cast<RGBAlgorithm*> (txt);
3✔
63
}
64

65
/****************************************************************************
66
 * Text & Font
67
 ****************************************************************************/
68

69
void RGBText::setText(const QString& str)
10✔
70
{
71
    m_text = str;
10✔
72
}
10✔
73

74
QString RGBText::text() const
9✔
75
{
76
    return m_text;
9✔
77
}
78

79
void RGBText::setFont(const QFont& font)
3✔
80
{
81
    m_font = font;
3✔
82
}
3✔
83

84
QFont RGBText::font() const
16✔
85
{
86
    return m_font;
16✔
87
}
88

89
/****************************************************************************
90
 * Animation
91
 ****************************************************************************/
92

93
void RGBText::setAnimationStyle(RGBText::AnimationStyle ani)
14✔
94
{
95
    if (ani >= StaticLetters && ani <= Vertical)
14✔
96
        m_animationStyle = ani;
12✔
97
    else
98
        m_animationStyle = StaticLetters;
2✔
99
}
14✔
100

101
RGBText::AnimationStyle RGBText::animationStyle() const
10,215✔
102
{
103
    return m_animationStyle;
10,215✔
104
}
105

106
QString RGBText::animationStyleToString(RGBText::AnimationStyle ani)
8✔
107
{
108
    switch (ani)
8✔
109
    {
110
    default:
3✔
111
    case StaticLetters:
112
        return QString("Letters");
3✔
113
    case Horizontal:
2✔
114
        return QString("Horizontal");
2✔
115
    case Vertical:
3✔
116
        return QString("Vertical");
3✔
117
    }
118
}
119

120
RGBText::AnimationStyle RGBText::stringToAnimationStyle(const QString& str)
8✔
121
{
122
    if (str == QString("Horizontal"))
8✔
123
        return Horizontal;
124
    else if (str == QString("Vertical"))
3✔
125
        return Vertical;
126
    else
127
        return StaticLetters;
2✔
128
}
129

130
QStringList RGBText::animationStyles()
1✔
131
{
132
    QStringList list;
133
    list << animationStyleToString(StaticLetters);
2✔
134
    list << animationStyleToString(Horizontal);
2✔
135
    list << animationStyleToString(Vertical);
2✔
136
    return list;
1✔
137
}
138

139
void RGBText::setXOffset(int offset)
6✔
140
{
141
    m_xOffset = offset;
6✔
142
}
6✔
143

144
int RGBText::xOffset() const
212✔
145
{
146
    return m_xOffset;
212✔
147
}
148

149
void RGBText::setYOffset(int offset)
6✔
150
{
151
    m_yOffset = offset;
6✔
152
}
6✔
153

154
int RGBText::yOffset() const
211✔
155
{
156
    return m_yOffset;
211✔
157
}
158

159
int RGBText::scrollingTextStepCount() const
100✔
160
{
161
    QFontMetrics fm(m_font);
200✔
162
    if (animationStyle() == Vertical)
100✔
163
        return m_text.length() * fm.ascent();
50✔
164
    else{
165
#if (QT_VERSION < QT_VERSION_CHECK(5, 11, 0))
166
        return fm.width(m_text);
167
#else
168
        return fm.horizontalAdvance(m_text);
50✔
169
#endif
170
    }
171
}
172

173
void RGBText::renderScrollingText(const QSize& size, uint rgb, int step, RGBMap &map) const
98✔
174
{
175
    QImage image;
196✔
176
    if (animationStyle() == Horizontal)
98✔
177
        image = QImage(scrollingTextStepCount(), size.height(), QImage::Format_RGB32);
49✔
178
    else
179
        image = QImage(size.width(), scrollingTextStepCount(), QImage::Format_RGB32);
49✔
180
    image.fill(QRgb(0));
98✔
181

182
    QPainter p(&image);
196✔
183
    p.setRenderHint(QPainter::TextAntialiasing, false);
98✔
184
    p.setRenderHint(QPainter::Antialiasing, false);
98✔
185
    p.setFont(m_font);
98✔
186
    p.setPen(QColor(rgb));
98✔
187

188
    if (animationStyle() == Vertical)
98✔
189
    {
190
        QFontMetrics fm(m_font);
98✔
191
        QRect rect(0, 0, image.width(), image.height());
49✔
192

193
        for (int i = 0; i < m_text.length(); i++)
196✔
194
        {
195
            rect.setY((i * fm.ascent()) + yOffset());
147✔
196
            rect.setX(xOffset());
147✔
197
            rect.setHeight(fm.ascent());
147✔
198
            p.drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, m_text.mid(i, 1));
147✔
199
        }
200
    }
201
    else
202
    {
203
        // Draw the whole text each time
204
        QRect rect(xOffset(), yOffset(), image.width(), image.height());
49✔
205
        p.drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, m_text);
49✔
206
    }
207
    p.end();
98✔
208

209
    // Treat the RGBMap as a "window" on top of the fully-drawn text and pick the
210
    // correct pixels according to $step.
211
    map.resize(size.height());
98✔
212
    for (int y = 0; y < size.height(); y++)
1,078✔
213
    {
214
        map[y].resize(size.width());
980✔
215
        for (int x = 0; x < size.width(); x++)
10,780✔
216
        {
217
            if (animationStyle() == Horizontal)
9,800✔
218
            {
219
                if (step + x < image.width())
4,900✔
220
                    map[y][x] = image.pixel(step + x, y);
4,350✔
221
            }
222
            else
223
            {
224
                if (step + y < image.height())
4,900✔
225
                    map[y][x] = image.pixel(x, step + y);
4,350✔
226
            }
227
        }
228
    }
229
}
98✔
230

231
void RGBText::renderStaticLetters(const QSize& size, uint rgb, int step, RGBMap &map) const
4✔
232
{
233
    QImage image(size, QImage::Format_RGB32);
8✔
234
    image.fill(QRgb(0));
4✔
235

236
    QPainter p(&image);
8✔
237
    p.setRenderHint(QPainter::TextAntialiasing, false);
4✔
238
    p.setRenderHint(QPainter::Antialiasing, false);
4✔
239
    p.setFont(m_font);
4✔
240
    p.setPen(QColor(rgb));
4✔
241

242
    // Draw one letter at a time
243
    QRect rect(xOffset(), yOffset(), size.width(), size.height());
4✔
244
    p.drawText(rect, Qt::AlignCenter, m_text.mid(step, 1));
4✔
245
    p.end();
4✔
246

247
    map.resize(size.height());
4✔
248
    for (int y = 0; y < size.height(); y++)
44✔
249
    {
250
        map[y].resize(size.width());
40✔
251
        for (int x = 0; x < size.width(); x++)
440✔
252
            map[y][x] = image.pixel(x, y);
400✔
253
    }
254
}
4✔
255

256
/****************************************************************************
257
 * RGBAlgorithm
258
 ****************************************************************************/
259

260
int RGBText::rgbMapStepCount(const QSize& size)
3✔
261
{
262
    Q_UNUSED(size);
263
    if (animationStyle() == StaticLetters)
3✔
264
        return m_text.length();
1✔
265
    else
266
        return scrollingTextStepCount();
2✔
267
}
268

NEW
269
void RGBText::rgbMapSetColors(QVector<uint> &colors)
×
270
{
271
    Q_UNUSED(colors);
NEW
272
}
×
273

274
void RGBText::rgbMap(const QSize& size, uint rgb, int step, RGBMap &map)
102✔
275
{
276
    if (animationStyle() == StaticLetters)
102✔
277
        renderStaticLetters(size, rgb, step, map);
4✔
278
    else
279
        renderScrollingText(size, rgb, step, map);
98✔
280
}
102✔
281

282
QString RGBText::name() const
10✔
283
{
284
    return QString("Text");
10✔
285
}
286

287
QString RGBText::author() const
1✔
288
{
289
    return QString("Heikki Junnila");
1✔
290
}
291

292
int RGBText::apiVersion() const
1✔
293
{
294
    return 1;
1✔
295
}
296

297
RGBAlgorithm::Type RGBText::type() const
4✔
298
{
299
    return RGBAlgorithm::Text;
4✔
300
}
301

302
int RGBText::acceptColors() const
×
303
{
304
    return 2; // start and end colors accepted
×
305
}
306

307
bool RGBText::loadXML(QXmlStreamReader &root)
7✔
308
{
309
    if (root.name() != KXMLQLCRGBAlgorithm)
14✔
310
    {
311
        qWarning() << Q_FUNC_INFO << "RGB Algorithm node not found";
1✔
312
        return false;
1✔
313
    }
314

315
    if (root.attributes().value(KXMLQLCRGBAlgorithmType).toString() != KXMLQLCRGBText)
6✔
316
    {
317
        qWarning() << Q_FUNC_INFO << "RGB Algorithm is not Text";
1✔
318
        return false;
1✔
319
    }
320

321
    while (root.readNextStartElement())
25✔
322
    {
323
        if (root.name() == KXMLQLCRGBTextContent)
40✔
324
        {
325
            setText(root.readElementText());
4✔
326
        }
327
        else if (root.name() == KXMLQLCRGBTextFont)
32✔
328
        {
329
            QFont font;
8✔
330
            QString fontName = root.readElementText();
8✔
331
            if (font.fromString(fontName) == true)
4✔
332
                setFont(font);
1✔
333
            else
334
                qWarning() << Q_FUNC_INFO << "Invalid font:" << fontName;
3✔
335
        }
336
        else if (root.name() == KXMLQLCRGBTextAnimationStyle)
24✔
337
        {
338
            setAnimationStyle(stringToAnimationStyle(root.readElementText()));
4✔
339
        }
340
        else if (root.name() == KXMLQLCRGBTextOffset)
16✔
341
        {
342
            QString str;
4✔
343
            int value;
344
            bool ok;
345
            QXmlStreamAttributes attrs = root.attributes();
4✔
346

347
            str = attrs.value(KXMLQLCRGBTextOffsetX).toString();
4✔
348
            ok = false;
4✔
349
            value = str.toInt(&ok);
4✔
350
            if (ok == true)
4✔
351
                setXOffset(value);
3✔
352
            else
353
                qWarning() << Q_FUNC_INFO << "Invalid X offset:" << str;
1✔
354

355
            str = attrs.value(KXMLQLCRGBTextOffsetY).toString();
4✔
356
            ok = false;
4✔
357
            value = str.toInt(&ok);
4✔
358
            if (ok == true)
4✔
359
                setYOffset(value);
3✔
360
            else
361
                qWarning() << Q_FUNC_INFO << "Invalid Y offset:" << str;
1✔
362
            root.skipCurrentElement();
4✔
363
        }
364
        else
365
        {
366
            qWarning() << Q_FUNC_INFO << "Unknown RGBText tag:" << root.name();
4✔
367
            root.skipCurrentElement();
4✔
368
        }
369
    }
370

371
    return true;
372
}
373

374
bool RGBText::saveXML(QXmlStreamWriter *doc) const
1✔
375
{
376
    Q_ASSERT(doc != NULL);
377

378
    doc->writeStartElement(KXMLQLCRGBAlgorithm);
1✔
379
    doc->writeAttribute(KXMLQLCRGBAlgorithmType, KXMLQLCRGBText);
1✔
380

381
    doc->writeTextElement(KXMLQLCRGBTextContent, m_text);
1✔
382

383
    doc->writeTextElement(KXMLQLCRGBTextFont, m_font.toString());
1✔
384

385
    doc->writeTextElement(KXMLQLCRGBTextAnimationStyle, animationStyleToString(animationStyle()));
1✔
386

387
    doc->writeStartElement(KXMLQLCRGBTextOffset);
1✔
388
    doc->writeAttribute(KXMLQLCRGBTextOffsetX, QString::number(xOffset()));
1✔
389
    doc->writeAttribute(KXMLQLCRGBTextOffsetY, QString::number(yOffset()));
1✔
390
    doc->writeEndElement();
1✔
391

392
    /* End the <Algorithm> tag */
393
    doc->writeEndElement();
1✔
394

395
    return true;
1✔
396
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc