From 05f4df3685b83b281d907589d547c894be3f1eb0 Mon Sep 17 00:00:00 2001 From: "Wayne C. Gramlich" Date: Sun, 1 Sep 2013 14:09:56 -0700 Subject: [PATCH] Initial code. --- .gitignore | 5 ++ Double.c | 6 ++ Double.h | 10 ++++ File.c | 46 +++++++++++++++ File.h | 19 +++++++ Integer.c | 0 Integer.h | 10 ++++ Logical.c | 5 ++ Logical.h | 9 +++ Makefile | 79 ++++++++++++++++++++++++++ Memory.c | 28 +++++++++ Memory.h | 35 ++++++++++++ SVG.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++ SVG.h | 60 ++++++++++++++++++++ String.c | 53 +++++++++++++++++ String.h | 18 ++++++ Tags.c | 79 ++++++++++++++++++++++++++ Unsigned.c | 5 ++ Unsigned.h | 5 ++ 19 files changed, 635 insertions(+) create mode 100644 .gitignore create mode 100644 Double.c create mode 100644 Double.h create mode 100644 File.c create mode 100644 File.h create mode 100644 Integer.c create mode 100644 Integer.h create mode 100644 Logical.c create mode 100644 Logical.h create mode 100644 Makefile create mode 100644 Memory.c create mode 100644 Memory.h create mode 100644 SVG.c create mode 100644 SVG.h create mode 100644 String.c create mode 100644 String.h create mode 100644 Tags.c create mode 100644 Unsigned.c create mode 100644 Unsigned.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eee5cc --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*~ +*.o +*.d +Tags +Tags.ezc diff --git a/Double.c b/Double.c new file mode 100644 index 0000000..40de740 --- /dev/null +++ b/Double.c @@ -0,0 +1,6 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#include "Double.h" + +// Any *Double* support code goes here. + diff --git a/Double.h b/Double.h new file mode 100644 index 0000000..bfe5f68 --- /dev/null +++ b/Double.h @@ -0,0 +1,10 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#if !defined(DOUBLE_H_INCLUDED) +#define DOUBLE_H_INCLUDED 1 + +/// @brief *Double* is a double precision (64-bits) floating point number. +typedef double Double; + +#endif // !defined(DOUBLE_H_INCLUDED) + diff --git a/File.c b/File.c new file mode 100644 index 0000000..b4571a6 --- /dev/null +++ b/File.c @@ -0,0 +1,46 @@ +// Copyright (c) 2013 by Wayne C. Gramlich all rights reserved. + +#include + +#include "File.h" +#include "String.h" + +// *File* routines: + +/// @brief Closes *file*. +/// @param file to close. +/// +/// *File__close*() will close *file*. + +void File__close(File file) { + assert (fclose(file) == 0); +} + +/// @brief will write *format* out to *file* with all patterns that +/// start with "%" replaced by formatted versions of its arguments. +/// @param file to output to. +/// @parma format is the formatting string. +/// +/// *File__format*() will write *format* out to *file* with all patterns that +/// start with "%" replaced by formatted versions of its arguments. + +void File__format(File file, String format, ...) { + // Set up *variadic_arguments to start after *format*: + va_list variadic_arguments; + va_start(variadic_arguments, format); + + // Perform the format: + Unsigned formatted_size = vfprintf(file, format, variadic_arguments); +} + +/// @brief will open *file_name* using *flags* to specify read/write options. +/// @param file_name is the file name to open. +/// @param flags specify the read/write options. +/// +/// *File__open*() will open *file_name* using *flags* to read/write options. +/// An open *File* object is returned or (*File)0 if the open failed. + +File File__open(String file_name, String flags) { + return fopen(file_name, flags); +} + diff --git a/File.h b/File.h new file mode 100644 index 0000000..8fecfaf --- /dev/null +++ b/File.h @@ -0,0 +1,19 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#if !defined(FILE_H_INCLUDED) +#define FILE_H_INCLUDED 1 + +#include +#include + +#include "String.h" + +/// @brief *FILE* is a file I/O object. +typedef FILE *File; + +// External declarations: +extern void File__close(File file); +extern void File__format(File file, String format, ...); +extern File File__open(String file_name, String flags); + +#endif // !defined(FILE_H_INCLUDED) diff --git a/Integer.c b/Integer.c new file mode 100644 index 0000000..e69de29 diff --git a/Integer.h b/Integer.h new file mode 100644 index 0000000..88da12c --- /dev/null +++ b/Integer.h @@ -0,0 +1,10 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#if !defined(INTEGER_H_INCLUDED) +#define INTEGER_H_INCLUDED 1 + +/// @brief *Integer* is a 32-bit signed integer. +typedef int Integer; + +#endif // !defined(INTEGER_H_INCLUDED) + diff --git a/Logical.c b/Logical.c new file mode 100644 index 0000000..9b2c7fd --- /dev/null +++ b/Logical.c @@ -0,0 +1,5 @@ +// Copyright (c) by Wayne C. Gramlich. All rights reserved. + +#include "Logical.h" + +// Any *Logical* support code goes here. diff --git a/Logical.h b/Logical.h new file mode 100644 index 0000000..3af6050 --- /dev/null +++ b/Logical.h @@ -0,0 +1,9 @@ +/// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#if !defined(LOGICAL_H_INCLUDED) +#define LOGICAL_H_INCLUDED 1 + +/// @brief *Logical* is a true/false value. +typedef int Logical; + +#endif // !defined(LOGICAL_H_INCLUDED) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5da51ed --- /dev/null +++ b/Makefile @@ -0,0 +1,79 @@ +# Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + + +C_WARNING_OPTIONS := \ + -Wreturn-type \ + -Wno-missing-braces \ + -Wextra \ + -Wno-missing-field-initializers \ + -Wformat=2 \ + -Wswitch-default \ + -Wcast-align \ + -Wpointer-arith \ + -Wbad-function-cast \ + -Wstrict-overflow=5 \ + -Wstrict-prototypes \ + -Winline \ + -Wundef \ + -Wcast-qual \ + -Wshadow \ + -Wunreachable-code \ + -Wlogical-op \ + -Wfloat-equal \ + -Wstrict-aliasing=2 \ + -Wold-style-definition \ + -Werror \ + +C_OPTIONS := \ + -std=c11 \ + -g \ + -MMD \ + ${C_WARNING_OPTIONS} \ + +CC := gcc ${C_OPTIONS} + +COMMON_O_FILES := \ + Double.o \ + File.o \ + Integer.o \ + Logical.o \ + Memory.o \ + String.o \ + SVG.o \ + Unsigned.o \ + +TAGS_O_FILES := \ + Tags.o \ + +ALL_O_FILES := \ + ${COMMON_O_FILES} \ + ${TAGS_O_FILES} \ + +ALL_C_BACKUPS := ${ALL_O_FILES:%.o=%.c~} +ALL_D_FILES := ${ALL_O_FILES:%.o=%.d} +ALL_H_BACKUPS := ${ALL_O_FILES:%.o=%.h~} + +PROGRAMS := \ + Tags \ + +all: ${PROGRAMS} + +Tags: ${COMMON_O_FILES} ${TAGS_O_FILES} + $(CC) -o $@ ${TAGS_O_FILES} ${COMMON_O_FILES} + +clean: + rm -f ${ALL_C_BACKUPS} + rm -f ${ALL_D_FILES} + rm -f ${ALL_H_BACKUPS} + rm -f ${ALL_O_FILES} + rm -f ${PROGRAMS} + rm Makefile~ Tags.ezc~ + +%.o: %c + $(CC) -c -o $@ $< + + +# Used with gcc -MMD option to force automagic dependency checking: +-include ${ALL_D_FILES} + + diff --git a/Memory.c b/Memory.c new file mode 100644 index 0000000..4b6ca03 --- /dev/null +++ b/Memory.c @@ -0,0 +1,28 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#include +#include +#include "Unsigned.h" +#include "Memory.h" + +/// @brief Allocates *bytes* of memory and returns a pointer to it. +/// @param bytes is the number of bytes to allocate. +/// @returns a pointer to the allocated memory chunk. +/// +/// *Memory__allocate*() will allocated and return a pointer to a chunk +/// of *bytes* memory. + +Memory Memory__allocate(Unsigned bytes) { + Memory memory = (Memory)malloc(bytes); + assert (memory != (Memory)0); + return memory; +} + +/// @brief Releases the storage associated with *memory*. +/// @param memory to release. +/// +/// *Memory__free*() will release the storage associated with *memory*. + +void Memory__free(Memory memory) { + free(memory); +} diff --git a/Memory.h b/Memory.h new file mode 100644 index 0000000..78824ec --- /dev/null +++ b/Memory.h @@ -0,0 +1,35 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#if !defined(MEMORY_H_INCLUDED) +#define MEMORY_H_INCLUDED 1 + +/// @brief Allocate a *Type* object from the heap. +/// +/// The type must be a pointer type where the underlying type defintion +/// is available to the compiler. +/// +/// This allocates an object of type *Type* by doing "Memory_new(Type)". +/// This macro when expanded works as follows: +/// +/// Type zilch = (Type)0; +/// UInteger type_size = sizeof(*zilch); +/// Type type = (Type)Memory_allocate(type_size); +/// +/// "sizeof(*((Type)0))" does not generate any code. The compiler +/// evaluates it to get the number of bytes associated with "Type": + +#define Memory__new(Type) ((Type)Memory__allocate(sizeof(*((Type)0)))) + +/// @brief *Memory* is a pointer to memory. +typedef void *Memory; + +#include "Unsigned.h" + +// Extern declarations: + +extern Memory Memory__allocate(Unsigned bytes); +extern void Memory__free(Memory memory); + + +#endif // !defined(MEMORY_H_INCLUDED) + diff --git a/SVG.c b/SVG.c new file mode 100644 index 0000000..5bf3dfe --- /dev/null +++ b/SVG.c @@ -0,0 +1,163 @@ +// Copyright (c) by Wayne C. Gramlich. All rights reserved. + +#include "SVG.h" + +/// @brief Close SVG object. +/// @param svg object to close +/// +/// *SVG__close*() will close *svg*. + +void SVG__close(SVG svg) { + // Close *svg*: + File svg_stream = svg->stream; + File__format(svg_stream, "\n"); + File__close(svg_stream); + svg->stream = (File)0; +} + +/// @brief Draw a line from (*x1*, *y1*) to (*x2*, *y2*) using *stroke*. +/// @param svg is the *SVG* object to draw line to. +/// @param x1 is X coordinate of first point. +/// @param y1 is Y coordinate of first point. +/// @param x2 is X coordinate of second point. +/// @param y2 is Y coordinate of second point. +/// @param stroke is stroke string. +/// +/// *SVG__line*() will draw a line to *svg* from (*x1*, *y1*) to (*x2*, *y2*) +/// using *stroke*. + +void SVG__line(SVG svg, + Double x1, Double y1, Double x2, Double y2, String stroke) { + // Extract some values from *svg*: + File svg_stream = svg->stream; + Double x_offset = svg->x_offset; + Double y_offset = svg->y_offset; + Double x_scale = svg->x_scale; + Double y_scale = svg->y_scale; + String units = svg->units; + + // Output "" to *svg_stream*: + File__format(svg_stream, + "\n", stroke); +} + +/// @brief Open an SVG object: +/// @param base_name is the base name of the file name without the .svg. +/// @param width is the width of the SVG. +/// @param height is the height of the SVG. +/// @param x_scale is the amount is scale in X. +/// @param y_scale is the amount to scale in Y. +/// @param units is the units to use. +/// @returns a new *SVG* object. +/// +/// *SVG__open*() will create and return a new *SVG* for writing out +/// scable vector graphics. + +SVG SVG__open(String base_name, + Double width, Double height, Double x_scale, Double y_scale, String units) { + // Get *svg_stream* opened: + SVG svg = (SVG)0; + String file_name = String__format("%s.svg", base_name); + File svg_stream = File__open(file_name, "r"); + if (svg_stream == (File)0) { + File__format(stderr, "Unable to open %s.svg\n", base_name); + } else { + // Allocate and load up *svg*: + svg = Memory__new(SVG); + svg->height = height; + svg->stream = svg_stream; + svg->width = width; + svg->units = units; + svg->x_scale = x_scale; + svg->y_scale = y_scale; + svg->x_offset = 0.0; + svg->y_offset = 0.0; + + // Ouput the header for *svg*: + File__format(svg_stream, + "\n\n"); + File__format(svg_stream, + "\n\n"); + File__format(svg_stream, + "\n\n"); + } + + // Clean up and return: + String__free(file_name); + return svg; +} + +/// @brief Draw a *width* by *height* rectangle at (*x*, *y*). +/// @param svg is the *SVG* object to draw rectangle to. +/// @param x is the upper left X coordinate. +/// @param y is the uppper left Y coordinate. +/// @param width is the rectangle width. +/// @param height is the rectangle height. +/// @param stroke_color is the exterior line color. +/// @param fill_color is the interior fill color. +/// +/// *SVG__rectangle* will draw a *width* by *height* rectangle at (*x*, *y*) +/// with *stroke_color* and *fill_color* specifying the external line color +/// and internal fill color respectivily. + +void SVG__rectangle(SVG svg, Double x, Double y, + Double width, Double height, String stroke_color, String fill_color) { + // Grab some values from svg: + File svg_stream = svg->stream; + Double x_offset = svg->x_offset; + Double y_offset = svg->y_offset; + Double x_scale = svg->x_scale; + Double y_scale = svg->y_scale; + String units = svg->units; + + // Output "" to *svg_stream*: + Double x_final = (x + x_offset) * x_scale; + Double y_final = (y + y_offset) * y_scale; + File__format(svg_stream, + "\n", stroke_color, fill_color); +} + +/// @brief draw *message* at (*x*, *y*). +/// @param x is the X coordinate to draw text at. +/// @param y is the Y coordinate of draw text at. +/// @param font_size is the font size. +/// @param font_family is the font family to use. +/// +/// *SVG__text*() will draw *message* at (*x*, *y*) with *font_size* font +/// of type *font_family*. + +void SVG__text(SVG svg, + String message, Double x, Double y, String font_family, Unsigned font_size) { + // Grab some values from *svg*: + File svg_stream = svg->stream; + Double x_offset = svg->x_offset; + Double y_offset = svg->y_offset; + Double x_scale = svg->x_scale; + Double y_scale = svg->y_scale; + String units = svg->units; + + File__format(svg_stream, + "", font_family, font_size); + File__format(svg_stream, "%s%\n", message); +} diff --git a/SVG.h b/SVG.h new file mode 100644 index 0000000..40806a4 --- /dev/null +++ b/SVG.h @@ -0,0 +1,60 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#if !defined(SVG_H_INCLUDED) +#define SVG_H_INCLUDED 1 + +#include + +/// @brief *SVG* is a Scalable Vector Graphics object. +typedef struct SVG__Struct *SVG; + +#include "Double.h" +#include "File.h" +#include "Integer.h" +#include "Logical.h" +#include "Memory.h" +#include "Unsigned.h" + +/// @brief *SVG_Struct* is the data structure for representing Scalable +/// Vector Graphics. + +struct SVG__Struct { + /// @brief The output stream. + File stream; + + /// @brief Hight of SVG image. + Double height; + + /// @brief Width of SVG image. + Double width; + + /// @brief Units to use for SVG values. + String units; + + /// @brief Amount to offset X by. + Double x_offset; + + /// @brief Amount to scale X by. + Double x_scale; + + /// @brief Amount to offset Y by. + Double y_offset; + + /// @brief Amount to scale Y by. + Double y_scale; +}; + +// External declarations: + +extern void SVG__close(SVG svg); +extern void SVG__line(SVG svg, + Double x1, Double y1, Double x2, Double y2, String stroke); +extern SVG SVG__open(String base_name, + Double width, Double height, Double x_scale, Double y_scale, String units); +extern void SVG__rectangle(SVG svg, Double x, Double y, + Double width, Double height, String stroke_color, String fill_color); +extern void SVG__text(SVG svg, + String message, Double x, Double y, String font_family, Unsigned font_size); + + +#endif // !defined(SVG_H_INCLUDED) diff --git a/String.c b/String.c new file mode 100644 index 0000000..ff459e9 --- /dev/null +++ b/String.c @@ -0,0 +1,53 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#include +#include +#include + +#include "String.h" +#include "Memory.h" +#include "Unsigned.h" + +/// @brief Allocate and return for *size* characters. +/// @param size is the maximum string size excluding trailing null. +/// @returns allocated *String* object. +/// +/// *String__allocate*() will return a string that can conatain +/// *size* characters excluding trailing null. + +String String__allocate(Unsigned size) { + return (String)Memory__allocate(size + 1); +} + +/// @brief Return a formatted version of *format*. +/// @param format is the string to format. +/// @param ... are the addition arguments to be formatted. +/// @returns the formatted string. +/// +/// *String__format*() will a formatted version of *format* using the +/// additional variadic arguements. + +String String__format(String format, ...) { + // Set up *variadic_arguments to start after *format*: + va_list variadic_arguments; + va_start(variadic_arguments, format); + + // Compute *formatted_size*: + char buffer[2]; + Unsigned formatted_size = vsnprintf(buffer, 0, format, variadic_arguments); + // Allocated *formatted*: + String formatted = (String)Memory__allocate(formatted_size + 1); + + // Format *formatted*: + (void)vsnprintf(formatted, formatted_size, format, variadic_arguments); + + return formatted; +} + +/// @brief will free memory assciated with *string*. +/// @param string to free. + +void String__free(String string) { + Memory__free((Memory)string); +} + diff --git a/String.h b/String.h new file mode 100644 index 0000000..ddecbe9 --- /dev/null +++ b/String.h @@ -0,0 +1,18 @@ +/// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#if !defined(STRING_H_INCLUDED) +#define STRING_H_INCLUDED 1 + +/// @brief *String* is a null-terminated string. +typedef char *String; + +#include "Unsigned.h" + +// External declarations: + +extern String String__allocate(Unsigned size); +extern String String__format(String format, ...); +extern void String__free(String string); + +#endif // !defined(STRING_H_INCLUDED) + diff --git a/Tags.c b/Tags.c new file mode 100644 index 0000000..0401436 --- /dev/null +++ b/Tags.c @@ -0,0 +1,79 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +#include +#include +#include + +#include "SVG.h" + +Integer main(void) { + File__format(stdout, "Hello!\n"); + return 0; +} + +/// @brief Draw a rectangular section of bits: +/// @param cell_width is the cell width and height. +/// @param first_column is the first column of rectantle. +/// @param first_row is the first column of rectantle. +/// @param last_column is the last row to draw the bit at. +/// @param last_row is the last column to draw the bit at. +/// @param border is true if the tag has a border. +/// +/// *SVG__tag_bits*() will draw a row or column of black bits from +/// (*first_column*, *first_row*) to (*last_column*, *last_row*) +/// the 12 x 12 matrix that makes up a tag to *svg*. If *border* +/// *false*, the matrix is offset by the left by one. + +void SVG__tag_bits(SVG svg, Double cell_width, Unsigned first_column, + Unsigned first_row, Unsigned last_column, Unsigned last_row, Logical border) { + + // Deal with *border*: + Unsigned delta = 0; + if (!border) { + delta = 1; + } + + // Deal with SVG using left-hand (rather than right-hand) Cartesian + // coordinate system: + first_row = 11 - first_row; + last_row = 11 - last_row; + + // Make sure *first_column* < *last_column*: + if (first_column > last_column) { + Unsigned temporary_column = first_column; + first_column = last_column; + last_column = temporary_column; + } + + // Make sure *first_row* < *last_row*: + if (first_row > last_row) { + Unsigned temporary_row = first_row; + first_row = last_row; + last_row = temporary_row; + } + + // Output the appropriate rectangle to *svg*: + String color = "black"; + SVG__rectangle(svg, + (Double)(first_column - delta) * cell_width, + (Double)(first_row - delta) * cell_width, + (Double)(last_column - first_column + 1) * cell_width, + (Double)(last_row - first_row + 1) * cell_width, + color, color); +} + +/// @brief Draw a bit at *row* and *column*. +/// @param cell_width is the cell width and height. +/// @param row is the row to draw the bit at. +/// @param column is the column to draw the bit at. +/// @param border is true if the tag has a border. +/// +/// *SVG__tag_bit* draw a black bit at *row* and *column* in the 12 x 12 +/// matrix that makes up a tag and output it to *svg*. If *border* is *false* +/// the matrix is offset to the left by one. + +void SVG__tag_bit(SVG svg, + Double cell_width, Unsigned row, Unsigned column, Logical border) { + SVG__tag_bits(svg, cell_width, row, column, row, column, border); +} + diff --git a/Unsigned.c b/Unsigned.c new file mode 100644 index 0000000..95c4812 --- /dev/null +++ b/Unsigned.c @@ -0,0 +1,5 @@ +// Copyright (c) by Wayne C. Gramlich. All rights reserved. + +#include "Unsigned.h" + +// Any *Unsigned* support code goes here. diff --git a/Unsigned.h b/Unsigned.h new file mode 100644 index 0000000..f3fd58e --- /dev/null +++ b/Unsigned.h @@ -0,0 +1,5 @@ +// Copyright (c) 2013 by Wayne C. Gramlich. All rights reserved. + +/// @brief *Unsigned* is a 32-bit unsigned integer. +typedef unsigned int Unsigned; +