Topic 5.8 A monochrome screen is stored as a single array of bytes, allowing eight consecutive pixels to be stored in one byte. The screen has width w, where w is divisible by 8(that is, no byte will be split across rows). The height of the screen, of course, can be derived from the length of the array and the width. Implement a function drawHorizontalLine(byte[] screen, int width, int x1, int x2, int y) which draws a horizontal line from (x1, y) to (x2, y).
方法1:Iterate in a for loop from x1 to x2, setting each pixel along the way.
方法2:If x1 and x2 are far away from each other, the full bytes can be set one at a time byyy 000xFF. The residual start and end of the line can be set using masks. There are many special cases such as x1 and x2 are in the same byte.
public class c5_8 {
public static void drawLine(byte[] screen, int width, int x1, int x2, int y) {//screen是一个数组,顺次排了从第一层到最底层的所有数据,以字节为单位
int start_offset = x1 % 8;
int first_full_byte = x1 / 8;
if (start_offset != 0) {
first_full_byte++;
}
int end_offset = x2 % 8;
int last_full_byte = x2 / 8;
if (end_offset != 7) {
last_full_byte--;
}
// Set full bytes
for (int b = first_full_byte; b <= last_full_byte; b++) {
screen[(width / 8) * y + b] = (byte) 0xFF;//这里要注意,先找到对应层数,再找到相应位移
}
byte start_mask = (byte) (0xFF >> start_offset);
byte end_mask = (byte) ~(0xFF >> (end_offset + 1));//这里注意一下
// Set start and end of line
if ((x1 / 8) == (x2 / 8)) { // If x1 and x2 are in the same byte
byte mask = (byte) (start_mask & end_mask);
screen[(width / 8) * y + (x1 / 8)] |= mask;
} else {
if (start_offset != 0) {
int byte_number = (width / 8) * y + first_full_byte - 1;
screen[byte_number] |= start_mask;
}
if (end_offset != 7) {
int byte_number = (width / 8) * y + last_full_byte + 1;
screen[byte_number] |= end_mask;
}
}
}
public static int computeByteNum(int width, int x, int y) {
return (width * y + x) / 8;
}
public static void printByte(byte b) {
for (int i = 7; i >= 0; i--) {
System.out.print((b >> i) & 1);//注意:不是b=b>>i, 所以b是不变的;用&1的作用是只保留最后一位,其他位(高位)都清0
}
}
public static void printScreen(byte[] screen, int width) {
int height = screen.length * 8 / width;
for (int r = 0; r < height; r++) {
for (int c = 0; c < width; c+=8) {
byte b = screen[computeByteNum(width, c, r)];
printByte(b);
}
System.out.println("");
}
}
public static void main(String[] args) {
int width = 8 * 4;
int height = 5;
byte[] screen = new byte[width * height / 8];
drawLine(screen, width, 0, 8, 2);
printScreen(screen, width);
}
}
//结果
00000000000000000000000000000000
00000000000000000000000000000000
11111111100000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000