110105 Graphical Editor

来源:互联网 发布:linux是典型的应用软件 编辑:程序博客网 时间:2024/06/04 23:19


#include <string.h>#include <iostream>#include <vector>#include <stdio.h>using namespace std;#define MAX_DIM 250#define INIT_COLOR 'O'typedef int Dim_t;typedef char Color_t;struct Graph{    Graph() : Row(0), Col(0)    {    }    Color_t Pixel[MAX_DIM][MAX_DIM];    Dim_t Row;    Dim_t Col;};class DrawOP{public:    virtual ~DrawOP() {}    virtual void Execute(Graph& graph) = 0;};class Init : public DrawOP{public:    Init(Dim_t row, Dim_t col) : Row(row), Col(col) {}    void Execute(Graph& graph)    {        for(Dim_t i = 0; i < Row; ++i)        {            memset(graph.Pixel[i], INIT_COLOR, Col * sizeof(graph.Pixel[0][0]));        }        graph.Row = Row;        graph.Col = Col;    }private:    Dim_t Row, Col;};class Clear : public DrawOP{public:    void Execute(Graph& graph)    {        for(Dim_t i = 0; i < graph.Row; ++i)        {            memset(graph.Pixel[i], INIT_COLOR, graph.Col * sizeof(graph.Pixel[0][0]));        }    }};class LPixel : public DrawOP{public:    LPixel(Dim_t row, Dim_t col, Color_t color) : Row(row), Col(col), Color(color) {}    void Execute(Graph& graph)    {        graph.Pixel[Row][Col] = Color;    }private:    Dim_t Row, Col;    Color_t Color;};#define MAX(x, y) ((x) > (y) ? (x) : (y))#define MIN(x, y) ((x) > (y) ? (y) : (x))class VLINE : public DrawOP{public:    VLINE(Dim_t col, Dim_t startRow, Dim_t endRow, Color_t color) :         Col(col), StartRow(MIN(startRow, endRow)), EndRow(MAX(startRow, endRow)), Color(color) {}    void Execute(Graph& graph)    {        for(Dim_t i = StartRow; i <= EndRow; ++i)        {            graph.Pixel[i][Col] = Color;        }    }private:    Dim_t Col, StartRow, EndRow;    Color_t Color;};class HLINE : public DrawOP{public:    HLINE(Dim_t row, Dim_t startCol, Dim_t endCol, Color_t color) :         Row(row), StartCol(MIN(startCol, endCol)), EndCol(MAX(startCol, endCol)), Color(color) {}    void Execute(Graph& graph)    {        for(Dim_t i = StartCol; i <= EndCol; ++i)        {            graph.Pixel[Row][i] = Color;        }    }private:    Dim_t Row, StartCol, EndCol;    Color_t Color;};class KRec : public DrawOP{public:    KRec(Dim_t topLeftX, Dim_t topLeftY,         Dim_t bottomRightX, Dim_t bottomRightY, Color_t color) :         TopLeftX(MIN(topLeftX, bottomRightX)), TopLeftY(MIN(topLeftY, bottomRightY)),         BottomRightX(MAX(topLeftX, bottomRightX)), BottomRightY(MAX(topLeftY, bottomRightY)),         Color(color) {}    void Execute(Graph& graph)    {        for(Dim_t i = TopLeftY; i <= BottomRightY; ++i)        {            for(Dim_t j = TopLeftX; j <= BottomRightX; ++j)            {                graph.Pixel[i][j] = Color;            }        }    }private:    Dim_t TopLeftX, TopLeftY, BottomRightX, BottomRightY;    Color_t Color;};class Fill : public DrawOP{public:    Fill(Dim_t row, Dim_t col, Color_t color) : Row(row), Col(col), Color(color) {}    void Execute(Graph& graph)    {        DoFill(graph, Row, Col, Color);    }private:    void DoFill(Graph& graph, Dim_t row, Dim_t col, Color_t newColor)    {        Color_t oldColor = graph.Pixel[row][col];        if (oldColor == newColor)            return;        graph.Pixel[row][col] = newColor;        if ((row > 0) && (graph.Pixel[row - 1][col] == oldColor)) // upper            DoFill(graph, row - 1, col, newColor);        if ((col > 0) && (graph.Pixel[row][col - 1] == oldColor)) // left            DoFill(graph, row, col - 1, newColor);        if ((row < (graph.Row - 1)) && (graph.Pixel[row + 1][col] == oldColor)) // below            DoFill(graph, row + 1, col, newColor);        if ((col < (graph.Col - 1)) && (graph.Pixel[row][col + 1] == oldColor)) // right            DoFill(graph, row, col + 1, newColor);    }private:    Dim_t Row, Col;    Color_t Color;};class SOutput : public DrawOP{public:        SOutput(char* fileName)     {        int len = strlen(fileName) + 1;        FileName = new char[len];        memcpy(FileName, fileName, len * sizeof(char));    }    ~SOutput()    {        delete FileName;    }    void Execute(Graph& graph)    {        cout << FileName << endl;        for(Dim_t i = 0; i < graph.Row; ++i)        {            for(Dim_t j = 0; j < graph.Col; ++j)            {                cout << graph.Pixel[i][j];            }            cout << endl;        }    }private:    char* FileName;};void ExecuteCmds(vector<DrawOP*>& ops, Graph& graph){    for(size_t i = 0; i < ops.size(); ++i)        ops[i]->Execute(graph);}void ClearCmds(vector<DrawOP*>& ops){    for(size_t i = 0; i < ops.size(); ++i)        delete ops[i];    ops.clear();}#define BUF_SIZE 1024bool ParseCmd_Char(vector<DrawOP*>& ops, char cmd, Graph& graph){    Dim_t u, v, w, x;    Color_t color;    static char tmp[BUF_SIZE];    switch(cmd)    {    case 'I':        cin >> u >> v;        ops.push_back(new Init(v, u));        break;    case 'C':        ops.push_back(new Clear());        break;    case 'L':        cin >> u >> v >> color;        ops.push_back(new LPixel(v-1, u-1, color));        break;    case 'V':        cin >> u >> v >> w >> color;        ops.push_back(new VLINE(u-1, v-1, w-1, color));        break;    case 'H':        cin >> u >> v >> w >> color;        ops.push_back(new HLINE(w-1, u-1, v-1, color));        break;    case 'K':        cin >> u >> v >> w >> x >> color;        ops.push_back(new KRec(u-1, v-1, w-1, x-1, color));        break;    case 'F':        cin >> u >> v >> color;        ops.push_back(new Fill(v-1, u-1, color));        break;    case 'S':        cin >> tmp;        ops.push_back(new SOutput(tmp));        ExecuteCmds(ops, graph);        ClearCmds(ops);        break;    case 'X':        return false;    default:        cin >> tmp;    }    return true;}char* StepToFirstNonSpace(char* line){    char* pTmp = line;    while((*pTmp) == ' ')        ++pTmp;    return pTmp;}void GetInfos(Dim_t& a, Dim_t& b, char* line){    char* pValidLine = StepToFirstNonSpace(line);    sscanf(pValidLine, "%d %d", &a, &b);}void GetInfos(Dim_t& a, Dim_t& b, Color_t& color, char* line){    char* pValidLine = StepToFirstNonSpace(line);    sscanf(pValidLine, "%d %d %c", &a, &b, &color);}void GetInfos(Dim_t& a, Dim_t& b, Dim_t& c, Color_t& color, char* line){    char* pValidLine = StepToFirstNonSpace(line);    sscanf(pValidLine, "%d %d %d %c", &a, &b, &c, &color);}void GetInfos(Dim_t& a, Dim_t& b, Dim_t& c, Dim_t& d, Color_t& color, char* line){    char* pValidLine = StepToFirstNonSpace(line);    sscanf(pValidLine, "%d %d %d %d %c", &a, &b, &c, &d, &color);}void GetInfos(char* dest, char* line){    char* pValidLine = StepToFirstNonSpace(line);    sscanf(pValidLine, "%s", dest);}bool ParseCmd_Str(vector<DrawOP*>& ops, char* cmd, Graph& graph){    Dim_t u, v, w, x;    Color_t color;    static char fileName[BUF_SIZE];    switch(cmd[0])    {    case 'I':        GetInfos(u, v, cmd + 1);        ops.push_back(new Init(v, u));        break;    case 'C':        ops.push_back(new Clear());        break;    case 'L':        GetInfos(u, v, color, cmd + 1);        ops.push_back(new LPixel(v-1, u-1, color));        break;    case 'V':        GetInfos(u, v, w, color, cmd + 1);        ops.push_back(new VLINE(u-1, v-1, w-1, color));        break;    case 'H':        GetInfos(u, v, w, color, cmd + 1);        ops.push_back(new HLINE(w-1, u-1, v-1, color));        break;    case 'K':        GetInfos(u, v, w, x, color, cmd + 1);        ops.push_back(new KRec(u-1, v-1, w-1, x-1, color));        break;    case 'F':        GetInfos(u, v, color, cmd + 1);        ops.push_back(new Fill(v-1, u-1, color));        break;    case 'S':        GetInfos(fileName, cmd + 1);        ops.push_back(new SOutput(fileName));        ExecuteCmds(ops, graph);        ClearCmds(ops);        break;    case 'X':        return false;    }    return true;}void InputCmds(vector<DrawOP*>& ops, Graph& graph){    char cmd[BUF_SIZE];    while(true)    {        fgets(cmd, BUF_SIZE, stdin);        if (!ParseCmd_Str(ops, cmd, graph))            return;    }}int main(int argc, char* argv[]){    Graph graph;    vector<DrawOP*> ops;    InputCmds(ops, graph);    ExecuteCmds(ops, graph);    ClearCmds(ops);    return 0;}