rendered paste body#include <cairo.h>#include <pango/pango.h>#include <stdlib.h>#include <string.h>#include "words.h"#define DEFAULT_WIDTH 1200#define DEFAULT_HEIGHT 800#define DEFAULT_REPOS_W 24#define DEFAULT_REPOS_H 16#define MAX_FONT_SIZE 150#define MIN_FONT_SIZE 10cairo_surface_t *SURFACE;cairo_t *CONTEXT;extern list *WORDS ;extern list *stop_WORDS ;static int reposition_x(int *x,int font_size,double px){ double dx,bias; double top,bottom; bias = (1.0 - ((double)font_size/(double)MAX_FONT_SIZE)); if(bias>0.8) bias = 0.9; dx = (double)(*x)/(double)DEFAULT_WIDTH; bottom = px*bias; top = px + ((1-px)*(1-bias)); printf("x=%i,dx=%f,bottom=%f,top=%f\n",*x,dx,bottom,top); if( (dx >= bottom) && (dx <= top) ) return 1; if(dx > top){ (*x)-=DEFAULT_REPOS_W; }else if(dx < bottom) { (*x)+=DEFAULT_REPOS_W; } printf("left x=%i\n",*x); return 0;}static int reposition_y(int *y, int font_size, double py){ double dy,bias; double top,bottom; bias = (1.0 - ((double)font_size/(double)MAX_FONT_SIZE)); if(bias>0.9) bias = 0.9; dy = (double)(*y)/(double)DEFAULT_HEIGHT; bottom = py*bias; top = py + ((1-py)*(1-bias)); printf("dy=%f,bottom=%f,top=%f\n",dy,bottom,top); if(dy >= bottom && dy <= top ) return 1; if(dy > top){ (*y)-=DEFAULT_REPOS_H; }else if(dy < bottom){ (*y)+=DEFAULT_REPOS_H; } printf("left y=%i\n",*y); return 0;}static int check_overlap(int x, int y, int w, int h){ unsigned char *data; int row,offset; int i; printf("check_overlap: %i,%i,%i,%i\n",x,y,w,h); if(y<0){ return 0; } data = cairo_image_surface_get_data(SURFACE); if( ((x+w) > DEFAULT_WIDTH) || ((y+h)>DEFAULT_HEIGHT)) return 0; for(row = y ; row < (y+h) ; row++){ offset = (row*DEFAULT_WIDTH*4) + (x*4); for(i=(offset+3);i<(offset+(w*4));i+=4){ if(data[i] != 0) return 0; } } return 1;}static int place_text(char *string, int font_size){ int x,y,nx,ny,rx,ry,pw,ph; int tries; int rv; cairo_t *cr; cairo_surface_t *target; cairo_text_extents_t extents; x = random()%DEFAULT_WIDTH; y = random()%DEFAULT_HEIGHT; target = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,DEFAULT_WIDTH,DEFAULT_HEIGHT); cr = cairo_create(target); cairo_surface_destroy(target); cairo_font_options_t *options = cairo_font_options_create (); cairo_get_font_options (cr, options); cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE); cairo_set_font_options (cr, options); cairo_font_options_destroy (options); cairo_set_font_size(cr,font_size); cairo_text_extents(cr,string,&extents); cairo_destroy(cr); pw = (extents.width/10) + 2; ph = (extents.height/10) + 2;// extents.width += pw;// extents.height += ph; if(check_overlap(x+extents.x_bearing, y+extents.y_bearing, extents.width,extents.height)){ nx = x; for(tries=0;;tries++){ rx = nx; rv = reposition_x(&nx,font_size,0.5); if(rv)break; if(!check_overlap(nx+extents.x_bearing, y+extents.y_bearing, extents.width, extents.height))break; } printf("x tries=%i,rv=%i\n",tries,rv); ny = y; for(tries=0;;tries++){ ry = ny; rv = reposition_y(&ny,font_size,0.5); if(rv)break; if(!check_overlap(rx+extents.x_bearing, ny+extents.y_bearing, extents.width, extents.height))break; } printf("y tries=%i,rv=%i\n",tries,rv); printf("x_bearing=%f,y_bearing=%f\n",extents.x_bearing,extents.y_bearing); printf("x_bearing=%i,y_bearing=%i\n",(int)extents.x_bearing,(int)extents.y_bearing); printf("%s .. size=%i,x=%i,y=%i,rx=%i,ry=%i\n", string,font_size,x,y,rx,ry); //printf("tires = %i\n",tries); cairo_move_to(CONTEXT, rx , ry ); cairo_set_line_width(CONTEXT, 1.0); cairo_set_font_size(CONTEXT,font_size); cairo_set_source_rgb(CONTEXT, 0,// (double)rand()/RAND_MAX, 0.5, // (double)rand()/RAND_MAX, (double)random()/RAND_MAX); cairo_show_text(CONTEXT,string); return 1; } return 0;}int main (int argc, char **argv){ int tries; int failed; list *i; int count,total_tries; double font_size; double hit_ratio; time_t now; failed = 0; count = 0; total_tries = 0; time(&now); srandom((unsigned int) now); SURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,DEFAULT_WIDTH,DEFAULT_HEIGHT); CONTEXT = cairo_create(SURFACE); //cairo_set_font_size(CONTEXT, MAX_FONT_SIZE); cairo_font_options_t *options = cairo_font_options_create (); cairo_get_font_options (CONTEXT, options); cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE); cairo_set_font_options (CONTEXT, options); cairo_font_options_destroy (options); WORDS_read(argv[1]); WORDS_order(); WORDS_clean(); for(i=WORDS;i;i=i->next){ for(tries=1;tries<100;tries++){ font_size = ((double)(i->count + 1)/ (double)WORDS->count)*MAX_FONT_SIZE; if(place_text(i->string, (int) font_size + MIN_FONT_SIZE ))break; } if(tries==100)failed++; count++; total_tries += tries; if(count > 200) break; } hit_ratio = (double)count / (double)total_tries; printf("count = %i\n",count); printf("fails = %i\n",failed); printf("accuracy = %f\n",hit_ratio);// WORDS_dump(WORDS); cairo_surface_write_to_png(SURFACE,"Vikloud.png"); return 0;}