Skip to content

Commit 3649bef

Browse files
committed
Add DrawLine solution
1 parent 1d3f248 commit 3649bef

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

Diff for: src/05_bit_manipulation/draw_line.cpp

+60-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,68 @@
22
// eight consecutive pixels to be stored in one byte. The screen has width w,
33
// where w is divisible by 8 (that is, no byte will be split across rows). The
44
// height of the screen, of course, can be derived from the length of the array
5-
// and t he width. Implement a function that draws a horizontal line from (x1,
5+
// and the width. Implement a function that draws a horizontal line from (x1,
66
// y) to (x2, y).
77
// The method signature should look something like:
88
// drawLine(byte[] screen, int width, int x1, int x2, int y)
99
//
1010
// Hints: #366, #381, #384, #391
11+
12+
#include <cstdint>
13+
#include <vector>
14+
15+
// Solution
16+
// ------------------------------------------------------------------------------------------------
17+
void drawLine(std::vector<uint8_t> &screen, int width, int x1, int x2, int y) {
18+
int start_offset = x1 % 8;
19+
int first_full_byte = x1 / 8;
20+
if (start_offset != 0) {
21+
first_full_byte++;
22+
}
23+
24+
int end_offset = x2 % 8;
25+
int last_full_byte = x2 / 8;
26+
if (end_offset != 7) {
27+
last_full_byte--;
28+
}
29+
30+
// Set full bytes
31+
for (int b = first_full_byte; b <= last_full_byte; b++) {
32+
screen[(width / 8) * y + b] = 0xFFU;
33+
}
34+
35+
// Create masks for start and end of line
36+
uint8_t start_mask = (0xFFU >> start_offset);
37+
uint8_t end_mask = ~(0xFFU >> (end_offset + 1));
38+
39+
// Set start and end of line
40+
if ((x1 / 8) == (x2 / 8)) { // x1 and x2 are in the same byte
41+
uint8_t mask = (start_mask & end_mask);
42+
screen[(width / 8) * y + (x1 / 8)] |= mask;
43+
} else {
44+
if (start_offset != 0) {
45+
int byte_number = (width / 8) * y + first_full_byte - 1;
46+
screen[byte_number] |= start_mask;
47+
}
48+
if (end_offset != 7) {
49+
int byte_number = (width / 8) * y + last_full_byte + 1;
50+
screen[byte_number] |= end_mask;
51+
}
52+
}
53+
}
54+
55+
// Test
56+
// ------------------------------------------------------------------------------------------------
57+
58+
#include "gmock/gmock.h"
59+
#include "gtest/gtest.h"
60+
61+
TEST(DrawLineTest, Trivial) {
62+
int width = 48;
63+
int height = 1;
64+
std::vector<uint8_t> screen((width / 8) * height, 0);
65+
drawLine(screen, width, 12, 28, 0);
66+
ASSERT_THAT(screen,
67+
::testing::ElementsAre(0b00000000, 0b00001111, 0b11111111,
68+
0b11111000, 0b00000000, 0b00000000));
69+
}

0 commit comments

Comments
 (0)