//********** pngwriter.h ********************************************** // Author: Paul Blackburn // // Email: individual61@users.sourceforge.net // // Version: 0.5.4 (19 / II / 2009) // // Description: Library that allows plotting a 48 bit // PNG image pixel by pixel, which can // then be opened with a graphics program. // // License: GNU General Public License // Copyright 2002, 2003, 2004, 2005, 2006, 2007, // 2008, 2009 Paul Blackburn // // Website: Main: http://pngwriter.sourceforge.net/ // Sourceforge.net: http://sourceforge.net/projects/pngwriter/ // Freshmeat.net: http://freshmeat.net/projects/pngwriter/ // // Documentation: This header file is commented, but for a // quick reference document, and support, // take a look at the website. // //************************************************************************* /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * */ #ifndef PNGWRITER_H #define PNGWRITER_H 1 #define PNGWRITER_VERSION 0.54 #define NO_FREETYPE #include // REMEMBER TO ADD -DNO_FREETYPE TO YOUR COMPILATION FLAGS IF PNGwriter WAS // COMPILED WITHOUT FREETYPE SUPPORT!!! // // RECUERDA AGREGAR -DNO_FREETYPE A TUS OPCIONES DE COMPILACION SI PNGwriter // FUE COMPILADO SIN SOPORTE PARA FREETYPE!!! // #ifndef NO_FREETYPE #include #include FT_FREETYPE_H #endif #ifdef OLD_CPP // For compatibility with older compilers. #include #include #include #include using namespace std; #endif // from ifdef OLD_CPP #ifndef OLD_CPP // Default situation. #include #include #include #include #endif // from ifndef OLD_CPP //png.h must be included before FreeType headers. #include #include #include #define PNG_BYTES_TO_CHECK (4) #define PNGWRITER_DEFAULT_COMPRESSION (0) class pngwriter { private: char* filename_; char* textauthor_; char* textdescription_; char* texttitle_; char* textsoftware_; bool should_free; int height_; int width_; int backgroundcolour_; int bit_depth_; int rowbytes_; int colortype_; int compressionlevel_; bool transformation_; // Required by Mikkel's patch unsigned char * * graph_; double filegamma_; double screengamma_; void circle_aux(int xcentre, int ycentre, int x, int y, int red, int green, int blue); void circle_aux_blend(int xcentre, int ycentre, int x, int y, double opacity, int red, int green, int blue); int check_if_png(char* file_name, FILE** fp); int read_png_info(FILE* fp, png_structp* png_ptr, png_infop* info_ptr); int read_png_image(FILE* fp, png_structp png_ptr, png_infop info_ptr, png_bytepp* image, png_uint_32* width, png_uint_32* height); void flood_fill_internal(int xstart, int ystart, double start_red, double start_green, double start_blue, double fill_red, double fill_green, double fill_blue); void flood_fill_internal_blend(int xstart, int ystart, double opacity, double start_red, double start_green, double start_blue, double fill_red, double fill_green, double fill_blue); #ifndef NO_FREETYPE void my_draw_bitmap(FT_Bitmap* bitmap, int x, int y, double red, double green, double blue); void my_draw_bitmap_blend(FT_Bitmap* bitmap, int x, int y,double opacity, double red, double green, double blue); #endif /* The algorithms HSVtoRGB and RGBtoHSV were found at http://www.cs.rit.edu/~ncs/ * which is a page that belongs to Nan C. Schaller, though * these algorithms appear to be the work of Eugene Vishnevsky. * */ void HSVtoRGB(double* r, double* g, double* b, double h, double s, double v); void RGBtoHSV(float r, float g, float b, float* h, float* s, float* v); /* drwatop(), drawbottom() and filledtriangle() were contributed by Gurkan Sengun * ( , http://www.linuks.mine.nu/ ) * */ void drawtop(long x1,long y1,long x2,long y2,long x3, int red, int green, int blue); void drawbottom(long x1,long y1,long x2,long x3,long y3, int red, int green, int blue); void drawbottom_blend(long x1,long y1,long x2,long x3,long y3, double opacity, int red, int green, int blue); void drawtop_blend(long x1,long y1,long x2,long y2,long x3, double opacity, int red, int green, int blue); public: /* General Notes * It is important to remember that all functions that accept an argument of type "const char *" will also * accept "char *", this is done so you can have a changing filename (to make many PNG images in series * with a different name, for example), and to allow you to use string type objects which can be easily * turned into const char * (if theString is an object of type string, then it can be used as a const char * * by saying theString.c_str()). * It is also important to remember that whenever a function has a colour coeffiecient as its argument, * that argument can be either an int from 0 to 65535 or a double from 0.0 to 1.0. * It is important to make sure that you are calling the function with the type that you want. * Remember that 1 is an int, while 1.0 is a double, and will thus determine what version of the function * will be used. Similarly, do not make the mistake of calling for example plot(x, y, 0.0, 0.0, 65535), * because * there is no plot(int, int, double, double, int). * Also, please note that plot() and read() (and the functions that use them internally) * are protected against entering, for example, a colour coefficient that is over 65535 * or over 1.0. Similarly, they are protected against negative coefficients. read() will return 0 * when called outside the image range. This is actually useful as zero-padding should you need it. * */ /* Compilation * A typical compilation would look like this: * * g++ my_program.cc -o my_program freetype-config --cflags \ * -I/usr/local/include -L/usr/local/lib -lpng -lpngwriter -lz -lfreetype * * If you did not compile PNGwriter with FreeType support, then remove the * FreeType-related flags and add -DNO_FREETYPE above. * */ /* Constructor * The constructor requires the width and the height of the image, the background colour for the * image and the filename of the file (a pointer or simple "myfile.png"). The background colour * can only be initialized to a shade of grey (once the object has been created you can do whatever * you want, though), because generally one wants either a white (65535 or 1.0) or a black (0 or 0.0) * background to start with. * The default constructor creates a PNGwriter instance that is 250x250, white background, * and filename "out.png". * Tip: The filename can be given as easily as: * pngwriter mypng(300, 300, 0.0, "myfile.png"); * Tip: If you are going to create a PNGwriter instance for reading in a file that already exists, * then width and height can be 1 pixel, and the size will be automatically adjusted once you use * readfromfile(). * */ pngwriter(); pngwriter(const pngwriter& rhs); pngwriter(int width, int height, int backgroundcolour, char* filename); pngwriter(int width, int height, double backgroundcolour, char* filename); pngwriter(int width, int height, int backgroundcolour, const char* filename); pngwriter(int width, int height, unsigned char * data, const char* filename); pngwriter(int width, int height, double backgroundcolour, const char* filename); /* Destructor * */ ~pngwriter(); /* Assignment Operator * */ pngwriter& operator = (const pngwriter& rhs); /* Plot * With this function a pixel at coordinates (x, y) can be set to the desired colour. * The pixels are numbered starting from (1, 1) and go to (width, height). * As with most functions in PNGwriter, it has been overloaded to accept either int arguments * for the colour coefficients, or those of type double. If they are of type int, * they go from 0 to 65535. If they are of type double, they go from 0.0 to 1.0. * Tip: To plot using red, then specify plot(x, y, 1.0, 0.0, 0.0). To make pink, * just add a constant value to all three coefficients, like this: * plot(x, y, 1.0, 0.4, 0.4). * Tip: If nothing is being plotted to your PNG file, make sure that you remember * to close() the instance before your program is finished, and that the x and y position * is actually within the bounds of your image. If either is not, then PNGwriter will * not complain-- it is up to you to check for this! * Tip: If you try to plot with a colour coefficient out of range, a maximum or minimum * coefficient will be assumed, according to the given coefficient. For example, attempting * to plot plot(x, y, 1.0,-0.2,3.7) will set the green coefficient to 0 and the red coefficient * to 1.0. * */ void plot(int x, int y, int red, int green, int blue); void plot(int x, int y, double red, double green, double blue); /* Plot HSV * With this function a pixel at coordinates (x, y) can be set to the desired colour, * but with the colour coefficients given in the Hue, Saturation, Value colourspace. * This has the advantage that one can determine the colour that will be plotted with * only one parameter, the Hue. The colour coefficients must go from 0 to 65535 and * be of type int, or be of type double and go from 0.0 to 1.0. * */ void plotHSV(int x, int y, double hue, double saturation, double value); void plotHSV(int x, int y, int hue, int saturation, int value); /* Read * With this function we find out what colour the pixel (x, y) is. If "colour" is 1, * it will return the red coefficient, if it is set to 2, the green one, and if * it set to 3, the blue colour coefficient will be returned, * and this returned value will be of type int and be between 0 and 65535. * Note that if you call read() on a pixel outside the image range, the value returned * will be 0. * */ int read(int x, int y, int colour); /* Read, Average * Same as the above, only that the average of the three colour coefficients is returned. */ int read(int x, int y); /* dRead * With this function we find out what colour the pixel (x, y) is. If "colour" is 1, * it will return the red coefficient, if it is set to 2, the green one, and if * it set to 3, the blue colour coefficient will be returned, * and this returned value will be of type double and be between 0.0 and 1.0. * Note that if you call dread() outside the image range, the value returned will be 0.0 * */ double dread(int x, int y, int colour); /* dRead, Average * Same as the above, only that the average of the three colour coefficients is returned. */ double dread(int x, int y); /* Read HSV * With this function we find out what colour the pixel (x, y) is, but in the Hue, * Saturation, Value colourspace. If "colour" is 1, * it will return the Hue coefficient, if it is set to 2, the Saturation one, and if * it set to 3, the Value colour coefficient will be returned, and this returned * value will be of type int and be between 0 and 65535. Important: If you attempt * to read the Hue of a pixel that is a shade of grey, the value returned will be * nonsensical or even NaN. This is just the way the RGB -> HSV algorithm works: * the Hue of grey is not defined. You might want to check whether the pixel * you are reading is grey before attempting a readHSV(). * Tip: This is especially useful for categorizing sections of the image according * to their colour. * */ int readHSV(int x, int y, int colour); /* dRead HSV * With this function we find out what colour the pixel (x, y) is, but in the Hue, * Saturation, Value colourspace. If "colour" is 1, * it will return the Hue coefficient, if it is set to 2, the Saturation one, and if * it set to 3, the Value colour coefficient will be returned, * and this returned value will be of type double and be between 0.0 and 1.0. * */ double dreadHSV(int x, int y, int colour); /* Clear * The whole image is set to black. * */ void clear(void); /* Close * Close the instance of the class, and write the image to disk. * Tip: If you do not call this function before your program ends, no image * will be written to disk. * */ void close(void); /* Rename * To rename the file once an instance of pngwriter has been created. * Useful for assigning names to files based upon their content. * Tip: This is as easy as calling pngwriter_rename("newname.png") * If the argument is a long unsigned int, for example 77, the filename will be changed to * 0000000077.png * Tip: Use this to create sequences of images for movie generation. * */ void pngwriter_rename(char* newname); void pngwriter_rename(const char* newname); void pngwriter_rename(long unsigned int index); /* Figures * These functions draw basic shapes. Available in both int and double versions. * The line functions use the fast Bresenham algorithm. Despite the name, * the square functions draw rectangles. The circle functions use a fast * integer math algorithm. The filled circle functions make use of sqrt(). * */ void line(int xfrom, int yfrom, int xto, int yto, int red, int green,int blue); void line(int xfrom, int yfrom, int xto, int yto, double red, double green,double blue); void triangle(int x1, int y1, int x2, int y2, int x3, int y3, int red, int green, int blue); void triangle(int x1, int y1, int x2, int y2, int x3, int y3, double red, double green, double blue); void square(int xfrom, int yfrom, int xto, int yto, int red, int green,int blue); void square(int xfrom, int yfrom, int xto, int yto, double red, double green,double blue); void filledsquare(int xfrom, int yfrom, int xto, int yto, int red, int green,int blue); void filledsquare(int xfrom, int yfrom, int xto, int yto, double red, double green,double blue); void circle(int xcentre, int ycentre, int radius, int red, int green, int blue); void circle(int xcentre, int ycentre, int radius, double red, double green, double blue); void filledcircle(int xcentre, int ycentre, int radius, int red, int green, int blue); void filledcircle(int xcentre, int ycentre, int radius, double red, double green, double blue); /* Read From File * Open the existing PNG image, and copy it into this instance of the class. It is important to mention * that PNG variants are supported. Very generally speaking, most PNG files can now be read (as of version 0.5.4), * but if they have an alpha channel it will be completely stripped. If the PNG file uses GIF-style transparency * (where one colour is chosen to be transparent), PNGwriter will not read the image properly, but will not * complain. Also, if any ancillary chunks are included in the PNG file (chroma, filter, etc.), it will render * with a slightly different tonality. For the vast majority of PNGs, this should not be an issue. Note: * If you read an 8-bit PNG, the internal representation of that instance of PNGwriter will be 8-bit (PNG * files of less than 8 bits will be upscaled to 8 bits). To convert it to 16-bit, just loop over all pixels, * reading them into a new instance of PNGwriter. New instances of PNGwriter are 16-bit by default. * */ void readfromfile(char* name); void readfromfile(const char* name); /* Get Height * When you open a PNG with readfromfile() you can find out its height with this function. * */ int getheight(void); /* Get Width * When you open a PNG with readfromfile() you can find out its width with this function. * */ int getwidth(void); /* Set Compression Level * Set the compression level that will be used for the image. -1 is to use the default, * 0 is none, 9 is best compression. * Remember that this will affect how long it will take to close() the image. A value of 2 or 3 * is good enough for regular use, but for storage or transmission you might want to take the time * to set it at 9. * */ void setcompressionlevel(int level); /* Get Bit Depth * When you open a PNG with readfromfile() you can find out its bit depth with this function. * Mostly for troubleshooting uses. * */ int getbitdepth(void); /* Get Colour Type * When you open a PNG with readfromfile() you can find out its colour type (libpng categorizes * different styles of image data with this number). * Mostly for troubleshooting uses. * */ int getcolortype(void); /* Set Gamma Coeff * Set the image's gamma (file gamma) coefficient. This is experimental, but use it if your image's colours seem too bright * or too dark. The default value of 0.5 should be fine. The standard disclaimer about Mac and PC gamma * settings applies. * */ void setgamma(double gamma); /* Get Gamma Coeff * Get the image's gamma coefficient. This is experimental. * */ double getgamma(void); /* Bezier Curve * (After Frenchman Pierre Bˇzier from Regie Renault) * A collection of formulae for describing curved lines * and surfaces, first used in 1972 to model automobile surfaces. * (from the The Free On-line Dictionary of Computing) * See http://www.moshplant.com/direct-or/bezier/ for one of many * available descriptions of bezier curves. * There are four points used to define the curve: the two endpoints * of the curve are called the anchor points, while the other points, * which define the actual curvature, are called handles or control points. * Moving the handles lets you modify the shape of the curve. * */ void bezier(int startPtX, int startPtY, int startControlX, int startControlY, int endPtX, int endPtY, int endControlX, int endControlY, double red, double green, double blue); void bezier(int startPtX, int startPtY, int startControlX, int startControlY, int endPtX, int endPtY, int endControlX, int endControlY, int red, int green, int blue); /* Set Text * Sets the text information in the PNG header. If it is not called, the default is used. */ void settext(char* title, char* author, char* description, char* software); void settext(const char* title, const char* author, const char* description, const char* software); /* Version Number * Returns the PNGwriter version number. */ static double version(void); /* Write PNG * Writes the PNG image to disk. You can still change the PNGwriter instance after this. * Tip: This is exactly the same as close(), but easier to remember. * Tip: To make a sequence of images using only one instance of PNGwriter, alter the image, change its name, * write_png(), then alter the image, change its name, write_png(), etc. */ void write_png(void); /* Plot Text * Uses the Freetype2 library to set text in the image. face_path is the file path to a * TrueType font file (.ttf) (FreeType2 can also handle other types). fontsize specifices the approximate * height of the rendered font in pixels. x_start and y_start specify the placement of the * lower, left corner of the text string. angle is the text angle in radians. text is the text to be rendered. * The colour coordinates can be doubles from 0.0 to 1.0 or ints from 0 to 65535. * Tip: PNGwriter installs a few fonts in /usr/local/share/pngwriter/fonts to get you started. * Tip: Remember to add -DNO_FREETYPE to your compilation flags if PNGwriter was compiled without FreeType support. * */ void plot_text(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, double red, double green, double blue); void plot_text(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, int red, int green, int blue); /* Plot UTF-8 Text * Same as the above, but the text to be plotted is encoded in UTF-8. Why would you want this? To be able to plot * all characters available in a large TrueType font, for example: for rendering Japenese, Chinese and other * languages not restricted to the standard 128 character ASCII space. * Tip: The quickest way to get a string into UTF-8 is to write it in an adequate text editor, and save it as a file * in UTF-8 encoding, which can then be read in in binary mode. * */ void plot_text_utf8(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, double red, double green, double blue); void plot_text_utf8(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, int red, int green, int blue); /* Bilinear Interpolation of Image * Given a floating point coordinate (x from 0.0 to width, y from 0.0 to height), * this function will return the interpolated colour intensity specified by * colour (where red = 1, green = 2, blue = 3). * bilinear_interpolate_read() returns an int from 0 to 65535, and * bilinear_interpolate_dread() returns a double from 0.0 to 1.0. * Tip: Especially useful for enlarging an image. * */ int bilinear_interpolation_read(double x, double y, int colour); double bilinear_interpolation_dread(double x, double y, int colour); /* Plot Blend * Plots the colour given by red, green blue, but blended with the existing pixel * value at that position. opacity is a double that goes from 0.0 to 1.0. * 0.0 will not change the pixel at all, and 1.0 will plot the given colour. * Anything in between will be a blend of both pixel levels. Please note: This is neither * alpha channel nor PNG transparency chunk support. This merely blends the plotted pixels. * */ void plot_blend(int x, int y, double opacity, int red, int green, int blue); void plot_blend(int x, int y, double opacity, double red, double green, double blue); /* Invert * Inverts the image in RGB colourspace. * */ void invert(void); /* Resize Image * Resizes the PNGwriter instance. Note: All image data is set to black (this is * a resizing, not a scaling, of the image). * */ void resize(int width, int height); /* Boundary Fill * All pixels adjacent to the start pixel will be filled with the fill colour, until the boundary colour is encountered. * For example, calling boundary_fill() with the boundary colour set to red, on a pixel somewhere inside a red circle, * will fill the entire circle with the desired fill colour. If, on the other hand, the circle is not the boundary colour, * the rest of the image will be filled. * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. * */ void boundary_fill(int xstart, int ystart, double boundary_red,double boundary_green,double boundary_blue,double fill_red, double fill_green, double fill_blue) ; void boundary_fill(int xstart, int ystart, int boundary_red,int boundary_green,int boundary_blue,int fill_red, int fill_green, int fill_blue) ; /* Flood Fill * All pixels adjacent to the start pixel will be filled with the fill colour, if they are the same colour as the * start pixel. For example, calling flood_fill() somewhere in the interior of a solid blue rectangle will colour * the entire rectangle the fill colour. The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. * */ void flood_fill(int xstart, int ystart, double fill_red, double fill_green, double fill_blue) ; void flood_fill(int xstart, int ystart, int fill_red, int fill_green, int fill_blue) ; /* Polygon * This function takes an array of integer values containing the coordinates of the vertexes of a polygon. * Note that if you want a closed polygon, you must repeat the first point's coordinates for the last point. * It also requires the number of points contained in the array. For example, if you wish to plot a triangle, * the array will contain 6 elements, and the number of points is 3. Be very careful about this; if you specify the wrong number * of points, your program will either segfault or produce points at nonsensical coordinates. * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. * */ void polygon(int* points, int number_of_points, double red, double green, double blue); void polygon(int* points, int number_of_points, int red, int green, int blue); /* Plot CMYK * Plot a point in the Cyan, Magenta, Yellow, Black colourspace. Please note that this colourspace is * lossy, i.e. it cannot reproduce all colours on screen that RGB can. The difference, however, is * barely noticeable. The algorithm used is a standard one. The colour components are either * doubles from 0.0 to 1.0 or ints from 0 to 65535. * */ void plotCMYK(int x, int y, double cyan, double magenta, double yellow, double black); void plotCMYK(int x, int y, int cyan, int magenta, int yellow, int black); /* Read CMYK, Double version * Get a pixel in the Cyan, Magenta, Yellow, Black colourspace. if 'colour' is 1, the Cyan component will be returned * as a double from 0.0 to 1.0. If 'colour is 2, the Magenta colour component will be returned, and so on, up to 4. * */ double dreadCMYK(int x, int y, int colour); /* Read CMYK * Same as the above, but the colour components returned are an int from 0 to 65535. * */ int readCMYK(int x, int y, int colour); /* Scale Proportional * Scale the image using bilinear interpolation. If k is greater than 1.0, the image will be enlarged. * If k is less than 1.0, the image will be shrunk. Negative or null values of k are not allowed. * The image will be resized and the previous content will be replaced by the scaled image. * Tip: use getheight() and getwidth() to find out the new width and height of the scaled image. * Note: After scaling, all images will have a bit depth of 16, even if the original image had * a bit depth of 8. * */ void scale_k(double k); /* Scale Non-Proportional * Scale the image using bilinear interpolation, with different horizontal and vertical scale factors. * */ void scale_kxky(double kx, double ky); /* Scale To Target Width and Height * Scale the image in such a way as to meet the target width and height. * Tip: if you want to keep the image proportional, scale_k() might be more appropriate. * */ void scale_wh(int finalwidth, int finalheight); /* Blended Functions * All these functions are identical to their non-blended types. They take an extra argument, opacity, which is * a double from 0.0 to 1.0 and represents how much of the original pixel value is retained when plotting the * new pixel. In other words, if opacity is 0.7, then after plotting, the new pixel will be 30% of the * original colour the pixel was, and 70% of the new colour, whatever that may be. As usual, each function * is available in int or double versions. Please note: This is neither alpha channel nor PNG transparency chunk support. This merely blends the plotted pixels. * */ // Start Blended Functions void plotHSV_blend(int x, int y, double opacity, double hue, double saturation, double value); void plotHSV_blend(int x, int y, double opacity, int hue, int saturation, int value); void line_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int blue); void line_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double blue); void square_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int blue); void square_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double blue); void filledsquare_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int blue); void filledsquare_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double blue); void circle_blend(int xcentre, int ycentre, int radius, double opacity, int red, int green, int blue); void circle_blend(int xcentre, int ycentre, int radius, double opacity, double red, double green, double blue); void filledcircle_blend(int xcentre, int ycentre, int radius, double opacity, int red, int green, int blue); void filledcircle_blend(int xcentre, int ycentre, int radius, double opacity, double red, double green, double blue); void bezier_blend(int startPtX, int startPtY, int startControlX, int startControlY, int endPtX, int endPtY, int endControlX, int endControlY, double opacity, double red, double green, double blue); void bezier_blend(int startPtX, int startPtY, int startControlX, int startControlY, int endPtX, int endPtY, int endControlX, int endControlY, double opacity, int red, int green, int blue); void plot_text_blend(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, double opacity, double red, double green, double blue); void plot_text_blend(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, double opacity, int red, int green, int blue); void plot_text_utf8_blend(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, double opacity, double red, double green, double blue); void plot_text_utf8_blend(char* face_path, int fontsize, int x_start, int y_start, double angle, char* text, double opacity, int red, int green, int blue); void boundary_fill_blend(int xstart, int ystart, double opacity, double boundary_red,double boundary_green,double boundary_blue,double fill_red, double fill_green, double fill_blue) ; void boundary_fill_blend(int xstart, int ystart, double opacity, int boundary_red,int boundary_green,int boundary_blue,int fill_red, int fill_green, int fill_blue) ; void flood_fill_blend(int xstart, int ystart, double opacity, double fill_red, double fill_green, double fill_blue) ; void flood_fill_blend(int xstart, int ystart, double opacity, int fill_red, int fill_green, int fill_blue) ; void polygon_blend(int* points, int number_of_points, double opacity, double red, double green, double blue); void polygon_blend(int* points, int number_of_points, double opacity, int red, int green, int blue); void plotCMYK_blend(int x, int y, double opacity, double cyan, double magenta, double yellow, double black); void plotCMYK_blend(int x, int y, double opacity, int cyan, int magenta, int yellow, int black); // End of Blended Functions /* Laplacian * This function applies a discrete laplacian to the image, multiplied by a constant factor. * The kernel used in this case is: * 1.0 1.0 1.0 * 1.0 -8.0 1.0 * 1.0 1.0 1.0 * Basically, this works as an edge detector. The current pixel is assigned the sum of all neighbouring * pixels, multiplied by the corresponding kernel element. For example, imagine a pixel and its 8 neighbours: * 1.0 1.0 0.0 0.0 * 1.0 ->1.0<- 0.0 0.0 * 1.0 1.0 0.0 0.0 * This represents a border between white and black, black is on the right. Applying the laplacian to * the pixel specified above pixel gives: * 1.0*1.0 + 1.0*1.0 + 0.0*1.0 + * 1.0*1.0 + 1.0*-8.0 + 0.0*1.0 + * 1.0*1.0 + 1.0*1.0 + 0.0*1.0 = -3.0 * Applying this to the pixel to the right of the pixel considered previously, we get a sum of 3.0. * That is, after passing over an edge, we get a high value for the pixel adjacent to the edge. Since * PNGwriter limits the colour components if they are off-scale, and the result of the laplacian * may be negative, a scale factor and an offset value are included. This might be useful for * keeping things within range or for bringing out more detail in the edge detection. The * final pixel value will be given by: * final value = laplacian(original pixel)*k + offset * Tip: Try a value of 1.0 for k to start with, and then experiment with other values. * */ void laplacian(double k, double offset); /* Filled Triangle * Draws the triangle specified by the three pairs of points in the colour specified * by the colour coefficients. The colour components are either doubles from 0.0 to * 1.0 or ints from 0 to 65535. * */ void filledtriangle(int x1,int y1,int x2,int y2,int x3,int y3, int red, int green, int blue); void filledtriangle(int x1,int y1,int x2,int y2,int x3,int y3, double red, double green, double blue); /* Filled Triangle, Blended * Draws the triangle specified by the three pairs of points in the colour specified * by the colour coefficients, and blended with the background. See the description for Blended Functions. * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. * */ void filledtriangle_blend(int x1,int y1,int x2,int y2,int x3,int y3, double opacity, int red, int green, int blue); void filledtriangle_blend(int x1,int y1,int x2,int y2,int x3,int y3, double opacity, double red, double green, double blue); /* Arrow, Filled Arrow * Plots an arrow from (x1, y1) to (x2, y2) with the arrowhead at the second point, given the size in pixels * and the angle in radians of the arrowhead. The plotted arrow consists of one main line, and two smaller * lines originating from the second point. Filled Arrow plots the same, but the arrowhead is a solid triangle. * Tip: An angle of 10 to 30 degrees looks OK. * */ void arrow(int x1,int y1,int x2,int y2,int size, double head_angle, double red, double green, double blue); void arrow(int x1,int y1,int x2,int y2,int size, double head_angle, int red, int green, int blue); void filledarrow(int x1,int y1,int x2,int y2,int size, double head_angle, double red, double green, double blue); void filledarrow(int x1,int y1,int x2,int y2,int size, double head_angle, int red, int green, int blue); /* Cross, Maltese Cross * Plots a simple cross at x, y, with the specified height and width, and in the specified colour. * Maltese cross plots a cross, as before, but adds bars at the end of each arm of the cross. * The size of these bars is specified with x_bar_height and y_bar_width. * The cross will look something like this: * * ----- <-- ( y_bar_width) * | * | * |-------| <-- ( x_bar_height ) * | * | * ----- * */ void cross(int x, int y, int xwidth, int yheight, double red, double green, double blue); void cross(int x, int y, int xwidth, int yheight, int red, int green, int blue); void maltesecross(int x, int y, int xwidth, int yheight, int x_bar_height, int y_bar_width, double red, double green, double blue); void maltesecross(int x, int y, int xwidth, int yheight, int x_bar_height, int y_bar_width, int red, int green, int blue); /* Diamond and filled diamond * Plots a diamond shape, given the x, y position, the width and height, and the colour. * Filled diamond plots a filled diamond. * */ void filleddiamond(int x, int y, int width, int height, int red, int green, int blue); void diamond(int x, int y, int width, int height, int red, int green, int blue); void filleddiamond(int x, int y, int width, int height, double red, double green, double blue); void diamond(int x, int y, int width, int height, double red, double green, double blue); /* Get Text Width, Get Text Width UTF8 * Returns the approximate width, in pixels, of the specified *unrotated* text. It is calculated by adding * each letter's width and kerning value (as specified in the TTF file). Note that this will not * give the position of the farthest pixel, but it will give a pretty good idea of what area the * text will occupy. Tip: The text, when plotted unrotated, will fit approximately in a box with its lower left corner at * (x_start, y_start) and upper right at (x_start + width, y_start + size), where width is given by get_text_width() * and size is the specified size of the text to be plotted. Tip: Text plotted at position * (x_start, y_start), rotated with a given 'angle', and of a given 'size' * whose width is 'width', will fit approximately inside a rectangle whose corners are at * 1 (x_start, y_start) * 2 (x_start + width*cos(angle), y_start + width*sin(angle)) * 3 (x_start + width*cos(angle) - size*sin(angle), y_start + width*sin(angle) + size*cos(angle)) * 4 (x_start - size*sin(angle), y_start + size*cos(angle)) * */ int get_text_width(char* face_path, int fontsize, char* text); int get_text_width_utf8(char* face_path, int fontsize, char* text); }; #endif