C ++ ZA DUŻO, ABY WYGRAĆ
Napisałem w pełni funkcjonalny program do rysowania PPM w C ++, z własną czcionką bitmapową. Nawet usunięcie wszystkich niepotrzebnych funkcji jest wciąż ogromne w porównaniu z odpowiedziami tutaj z powodu definicji czcionki.
Tak czy inaczej, oto wynik dla HELLO WORLD:
I kod:
ppmdraw.h
#ifndef PPMDRAW_H
#define PPMDRAW_H
#include <fstream>
#include <sstream>
#include <map>
#include <bitset>
#include <vector>
struct pixel{
unsigned char r;
unsigned char g;
unsigned char b;
bool equals(pixel p){
return (r == p.r && g == p.g && b == p.b);
}
};
class PPMDraw
{
public:
PPMDraw(int w, int h);
virtual ~PPMDraw();
void fill(unsigned char r, unsigned char g, unsigned char b);
void set_color(unsigned char r, unsigned char g, unsigned char b);
void draw_point(int x, int y);
void draw_char(int x, int y, char c);
void draw_string(int x, int y, std::string text);
bool save(std::string file);
private:
int width;
int height;
pixel * image;
std::vector<bool> checked;
unsigned char red;
unsigned char green;
unsigned char blue;
void init_alpha();
std::map<char, std::bitset<48> > font;
};
#endif // PPMDRAW_H
ppmdraw.cpp
#include "PPMDraw.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cmath>
#include <map>
#include <bitset>
#include <vector>
// standard constructor
PPMDraw::PPMDraw(int w, int h){
width = w;
height = h;
// make an array to hold all the pixels, r, g, b for each
image = new pixel[width * height];
// a bitset to use for functions that have to check which pixels have been worked on
checked = std::vector<bool>();
for(int i = 0; i < width * height; i++){
checked.push_back(false);
}
init_alpha();
}
PPMDraw::~PPMDraw(){
if(image != nullptr){
delete[] image;
}
}
void PPMDraw::fill(unsigned char r, unsigned char g, unsigned char b){
for(int i = 0; i < width * height; i++){
image[i + 0] = pixel{r, g, b};
}
}
void PPMDraw::set_color(unsigned char r, unsigned char g, unsigned char b){
red = r;
green = g;
blue = b;
}
void PPMDraw::draw_point(int x, int y){
if(x >= 0 && x < width && y >= 0 && y < height){
image[y * width + x] = pixel{red, green, blue};
}
}
void PPMDraw::draw_char(int x, int y, char c){
std::bitset<48> letter = font[c];
int n = 47;
for(int i = 0; i < 6; i++){
for(int j = 0; j < 8; j++){
if(letter[n]){
draw_point(x + i, y + j);
}
n--;
}
}
}
void PPMDraw::draw_string(int x, int y, std::string text){
for(unsigned int i = 0; i < text.length(); i++){
draw_char(x + 6 * i, y, text[i]);
}
}
bool PPMDraw::save(std::string file){
std::ofstream save(file.c_str(), std::ios_base::out | std::ios_base::binary);
if(save.is_open()){
save << "P6" << std::endl;
save << width << " " << height << std::endl;
save << "255" << std::endl;
unsigned char * temp = new unsigned char[height * width * 3];
for(int i = 0; i < height * width; i++){
temp[i * 3 + 0] = image[i].r;
temp[i * 3 + 1] = image[i].g;
temp[i * 3 + 2] = image[i].b;
}
save.write(reinterpret_cast<const char *> (temp), height*width*3*sizeof(unsigned char));
delete temp;
save.close();
return true;
}else{
return false;
}
}
void PPMDraw::init_alpha(){
// Define a simple font for drawing text
font[' '] = std::bitset<48> (std::string("000000000000000000000000000000000000000000000000"));
font['!'] = std::bitset<48> (std::string("000000000000000011110110000000000000000000000000"));
font['"'] = std::bitset<48> (std::string("000000001100000000000000110000000000000000000000"));
font['#'] = std::bitset<48> (std::string("001010001111111000101000111111100010100000000000"));
font['$'] = std::bitset<48> (std::string("001001000101010011111110010101000100100000000000"));
font['%'] = std::bitset<48> (std::string("000000100100110000010000011000001000010000000000"));
font['&'] = std::bitset<48> (std::string("000111001110001010110010110011000000001000000000"));
font['\\'] = std::bitset<48> (std::string("100000000110000000010000000011000000001000000000"));
font['('] = std::bitset<48> (std::string("000000000000000001111100100000100000000000000000"));
font[')'] = std::bitset<48> (std::string("000000001000001001111100000000000000000000000000"));
font['*'] = std::bitset<48> (std::string("010010000011000011100000001100000100100000000000"));
font['+'] = std::bitset<48> (std::string("000100000001000001111100000100000001000000000000"));
font[','] = std::bitset<48> (std::string("000000000000000000000110000000000000000000000000"));
font['-'] = std::bitset<48> (std::string("000100000001000000010000000100000001000000000000"));
font['.'] = std::bitset<48> (std::string("000000000000000000000100000000000000000000000000"));
font['/'] = std::bitset<48> (std::string("000000100000110000010000011000001000000000000000"));
font['0'] = std::bitset<48> (std::string("011111001000001010000010100000100111110000000000"));
font['1'] = std::bitset<48> (std::string("000000001000001011111110000000100000000000000000"));
font['2'] = std::bitset<48> (std::string("010011101001001010010010100100100111001000000000"));
font['3'] = std::bitset<48> (std::string("010001001000001010000010100100100110110000000000"));
font['4'] = std::bitset<48> (std::string("111100000001000000010000000100001111111000000000"));
font['5'] = std::bitset<48> (std::string("111001001001001010010010100100101001110000000000"));
font['6'] = std::bitset<48> (std::string("011111001001001010010010100100101000110000000000"));
font['7'] = std::bitset<48> (std::string("100000001000000010000110100110001110000000000000"));
font['8'] = std::bitset<48> (std::string("011011001001001010010010100100100110110000000000"));
font['9'] = std::bitset<48> (std::string("011000001001000010010000100100000111111000000000"));
font[':'] = std::bitset<48> (std::string("000000000000000001000100000000000000000000000000"));
font[';'] = std::bitset<48> (std::string("000000000000000001000110000000000000000000000000"));
font['<'] = std::bitset<48> (std::string("000000000001000000101000010001000000000000000000"));
font['='] = std::bitset<48> (std::string("001010000010100000101000001010000000000000000000"));
font['>'] = std::bitset<48> (std::string("000000000100010000101000000100000000000000000000"));
font['?'] = std::bitset<48> (std::string("010000001000000010001010100100000110000000000000"));
font['@'] = std::bitset<48> (std::string("011111001000001010111010101010100111001000000000"));
font['A'] = std::bitset<48> (std::string("011111101001000010010000100100000111111000000000"));
font['B'] = std::bitset<48> (std::string("111111101001001010010010100100100110110000000000"));
font['C'] = std::bitset<48> (std::string("011111001000001010000010100000100100010000000000"));
font['D'] = std::bitset<48> (std::string("111111101000001010000010100000100111110000000000"));
font['E'] = std::bitset<48> (std::string("111111101001001010010010100100101000001000000000"));
font['F'] = std::bitset<48> (std::string("111111101001000010010000100100001000000000000000"));
font['G'] = std::bitset<48> (std::string("011111001000001010000010100010100100110000000000"));
font['H'] = std::bitset<48> (std::string("111111100001000000010000000100001111111000000000"));
font['I'] = std::bitset<48> (std::string("100000101000001011111110100000101000001000000000"));
font['J'] = std::bitset<48> (std::string("000011000000001000000010000000101111110000000000"));
font['K'] = std::bitset<48> (std::string("111111100001000000010000001010001100011000000000"));
font['L'] = std::bitset<48> (std::string("111111100000001000000010000000100000001000000000"));
font['M'] = std::bitset<48> (std::string("111111101000000001100000100000001111111000000000"));
font['N'] = std::bitset<48> (std::string("111111100100000000100000000100001111111000000000"));
font['O'] = std::bitset<48> (std::string("011111001000001010000010100000100111110000000000"));
font['P'] = std::bitset<48> (std::string("111111101001000010010000100100001111000000000000"));
font['Q'] = std::bitset<48> (std::string("011111001000001010001010100001000111101000000000"));
font['R'] = std::bitset<48> (std::string("111111101001000010010000100110001111011000000000"));
font['S'] = std::bitset<48> (std::string("011000101001001010010010100100101000110000000000"));
font['T'] = std::bitset<48> (std::string("100000001000000011111110100000001000000000000000"));
font['U'] = std::bitset<48> (std::string("111111000000001000000010000000101111110000000000"));
font['V'] = std::bitset<48> (std::string("111110000000010000000010000001001111100000000000"));
font['W'] = std::bitset<48> (std::string("111111100000001000001100000000101111111000000000"));
font['X'] = std::bitset<48> (std::string("110001100010100000010000001010001100011000000000"));
font['Y'] = std::bitset<48> (std::string("110000000010000000011110001000001100000000000000"));
font['Z'] = std::bitset<48> (std::string("100001101000101010010010101000101100001000000000"));
font['['] = std::bitset<48> (std::string("000000001111111010000010100000100000000000000000"));
font['\''] = std::bitset<48> (std::string("100000000110000000010000000011000000001000000000"));
font[']'] = std::bitset<48> (std::string("000000001000001010000010111111100000000000000000"));
font['^'] = std::bitset<48> (std::string("001000000100000010000000010000000010000000000000"));
font['_'] = std::bitset<48> (std::string("000000100000001000000010000000100000001000000000"));
font['`'] = std::bitset<48> (std::string("000000001000000001000000000000000000000000000000"));
font['a'] = std::bitset<48> (std::string("000001000010101000101010001010100001111000000000"));
font['b'] = std::bitset<48> (std::string("111111100001001000010010000100100000110000000000"));
font['c'] = std::bitset<48> (std::string("000111000010001000100010001000100001010000000000"));
font['d'] = std::bitset<48> (std::string("000011000001001000010010000100101111111000000000"));
font['e'] = std::bitset<48> (std::string("000111000010101000101010001010100001101000000000"));
font['f'] = std::bitset<48> (std::string("000100000111111010010000100100000000000000000000"));
font['g'] = std::bitset<48> (std::string("001100100100100101001001010010010011111000000000"));
font['h'] = std::bitset<48> (std::string("111111100001000000010000000100000000111000000000"));
font['i'] = std::bitset<48> (std::string("000000000000000001011110000000000000000000000000"));
font['j'] = std::bitset<48> (std::string("000000100000000100000001010111100000000000000000"));
font['k'] = std::bitset<48> (std::string("111111100000100000010100001000100000000000000000"));
font['l'] = std::bitset<48> (std::string("000000000000000011111110000000000000000000000000"));
font['m'] = std::bitset<48> (std::string("000111100001000000001000000100000001111000000000"));
font['n'] = std::bitset<48> (std::string("001111100001000000010000000100000001111000000000"));
font['o'] = std::bitset<48> (std::string("000111000010001000100010001000100001110000000000"));
font['p'] = std::bitset<48> (std::string("001111110010010000100100001001000001100000000000"));
font['q'] = std::bitset<48> (std::string("000110000010010000100100001001000011111100000000"));
font['r'] = std::bitset<48> (std::string("000000000011111000010000000100000000000000000000"));
font['s'] = std::bitset<48> (std::string("000000000001001000101010001010100010010000000000"));
font['t'] = std::bitset<48> (std::string("000000000010000011111110001000000000000000000000"));
font['u'] = std::bitset<48> (std::string("000111000000001000000010000000100001110000000000"));
font['v'] = std::bitset<48> (std::string("000110000000010000000010000001000001100000000000"));
font['w'] = std::bitset<48> (std::string("000111100000001000000100000000100001111000000000"));
font['x'] = std::bitset<48> (std::string("001000100001010000001000000101000010001000000000"));
font['y'] = std::bitset<48> (std::string("001100000000100000000111000010000011000000000000"));
font['z'] = std::bitset<48> (std::string("010001100100101001010010011000100000000000000000"));
font['{'] = std::bitset<48> (std::string("000000000000000001101100100100100000000000000000"));
font['|'] = std::bitset<48> (std::string("000000000000000011111110000000000000000000000000"));
font['}'] = std::bitset<48> (std::string("000000000000000010010010011011000000000000000000"));
font['~'] = std::bitset<48> (std::string("000100000010000000010000000010000001000000000000"));
}
main.cpp
#include "PPMDraw.h"
#include <iostream>
int main(){
// ask for input
std::string input;
std::cout << "ENTER YOUR TEXT" << std::endl;
getline(std::cin, input);
// get size for image
int width = input.size() * 6;
PPMDraw image = PPMDraw(width, 8);
image.fill(255, 255, 255);
image.set_color(0, 0, 0);
image.draw_string(0, 0, input);
image.save("text.ppm");
}
Makefile
CC = g++
CFLAGS = -Wall -c -std=c++11
LFLAGS = -Wall
OBJS = main.o PPMDraw.o
list: $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o text2ppm
main.o: PPMDraw.h
$(CC) $(CFLAGS) main.cpp
PPMDraw.o: PPMDraw.h
$(CC) $(CFLAGS) PPMDraw.cpp
clean:
rm *.o main
Jeśli jesteś zainteresowany, pełna biblioteka PPMDraw jest tutaj :