All pastes #943480 Raw Edit

Anonymous

public text v1 · immutable
·published 2008-03-15 09:13 UTC
rendered paste body
//
// Copyright 8-16-2007 Jonathan Westbrock <dulljon@yahoo.com>
// img-gen
//
// Permission is granted to modify and distribute this software and accompanying documentation, 
// provided that this complete notice appear in any and all revisions, as well as accompanying
// documentation.
// 
// No warranty shall be offered, or liability accepted by author, be these implied, expressed, or imagined.
// Any damages, direct or indirect, resulting from the use of this software are hereby disclaimed. 
// The author makes no claim of any kind as to the sustainablity, stability, or quality of this product.
//
// Distributed under the terms of the GNU General Public license(GPL).
//
#include <cairo.h>
#include <stdio.h>
#include <stdlib.h>
#include <argp.h>
#include <string.h>
const char *argp_program_version = "Alpha";
const char *argp_program_bug_address = "<dulljon@yahoo.com>";
const char chrValidList[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-.<\'\'}=|/@+)]{~>[!#$%&(,?:;'\" ";
	struct arguments
	{
  		char *args[5];
  		int verbose, shadow, raised, bold, italic, oblique;
  		char *program, *font;
		double width, height, f1R, f1G, f1B, f1A, fS, indent, opacity, stampX, stampY;
	};
	static struct argp_option options[] =
	{
  		{"verbose",    'v', 0, 0, "Produce verbose output DEFAULT:Off"},
		{"shadow",     's', 0, 0, "Font drop shadow DEFAULT:Off"},
		{"bold",       'b', 0, 0, "Bold font DEFAULT:Off"},
		{"italic",     'i', 0, 0, "Italic font DEFAULT:Off"},
		{"oblique",    'o', 0, 0, "Oblique font DEFAULT:Off (overrides italic)"},
		{"raised",     'r', 0, 0, "Raised font effect DEFAULT:Off"},
		{"width",      'w', "WIDTH", 0, "Set output WIDTH DEFAULT:1280"},
		{"height",     'h', "HEIGHT", 0, "Set output HEIGHT DEFAULT:1024"},
		{"program",    'p', "PROGRAM", 0,"Read output from PROGRAM DEFAULT:Fortune"},
		{"Red",        'R', "Font RED", 0,"Level of RED in font output DEFAULT:0.7"},
		{"Green",      'G', "Font GREEN", 0,"Level of GREEN in font output DEFAULT:0.7"},
		{"Blue",       'B', "Font BLUE", 0,"Level of BLUE in font output DEFAULT:0.7"},
		{"Alpha",      'A', "Font ALPHA", 0,"Level of ALPHA in font output DEFAULT:0.9"},
		{"Size",       'S', "Font SIZE", 0,"SIZE of font output DEFAULT:25.0"},
		{"indent",     'I', "INDENT", 0,"INDENT of output text DEFAULT:10.0"},
		{"opacity",    'O', "OPACITY", 0,"Output image OPACITY level DEFAULT:1.0"},
		{"placex",     'x', "PLACEX", 0,"Beginning X PLACEMENT of input image on the background"},
		{"placey",     'y', "PLACEY", 0,"Beginning Y PLACEMENT of input image on the background"},
		{"font",       'f', "FONT", 0,"FONT of text output DEFAULT: Bitstream Vera Sans Mono"},
  		{0}
	};
	static error_t parse_opt (int key, char *arg, struct argp_state *state)
	{
  		struct arguments *arguments = state->input;

  		switch (key)
    		{ 
			case 'v': arguments->verbose = 1;
      			break;
			case 's': arguments->shadow = 1;
      			break;
			case 'b': arguments->bold = 1;
      			break;
			case 'i': arguments->italic = 1;
      			break;
			case 'o': arguments->oblique = 1;
      			break;
			case 'r': arguments->raised = 1;
      			break;
			case 'w': arguments->width = atof(arg);
      			break;
			case 'h': arguments->height = atof(arg);
      			break;
			case 'R': arguments->f1R = atof(arg);
      			break;
			case 'G': arguments->f1G = atof(arg);
      			break;
			case 'B': arguments->f1B = atof(arg);
      			break;
			case 'A': arguments->f1A = atof(arg);
      			break;
			case 'S': arguments->fS = atof(arg);
      			break;
			case 'p': arguments->program = arg;
      			break;
			case 'I': arguments->indent = atof(arg);
      			break;
			case 'O': arguments->opacity = atof(arg);
      			break;
			case 'x': arguments->stampX = atof(arg);
      			break;
			case 'y': arguments->stampY = atof(arg);
      			break;
			case 'f': arguments->font = arg;
      			break;
    			case ARGP_KEY_ARG: if (state->arg_num >= 5)
				{
	  				argp_usage(state);
				}
      			arguments->args[state->arg_num] = arg;
      			break;
    			case ARGP_KEY_END: if (state->arg_num < 5)
				{
	  				argp_usage (state);
				}
      			break;
    			default: return ARGP_ERR_UNKNOWN;
    		}
  		return 0;
	}
	static char args_doc[] = "Input.png Output.png Red Green Blue";
	static char doc[] = "img-gen -- A simple utility to generate images for use as backgrounds, etc.";
	static struct argp argp = {options, parse_opt, args_doc, doc};
	int clean_string(char *udata, int verb)
	{
		char *control;
		if (verb > 0)
	    		printf("\nInput: %s", udata);
	    	for (control = udata; *(control += strspn(control, chrValidList)); /* */)
	        	*control = ' ';
		if (verb > 0)
	    		printf("\nOutput: %s", udata);
		return 1;
	}
	int draw_raised (cairo_t *surfus, char *strung, double pigX, double pigY, double fR, double fG, double fB, double fA, double FS, int verb)
	{
		cairo_set_font_size (surfus, FS);
        	cairo_set_source_rgba (surfus, 0.5, 0.5, 0.5, 0.2);
        	cairo_move_to (surfus, pigX+2, pigY+2);
		cairo_show_text (surfus, strung);
        	if (verb > 0)
	    		printf("<Drew text>\n");
		cairo_set_source_rgba (surfus, fR /2, fG /2, fB /2 , fA /2);
        	cairo_move_to (surfus, pigX + 1, pigY + 1);
        	cairo_show_text (surfus, strung);
		if (verb > 0)
	    		printf("<Drew text>\n");
		cairo_set_source_rgba (surfus, fR, fG, fB, fA);
		cairo_move_to (surfus, pigX, pigY);
		cairo_show_text (surfus, strung);
		if (verb > 0)
	    		printf("<Drew text>\n<Raise complete>\n");
		return 1;
	}
	int draw_flat (cairo_t *surfus, char *strung, double pigX, double pigY, double fR, double fG, double fB, double fA, double FS, int verb)
	{	
		cairo_set_font_size (surfus, FS);
        	cairo_set_source_rgba (surfus, fR, fG, fB, fA);
        	cairo_move_to (surfus, pigX, pigY);
        	cairo_show_text (surfus, strung);
		if (verb > 0)
			printf("<Drew text>\n<Default flat draw complete\n>");
		return 1;
	}
	int draw_shadow (cairo_t *surfus, char *strung, double pigX, double pigY, double fR, double fG, double fB, double fA, double FS, int verb)
	{	
		cairo_set_font_size (surfus, FS);		
        	cairo_set_source_rgba (surfus, 0.0, 0.0, 0.0, 0.8);
        	cairo_move_to (surfus, pigX +3, pigY +3);
        	cairo_show_text (surfus, strung);
		if (verb > 0)
	    		printf("<Drew text>\n");
		cairo_set_source_rgba (surfus, fR, fG, fB, fA);
        	cairo_move_to (surfus, pigX, pigY);
        	cairo_show_text (surfus, strung);
		if (verb > 0)
	    		printf("<Drew text>\n<Shadow complete>\n");
		return 1;
	}
	int draw_it(cairo_t* surf, char *strung, double pigX, double pigY, double fR, double fG, double fB, double fA, double FS, int verb, int shadow, int raise)
	{
		int intByteHolder = clean_string(strung, verb);
		if(shadow)
		{
			if (verb > 0)
	    		printf("\n<Shadow initiated>\n");
			intByteHolder = draw_shadow(surf, strung, pigX, pigY, fR, fG, fB, fA, FS, verb);			
		}
		
		if(raise)
		{
			if (verb > 0)
	    		printf("\n<Raise initiated>\n");
			intByteHolder = draw_raised(surf, strung, pigX, pigY, fR, fG, fB, fA, FS, verb);
		}
		if(!raise && !shadow)
		{
			if (verb > 0)
	    		printf("\n<Default flat draw initiated>\n");
			intByteHolder = draw_flat(surf, strung, pigX, pigY, fR, fG, fB, fA, FS, verb);
		}
		return intByteHolder;
	}
	int main (int argc, char *argv[])
	{
		struct arguments arguments;
		char verbage[] ="Verbose output enabled.\n";
		arguments.program = "fortune";
		arguments.width   = 1280;
		arguments.height  = 1024;
		arguments.f1R= 0.7;	
		arguments.f1G= 0.7;
		arguments.f1B= 0.7;
		arguments.f1A= 0.9;
		arguments.fS= 25.0;
		arguments.indent= 10.0;
 	 	arguments.verbose = 0;
		arguments.shadow = 0;
		arguments.bold = 0;
		arguments.italic = 0;
		arguments.oblique = 0;
		arguments.raised = 0;
		arguments.opacity = 1;
		arguments.stampX = 0.00000009;
		arguments.stampY = 0.00000009;
		arguments.font = "Bitstream Vera Sans Mono";
  		argp_parse (&argp, argc, argv, 0, 0, &arguments);
  		if (arguments.verbose)
    			printf (verbage);
		FILE *pipInput;
		pipInput = popen (arguments.program, "r");
		if (pipInput == NULL)
    		{
      			return EXIT_FAILURE;
    		}
        	cairo_surface_t *croSurface, *croPNGSurface;
        	cairo_t *srfOutput, *srfPNG;
		int intInputBytes;
  		int intNumBytes = 100;
  		char *strInput;
		cairo_font_slant_t croFontSlant;
		cairo_font_weight_t croFontWeight;
		if(arguments.italic > 0)
		{
			croFontSlant = CAIRO_FONT_SLANT_ITALIC;
		}
		else if(arguments.oblique > 0)
		{
			croFontSlant = CAIRO_FONT_SLANT_OBLIQUE;
		}
		else
		{
			croFontSlant = CAIRO_FONT_SLANT_NORMAL;
		}
		if(arguments.bold > 0)
		{
			croFontWeight = CAIRO_FONT_WEIGHT_BOLD;
		}
		else
		{
			croFontWeight = CAIRO_FONT_WEIGHT_NORMAL;
		}
		strInput = (char *) malloc (intNumBytes + 1);
        	croPNGSurface = cairo_image_surface_create_from_png (arguments.args[0]);
		croSurface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, arguments.width, arguments.height);		
		srfOutput = cairo_create (croSurface);
		if(arguments.opacity > 0.0)
		{
			double bgR = atof(arguments.args[2]), bgG = atof(arguments.args[3]), bgB = atof(arguments.args[4]), bgA = arguments.opacity;
			cairo_pattern_t *patBg;
			patBg = cairo_pattern_create_linear (0.0, 0.0,  0.0, arguments.height);
			cairo_pattern_add_color_stop_rgba (patBg, 1.0, bgR, bgG, bgB, bgA);
			cairo_rectangle (srfOutput, 0, 0, arguments.width, arguments.height);
			cairo_set_source (srfOutput, patBg);
			cairo_fill (srfOutput);
			cairo_pattern_destroy (patBg);
			if(arguments.verbose > 0)
			printf("Drew the background\n");
		}
		else
			if(arguments.verbose > 0)
			printf("Skipping the background\n");
		if(arguments.stampX > 0.00000009 || arguments.stampY > 0.00000009)
		{
			cairo_set_source_surface(srfOutput, croPNGSurface, arguments.stampX, arguments.stampY);
		}
		else
		{
			cairo_set_source_surface(srfOutput, croPNGSurface, arguments.width - cairo_image_surface_get_width (croPNGSurface), arguments.height - cairo_image_surface_get_height (croPNGSurface));
		}
		cairo_paint (srfOutput);
		cairo_surface_destroy(croPNGSurface);		
		intInputBytes = getline(&strInput, &intNumBytes, pipInput);
	    	cairo_select_font_face (srfOutput, arguments.font, croFontSlant, croFontWeight);
        	intInputBytes = draw_it(srfOutput, strInput, arguments.indent, arguments.fS, arguments.f1R, arguments.f1G, arguments.f1B, arguments.f1A, arguments.fS, arguments.verbose, arguments.shadow, arguments.raised);
		double dblPosY = arguments.fS*2;
		while(getline (&strInput, &intNumBytes, pipInput) != -1)
		{	
			intInputBytes = draw_it(srfOutput, strInput, arguments.indent, dblPosY, arguments.f1R, arguments.f1G, arguments.f1B, arguments.f1A, arguments.fS, arguments.verbose, arguments.shadow, arguments.raised);
			strInput = (char *) malloc (intNumBytes);
			dblPosY += arguments.fS;
		}
        	cairo_destroy (srfOutput);
        	cairo_surface_write_to_png (croSurface, arguments.args[1]);
		if(arguments.verbose > 0)
			printf("Wrote the Output png\n");
        	cairo_surface_destroy (croSurface);
		pclose(pipInput);
		
        	return 0;
	}