Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 26.25 KB | None | 0 0
  1. // Assignment 1 19T2 COMP1511: CS Paint
  2. // paint.c
  3.  
  4. // This program was written by Josh Amoils (z5256967).
  5.  
  6. /* Overview: This program simulates the 'Paint' tool used on many computers
  7.    today. The canvas is comprised of a 2D array of numbers that correspond to
  8.    different shades. As outlined in the spec, this program executes functions to
  9.    simulate the use of various tools used in 'Paint' such as the Line Drawing,
  10.    Rectangle Drawing, Shading and Additive Brush tools.
  11.    
  12.    Limitations: This program achieves all the requirements outlined in the spec.
  13.    However, the functionality of this program is limited if it were to be
  14.    practically used as a replacement to 'Paint'; this program only draws
  15.    45 degree diagonal lines, has only 5 shading options and can only use an
  16.    additive brush of size 3 x 3 pixels.
  17.    
  18.    Understanding the code: The program is structured as follows:
  19.        1. The Main Function: Scans in the first number of an input command line
  20.           and directs the program to the relevant general tool function.
  21.        2. The General Tool Functions: Each tool has a general function that
  22.           assesses the validity of the input commands and runs smaller functions
  23.           depending on the relevant positions of the inputted start and
  24.           endpoints.  
  25.        3. The Smaller Functions: Each of these void functions directly change
  26.           the state of the canvas in one specific way. Most of these smaller
  27.           functions are named as follows,
  28.           "General Function: Smaller Function". */
  29.  
  30. // Libraries used in this program.
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33.  
  34. // The dimensions of the canvas (20 rows x 36 columns).
  35. #define N_ROWS 20
  36. #define N_COLS 36
  37.  
  38. // Shades (assuming your terminal has a black background).
  39. #define BLACK 0
  40. #define DARK 1
  41. #define GREY 2
  42. #define LIGHT 3
  43. #define WHITE 4
  44.  
  45. // Instruction commands for each tool
  46. #define LINE_DRAWING 1
  47. #define RECTANGLE_DRAWING 2
  48. #define SHADE_CHANGE 3
  49. #define COPY_AND_PASTE 4
  50. #define ADDITIVE_BRUSH 5
  51.  
  52. // Defines the size of the command array (# of commands) by action_command.
  53. #define LINE_INPUT_SIZE 4
  54. #define RECTANGLE_INPUT_SIZE 4
  55. #define COPY_PASTE_INPUT_SIZE 6
  56. #define ADDITIVE_BRUSH_INPUT_SIZE 9
  57.  
  58. // Types of Brushes.
  59. #define NORMAL 0
  60. #define ADDITIVE 1
  61.  
  62. // 2D Dimension of Additive Brush.
  63. #define ADDITIVE_BRUSH_DIMENSION 3
  64.  
  65. // Prototypes
  66. // Prints out the canvas.
  67. void printCanvas(int canvas[N_ROWS][N_COLS]);
  68.  
  69. // Sets the entire canvas to be blank.
  70. void setBlankCanvas(int canvas[N_ROWS][N_COLS]);
  71.  
  72. // Gets inputs for the commands array.
  73. void get_commands(int commands[], int input_size);
  74.  
  75. // Checks if a given row/column coordinate lies on the canvas.
  76. int valid_row(int row);
  77. int valid_col(int col);
  78. int valid_bounds(int start_row, int start_col, int end_row, int end_col);
  79.  
  80. // General Line Drawing function (includes additive brush functions).
  81. void line(int canvas[N_ROWS][N_COLS], int start_row, int start_col, int end_row,
  82. int end_col, int shade, int brush,
  83. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]);
  84.  
  85. // Line Drawing: Horizontal line.
  86. void horizontal_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  87. int end_row, int end_col, int shade);
  88.  
  89. // Line Drawing: Vertical line.
  90. void vertical_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  91. int end_row, int end_col, int shade);
  92.  
  93. // Line Drawing: Diagonal line with positive or negative gradient.
  94. void pos_diagonal_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  95. int end_row, int end_col, int shade);
  96.  
  97. void neg_diagonal_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  98. int end_row, int end_col, int shade);
  99.  
  100. // General Rectangle Drawing function.
  101. void rectangle(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  102. int end_row, int end_col, int shade);
  103.  
  104. // Rectangle Drawing: Makes Rectangle change on canvas.
  105. void draw_rectangle(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  106. int end_row, int end_col, int shade);
  107.  
  108. /* Copy/Paste Function: Comprised of a copy section (4 cases) and a
  109.    paste section. */
  110. void copy_and_paste(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  111. int end_row, int end_col, int target_row, int target_col);
  112.  
  113. // Copy/Paste Function: Copy Function.
  114. void copy(int row_size, int col_size, int copy_array[row_size][col_size],
  115. int canvas[N_ROWS][N_COLS], int start_row, int start_col, int end_row,
  116. int end_col);
  117.  
  118. // Copy/Paste Function: Paste function.
  119. void paste(int row_size, int col_size,
  120. int copy_array[row_size][col_size], int canvas[N_ROWS][N_COLS],
  121. int target_row, int target_col);
  122.  
  123. /* General Additive Brush function (Stamps one pixel at a time with the current
  124.    additive brush settings. */
  125. void additive_stamp(int canvas[N_ROWS][N_COLS],
  126. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION],
  127. int row_counter, int col_counter);
  128.  
  129. // Additive Brush: Inputs additive brush settings.
  130. void additive_input(
  131. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION],
  132. int commands[ADDITIVE_BRUSH_INPUT_SIZE]);
  133.  
  134. // Additive Brush: Draws Horizontal line with additive brush settings.
  135. void additive_brush_horiz(int canvas[N_ROWS][N_COLS], int start_row,
  136. int start_col, int end_row, int end_col,
  137. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]);
  138.  
  139. // Additive Brush: Draws Vertical line with additive brush settings.
  140. void additive_brush_vert(int canvas[N_ROWS][N_COLS], int start_row,
  141. int start_col, int end_row, int end_col,
  142. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]);
  143.  
  144. /* Additive Brush: Draws Diagonal line with positive gradient with
  145.    additive brush settings. */
  146. void additive_brush_pos_diagonal(int canvas[N_ROWS][N_COLS], int start_row,
  147. int start_col, int end_row, int end_col,
  148. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]);
  149.  
  150. /* Additive Brush: Draws Diagonal line with negative gradient with
  151.    additive brush settings. */
  152. void additive_brush_neg_diagonal(int canvas[N_ROWS][N_COLS], int start_row,
  153. int start_col, int end_row, int end_col,
  154. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]);
  155.  
  156. /* Checks if the a pixel's shade is still valid after the additive brush has
  157.    been applied. If it is not, this function will set the pixel to either
  158.    White or BLACK. */
  159. int valid_shade(int shade);
  160.  
  161. //Main Function
  162. int main(void) {
  163.    
  164.     /* Declares the canvas, action_command and the 2D array that stores the
  165.        additive brush settings. */
  166.     int canvas[N_ROWS][N_COLS];
  167.     int action_command;
  168.     int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION];
  169.    
  170.     /* Sets the default shade to BLACK and the default brush to
  171.        NORMAL (non-additive). */
  172.     int shade = BLACK;
  173.     int brush = NORMAL;
  174.    
  175.     // Makes canvas blank.
  176.     setBlankCanvas(canvas);
  177.    
  178.     /* Checks if command input exists and assigns it to the action_command
  179.        (the first number inputted on every line by the user).
  180.        The action_command is then used to direct the main function to the
  181.        relevant cs_paint functions. */
  182.     while (scanf("%d", &action_command) == 1) {
  183.        
  184.         // Resets the shade to the second command if it's a valid shade.
  185.         if (action_command == SHADE_CHANGE) {
  186.             int possible_shade;
  187.             scanf("%d", &possible_shade);  
  188.             if (possible_shade >= 0 && possible_shade <= 4) {
  189.                 shade = possible_shade;
  190.                 brush = NORMAL;
  191.             }
  192.         }
  193.         /* Collects subsequent commands and directs the program to the Draw Line
  194.            functions, taking into account the current shade and brush. */
  195.         if (action_command == LINE_DRAWING) {
  196.             int commands[LINE_INPUT_SIZE];
  197.             get_commands(commands, LINE_INPUT_SIZE);
  198.             line(canvas, commands[0], commands[1], commands[2], commands[3],
  199.             shade, brush, add_shade);
  200.         }
  201.         /* Collects subsequent commands and directs the program to the Rectangle
  202.            function, taking into account the current shade. */
  203.         else if (action_command == RECTANGLE_DRAWING) {
  204.             int commands[RECTANGLE_INPUT_SIZE];
  205.             get_commands(commands, RECTANGLE_INPUT_SIZE);
  206.             rectangle(canvas, commands[0], commands[1], commands[2],
  207.             commands[3], shade);
  208.         }
  209.         /* Collects subsequent commands and directs the program to the
  210.             Copy/Paste function. */
  211.         else if (action_command == COPY_AND_PASTE) {
  212.             int commands[COPY_PASTE_INPUT_SIZE];
  213.             get_commands(commands, COPY_PASTE_INPUT_SIZE);
  214.             copy_and_paste(canvas, commands[0], commands[1], commands[2],
  215.             commands[3], commands[4], commands[5]);
  216.         }
  217.         /*Collects subsequent commands and directs the program to the additive
  218.           brush customisation function. Inputs the whole command array into
  219.           the additive_input function rather than individual values as shown in
  220.           the other commands.This increases the maintainability of the additive
  221.           brush feature, allowing the brush size to be easily adjusted for
  222.           different stamp sizes.*/
  223.         else if (action_command == ADDITIVE_BRUSH) {
  224.             int commands[ADDITIVE_BRUSH_INPUT_SIZE];
  225.             get_commands(commands, ADDITIVE_BRUSH_INPUT_SIZE);
  226.             additive_input(add_shade, commands);
  227.             brush = ADDITIVE;
  228.         }
  229.     }
  230.    
  231.     // Prints the canvas after all the adjustments.  
  232.     printCanvas(canvas);
  233.  
  234.     return 0;
  235. }
  236.  
  237. // Functions
  238. // Collects Commands and stores them in an array called "commands".
  239. void get_commands(int commands[], int input_size) {
  240.  
  241.     int counter = 0;
  242.     while (counter < input_size) {
  243.         scanf("%d", &commands[counter]);
  244.         counter++;
  245.     }
  246. }
  247.  
  248. // Checks if a row value is valid.
  249. int valid_row(int row) {
  250.  
  251.     int valid = 0;
  252.     if (row >= 0 && row < N_ROWS) {
  253.         valid = 1;
  254.     }
  255.     return valid;
  256. }
  257.          
  258. // Checks if a column value is valid.
  259. int valid_col(int col) {
  260.  
  261.     int valid = 0;
  262.     if (col >= 0 && col < N_COLS) {
  263.         valid = 1;
  264.     }
  265.     return valid;
  266. }
  267.  
  268. // Checks if input bounds are valid.
  269. int valid_bounds(int start_row, int start_col, int end_row, int end_col) {
  270.  
  271.     int valid = 0;
  272.     if (valid_row(start_row) && valid_row(end_row) && valid_col(start_col) &&
  273.     valid_col(end_col)) {
  274.         valid = 1;
  275.     }
  276.     return valid;
  277. }
  278.  
  279. // Lines Drawing
  280. void line(int canvas[N_ROWS][N_COLS], int start_row, int start_col, int end_row,
  281. int end_col, int shade, int brush,
  282. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]) {
  283.  
  284.     // Checks if the commands are valid.
  285.     if (valid_bounds(start_row, start_col, end_row, end_col)) {
  286.         // If brush is normal, program uses Stage 1/2 functions.
  287.         if (brush == NORMAL) {
  288.             /* Draws a Horizontal line, taking into account the forwards and
  289.                backwards cases. */
  290.             if (start_row == end_row) {
  291.                 if (start_col < end_col) {
  292.                     horizontal_line(canvas, start_row, start_col, end_row,
  293.                     end_col, shade);
  294.                 }
  295.                 else {
  296.                     horizontal_line(canvas, start_row, end_col, end_row,
  297.                     start_col, shade);
  298.                 }
  299.             }
  300.             /* Draws a Vertical line, taking into account the forwards and
  301.                backwards cases. */
  302.             else if (start_col == end_col) {
  303.                 if (start_row < end_row) {
  304.                     vertical_line(canvas, start_row, start_col, end_row,
  305.                     end_col, shade);
  306.                     }
  307.                 else {
  308.                     vertical_line(canvas, end_row, start_col, start_row,
  309.                     end_col, shade);
  310.                 }
  311.             }
  312.             /* Draws a Diagonal line. If the distance between the rows is equal
  313.                to the difference between the columns, the line is angled at
  314.                45 degrees. */  
  315.             else if (abs(end_row - start_row) == abs(end_col - start_col)) {
  316.                 // Line with negative gradient.
  317.                 if (start_row < end_row && start_col < end_col) {
  318.                     neg_diagonal_line(canvas, start_row, start_col, end_row,
  319.                     end_col, shade);
  320.                 }
  321.                 else if (start_row > end_row && start_col > end_col) {
  322.                     neg_diagonal_line(canvas, end_row, end_col, start_row,
  323.                     start_col, shade);
  324.                 }
  325.                 // Line with positive gradient.
  326.                 else if (start_row > end_row && start_col < end_col) {
  327.                     pos_diagonal_line(canvas, start_row, start_col, end_row,
  328.                     end_col, shade);
  329.                 }
  330.                 else if (start_row < end_row && start_col > end_col) {
  331.                     pos_diagonal_line(canvas, end_row, end_col, start_row,
  332.                     start_col, shade);
  333.                 }
  334.             }
  335.         }    
  336.         /* Directs program to Draw Line functions that take into account current
  337.            additive brush settings. */
  338.         else if (brush == ADDITIVE) {
  339.             // Horizontal line.
  340.             if (start_row == end_row) {
  341.                 if (start_col < end_col) {
  342.                     additive_brush_horiz(canvas, start_row, start_col, end_row,
  343.                     end_col, add_shade);
  344.                 }
  345.                 else {
  346.                     additive_brush_horiz(canvas, start_row, end_col, end_row,
  347.                     start_col, add_shade);
  348.                 }
  349.             }
  350.             // Vertical line.
  351.             else if (start_col == end_col) {
  352.                 if (start_row < end_row) {
  353.                     additive_brush_vert(canvas, start_row, start_col, end_row,
  354.                     end_col, add_shade);  
  355.                 }
  356.                 else {
  357.                     additive_brush_vert(canvas, end_row, start_col, start_row,
  358.                     end_col, add_shade);    
  359.                 }
  360.             }
  361.             // Diagonal Lines.
  362.             else if (abs(end_row - start_row) == abs(end_col - start_col)) {
  363.                 if (start_row < end_row && start_col < end_col) {
  364.                     additive_brush_pos_diagonal(canvas, start_row, start_col,
  365.                     end_row, end_col, add_shade);
  366.                 }
  367.                 else if (start_row > end_row && start_col > end_col) {
  368.                     additive_brush_pos_diagonal(canvas, end_row, end_col,
  369.                     start_row, start_col, add_shade);
  370.                 }
  371.                 else if (start_row > end_row && start_col < end_col) {
  372.                     additive_brush_neg_diagonal(canvas, start_row, start_col,
  373.                     end_row, end_col, add_shade);
  374.                 }
  375.                 else if (start_row < end_row && start_col > end_col) {
  376.                     additive_brush_neg_diagonal(canvas, end_row, end_col,
  377.                     start_row, start_col, add_shade);
  378.                 }
  379.             }    
  380.         }
  381.     }    
  382. }
  383.  
  384. // Normal Brush: Draws Horizontal line.
  385. void horizontal_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  386. int end_row, int end_col, int shade) {
  387.  
  388.     while (start_col <= end_col) {
  389.         canvas[start_row][start_col] = shade;
  390.         start_col++;  
  391.     }
  392. }
  393.  
  394. // Normal Brush: Draws Vertical line.
  395. void vertical_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  396. int end_row, int end_col, int shade) {
  397.  
  398.     while (start_row <= end_row) {
  399.         canvas[start_row][start_col] = shade;
  400.         start_row++;  
  401.     }
  402. }
  403.  
  404. // Normal Brush: Draws Diagonal line with a negative gradient.
  405. void neg_diagonal_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  406. int end_row, int end_col, int shade) {
  407.  
  408.     int col_counter = start_col;
  409.     int row_counter = start_row;
  410.     while (col_counter <= end_col) {
  411.         canvas[row_counter][col_counter] = shade;
  412.         col_counter++;
  413.         row_counter++;
  414.     }
  415. }
  416.  
  417. // Normal Brush: Draws Diagonal line with a positive gradient.
  418. void pos_diagonal_line(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  419. int end_row, int end_col, int shade) {
  420.  
  421.     int col_counter = start_col;
  422.     int row_counter = start_row;
  423.     while (col_counter <= end_col) {
  424.         canvas[row_counter][col_counter] = shade;
  425.         col_counter++;
  426.         row_counter--;
  427.     }
  428. }
  429.  
  430. // General Rectangle Function.
  431. void rectangle(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  432. int end_row, int end_col, int shade) {
  433.  
  434.     if (valid_bounds(start_row, start_col, end_row, end_col)) {
  435.         // Rectangle: Case 1.
  436.         if (start_row <= end_row && start_col <= end_col) {
  437.             draw_rectangle(canvas, start_row, start_col, end_row, end_col,
  438.             shade);
  439.         }
  440.         // Rectangle: Case 2.
  441.         else if (end_row <= start_row && start_col <= end_col) {
  442.             draw_rectangle(canvas, end_row, start_col, start_row, end_col,
  443.             shade);
  444.         }
  445.         // Rectangle: Case 3.
  446.         else if (start_row <= end_row && end_col <= start_col) {
  447.             draw_rectangle(canvas, start_row, end_col, end_row, start_col,
  448.             shade);    
  449.         }
  450.         // Rectangle: Case 4.
  451.         else {
  452.             draw_rectangle(canvas, end_row, end_col, start_row, start_col,
  453.             shade);      
  454.         }    
  455.     }
  456. }
  457. // Rectangle Function: Draws the rectangle by looping through the rows/coloumns.
  458. void draw_rectangle(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  459. int end_row, int end_col, int shade) {
  460.  
  461.     int row_counter = start_row;
  462.     int col_counter = start_col;
  463.     while (row_counter <= end_row) {
  464.         col_counter = start_col;
  465.         while (col_counter <= end_col) {
  466.             canvas[row_counter][col_counter] = shade;
  467.             col_counter++;
  468.         }
  469.         row_counter++;
  470.     }
  471. }  
  472.  
  473. /* Copy and paste function. The desired area is copied (taking into account the
  474.    relative positions of start and end) and then pasted. */
  475. void copy_and_paste(int canvas[N_ROWS][N_COLS], int start_row, int start_col,
  476. int end_row, int end_col, int target_row, int target_col) {
  477.    
  478.     int diff_row = abs(end_row - start_row);
  479.     int diff_col = abs(end_col - start_col);
  480.    
  481.     // Checks that all points are valid and that target area lies on the canvas.
  482.     if (valid_bounds(start_row, start_col, end_row, end_col)
  483.     && (valid_bounds(target_row, target_col, (target_row + diff_row),
  484.     (target_col + diff_col)))) {
  485.         int copy_array[diff_row + 1][diff_col + 1];
  486.        
  487.         // Copy: Case 1.
  488.         if ((start_row < end_row) && (start_col < end_col)) {
  489.             copy(diff_row + 1, diff_col + 1, copy_array, canvas, start_row,
  490.             start_col, end_row, end_col);
  491.         }
  492.          
  493.         // Copy: Case 2.
  494.         else if ((start_row > end_row) && (start_col < end_col)) {
  495.             copy(diff_row + 1, diff_col + 1, copy_array, canvas, end_row,
  496.             start_col, start_row, end_col);
  497.         }
  498.         // Copy: Case 3.
  499.         else if ((start_row < end_row) && (start_col > end_col)) {
  500.             copy(diff_row + 1, diff_col + 1, copy_array, canvas, start_row,
  501.             end_col, end_row, start_col);
  502.         }
  503.         // Copy: Case 4.
  504.         else {
  505.             copy(diff_row + 1, diff_col + 1, copy_array, canvas, end_row,
  506.             end_col, start_row, start_col);
  507.         }
  508.        
  509.         // Pastes the stored copy_array into the target area on the canvas.
  510.         paste(diff_row + 1, diff_col + 1, copy_array, canvas, target_row, target_col);
  511.                
  512.     }
  513. }
  514.  
  515. /* Copy and Paste: Copy function. Stores the desired area in a 2D array called
  516.    copy_array. */
  517. void copy(int row_size, int col_size, int copy_array[row_size][col_size],
  518. int canvas[N_ROWS][N_COLS], int start_row, int start_col, int end_row,
  519. int end_col) {
  520.  
  521.     int row_counter_array = 0;
  522.     int col_counter_array = 0;
  523.     int col_counter = start_col;
  524.     int row_counter = start_row;
  525.    
  526.     while (row_counter <= end_row) {
  527.         col_counter = start_col;
  528.         col_counter_array = 0;
  529.         while (col_counter <= end_col) {
  530.             copy_array[row_counter_array][col_counter_array]
  531.             = canvas[row_counter][col_counter];
  532.             col_counter++;
  533.             col_counter_array++;
  534.         }
  535.         row_counter++;
  536.         row_counter_array++;
  537.     }
  538. }
  539.  
  540. /* Copy and Paste: Paste function. Pastes copy_array onto the target area of the
  541.    canvas. */
  542. void paste(int row_size, int col_size,
  543. int copy_array[row_size][col_size], int canvas[N_ROWS][N_COLS],
  544. int target_row, int target_col) {
  545.  
  546.     int target_end_row = target_row + row_size - 1;
  547.     int target_end_col = target_col + col_size - 1;
  548.     int row_counter_array = 0;
  549.     int col_counter_array = 0;
  550.     int col_counter = target_col;
  551.    
  552.     while (target_row <= target_end_row) {
  553.         col_counter_array = 0;
  554.         col_counter = target_col;
  555.         while (col_counter <= target_end_col) {
  556.             canvas[target_row][col_counter]
  557.             = copy_array[row_counter_array][col_counter_array];
  558.             col_counter_array++;
  559.             col_counter++;
  560.         }
  561.         row_counter_array++;
  562.         target_row++;
  563.     }
  564. }      
  565. // Additive Brush: Inputs Additive Brush settings into a 3 x 3 array.
  566. void additive_input(
  567. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION],
  568. int commands[ADDITIVE_BRUSH_INPUT_SIZE]) {
  569.  
  570.     int col_counter = 0;
  571.     int row_counter = 0;
  572.    
  573.     while (row_counter <= 2) {
  574.         col_counter = 0;
  575.         while (col_counter <=2) {
  576.             add_shade[row_counter][col_counter]
  577.             = commands[(row_counter * 3) + col_counter];
  578.             col_counter++;
  579.         }
  580.         row_counter++;
  581.     }
  582. }
  583.  
  584. /* Additive Brush: Stamp Function. The stamp function will be called to
  585.    re-colour the 3 x 3 pixels around each referenced pixel in the Additive Draw
  586.    Line functions based on the current settings in the add_shade array. */
  587. void additive_stamp(int canvas[N_ROWS][N_COLS],
  588. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION],
  589. int row_counter, int col_counter) {
  590.  
  591.     // Loops through the columns around the referenced pixel from left to right.
  592.     int horiz = -1;
  593.     // Loops through the rows around the referenced pixel from top to bottom.
  594.     int vert = -1;
  595.     while (horiz <= 1) {
  596.         vert = -1;
  597.         while (vert <= 1) {
  598.             canvas[row_counter + vert][col_counter + horiz]
  599.             += add_shade[vert + 1][horiz + 1];
  600.             canvas[row_counter + vert][col_counter + horiz] =
  601.             valid_shade(canvas[row_counter + vert][col_counter + horiz]);
  602.             vert++;
  603.         }
  604.         horiz++;
  605.     }
  606. }
  607.    
  608. // Additive Brush: Draws Horizontal Line.
  609. void additive_brush_horiz(int canvas[N_ROWS][N_COLS], int start_row,
  610. int start_col, int end_row, int end_col,
  611. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]) {
  612.  
  613.     if (valid_bounds(start_row -1, start_col - 1, end_row + 1 , end_col + 1)) {
  614.         int col_counter = start_col;
  615.         while (col_counter <= end_col) {
  616.             additive_stamp(canvas, add_shade, start_row, col_counter);
  617.             col_counter++;
  618.         }
  619.     }
  620. }
  621.  
  622. // Additive Brush: Draws Vertical Line.
  623. void additive_brush_vert(int canvas[N_ROWS][N_COLS], int start_row,
  624. int start_col, int end_row, int end_col,
  625. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]) {
  626.  
  627.     if (valid_bounds(start_row - 1, start_col - 1, end_row + 1 , end_col + 1)) {
  628.         int row_counter = start_row;
  629.         while (row_counter <= end_row) {
  630.             additive_stamp(canvas, add_shade, row_counter, start_col);
  631.             row_counter++;
  632.         }
  633.     }                                                                                                                                  
  634. }
  635.  
  636. // Additive Brush: Draws Diagonal Line with a positive gradient.
  637. void additive_brush_pos_diagonal(int canvas[N_ROWS][N_COLS], int start_row,
  638. int start_col, int end_row, int end_col,
  639. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]) {
  640.  
  641.     if (valid_bounds(start_row - 1, start_col - 1, end_row + 1 , end_col + 1)) {
  642.         int col_counter = start_col;
  643.         int row_counter = start_row;
  644.         while (col_counter <= end_col) {
  645.             additive_stamp(canvas, add_shade, row_counter, col_counter);
  646.             col_counter++;
  647.             row_counter++;
  648.         }
  649.     }
  650. }
  651.  
  652. // Additive Brush: Draws Diagonal Line with a negative gradient.
  653. void additive_brush_neg_diagonal(int canvas[N_ROWS][N_COLS], int start_row,
  654. int start_col, int end_row, int end_col,
  655. int add_shade[ADDITIVE_BRUSH_DIMENSION][ADDITIVE_BRUSH_DIMENSION]) {
  656.  
  657.     if (valid_bounds(start_row - 1, start_col + 1, end_row + 1 , end_col - 1)) {
  658.         int col_counter = start_col;
  659.         int row_counter = start_row;
  660.         while (col_counter <= end_col) {
  661.             additive_stamp(canvas, add_shade, row_counter, col_counter);
  662.             col_counter++;
  663.             row_counter--;
  664.         }
  665.     }
  666. }  
  667.    
  668. /* Checks if the a pixel's shade is still valid after the additive brush has
  669.    been applied. If it is not, this function will set the pixel to either
  670.    White or BLACK. */
  671. int valid_shade(int shade) {
  672.  
  673.     if (shade > WHITE) {
  674.         shade = WHITE;
  675.     }
  676.     else if (shade < BLACK) {
  677.         shade = BLACK;
  678.     }
  679.     return shade;
  680. }  
  681.  
  682. /* Prints the canvas, by printing the integer value stored in
  683.    each element of the 2-dimensional canvas array. */
  684. void printCanvas(int canvas[N_ROWS][N_COLS]) {
  685.  
  686.     int row = 0;
  687.     while (row < N_ROWS) {
  688.         int col = 0;
  689.         while (col < N_COLS) {
  690.             printf("%d ", canvas[row][col]);
  691.             col++;
  692.         }
  693.         row++;
  694.         printf("\n");
  695.     }
  696. }
  697.  
  698.  
  699. /* Sets the entire canvas to be blank, by setting each element in the
  700.    2-dimensional canvas array to be WHITE (which is #defined at the top
  701.    of the file). */
  702. void setBlankCanvas(int canvas[N_ROWS][N_COLS]) {
  703.  
  704.     int row = 0;
  705.     while (row < N_ROWS) {
  706.         int col = 0;
  707.         while (col < N_COLS) {
  708.             canvas[row][col] = WHITE;
  709.             col++;
  710.         }
  711.         row++;
  712.     }
  713. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement