pensort
Description
pensort.c is a utility that processes a plotlib metafile, which contains a sequence of plotting commands. Its primary function is to reorder these commands such that all drawing operations for a specific “pen” (color/style) are grouped together. This is a common optimization for physical plotters or some rendering pipelines, as it reduces the number of pen changes, thus potentially speeding up plotting.
The module separates the original metafile into temporary files, one for each pen used, and then appends these temporary files back into a single output metafile in a sorted order. It also attempts to reset the plotting state (like text rotation and size) when a pen is selected, ensuring consistent rendering.
Functions
file_append(FILE *a, FILE *b): Appends the contents of filebto filea. ReadsRUNSIZE(16KB) chunks fromband writes them toa.reset_state(boolean text): Resets the plotting state for the current pen. WritesMOV,TRT, orTSZcommands to thesep_fileas needed.plot_start(float dx, float dy): Initializes the pensorting process. Writes aSTR(start) command to the main output file (plot_outfile).plot_end(): Finalizes the pensorting process. Iterates through all possible pens, appends their temporary files to the mainplot_outfile, writes anENDcommand, and closesplot_outfile.plot_pen(int pen): Selects a plotting pen. If the pen changes, it redirects output to a temporary file associated with the selected pen.plot_rotate(): (Placeholder function) Writes aROTcommand toplot_outfile.plot_move(float x, float y): Records a pen movement. Updatespen_x,pen_yto store the new position.plot_line(float x, float y): Draws a line. Callsreset_state(false)to ensure correct pen position and writes anLNE(line) command to the currentsep_file.plot_text(char *text): Draws text. Callsreset_state(true)to ensure correct pen position and text state, then writes aTXT(text) command to the currentsep_file.plot_textrot(float angle): Sets text rotation. Updatesnew_angleand setsangle_flagfor all pens.plot_textsize(float x, float y): Sets text size. Updatesnew_x,new_yand setssize_flagfor all pens.plot_clip(float x0, float y0, float x1, float y1): Sets clipping window. Updatesclip_x0,clip_y0,clip_x1,clip_y1and setsclip_flagfor all pens.
How It Works
pensort acts as a specialized plotlib device driver that intercepts plotting commands and reorders them before generating the final metafile. Instead of writing commands directly to the final output, it redirects them to temporary files, one for each pen. When the plot is finalized (plot_end()), it concatenates these temporary files back into a single output file, grouped by pen. This strategy minimizes physical pen changes on plotters, which can be a time-consuming operation. The module also manages internal state variables (like current pen position, text rotation, and size) and ensures these are correctly reset when a new pen is selected in the sorted output.
Output Files
The module outputs a plotlib metafile (plot_outfile) with plotting commands sorted by pen.
Dependencies
plotdriver.h: Defines the interface forplotlibdevice drivers.plotlib.h: Defines generalplotlibconstants and global variables.hpgl.h: (Included, but HPGL-specific functionality is not directly used by this pensorting logic; it processesplotlib’s intermediate metafile format).- Standard C library functions for file I/O and string manipulation.
Notes
The actual sorting happens by redirecting output for each pen to a temporary file. When plot_end() is called, these temporary files are concatenated into the final output in a specific order (from MAXPENS-1 down to 0, with first_pen appended last if it’s not 0). The state (pen_x, pen_y, new_angle, new_x, new_y) is maintained globally, and flags (pos_change, angle_flag, size_flag) are used to ensure that these states are applied to each pen’s temporary file when that pen is selected.