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 16#define DEFAULT_REPOS_H 12#define MAX_FONT_SIZE 120#define MIN_FONT_SIZE 5cairo_surface_t *SURFACE;cairo_t *CONTEXT;extern list *WORDS ;extern list *stop_WORDS ;static int reposition_x(int *x,int font_size){ double dx,bias; bias = (1.0 - ((double)font_size/(double)MAX_FONT_SIZE))/3.0; if(bias>0.4) bias = 0.4; dx = (double)(*x)/(double)DEFAULT_WIDTH; if(dx > bias && dx < (1-bias) ) return 1; if(*x > (DEFAULT_WIDTH/2)){ (*x)-=DEFAULT_REPOS_W; }else { (*x)+=DEFAULT_REPOS_W; } return 0;}static int reposition_y(int *y, int font_size){ double dy,bias; bias = (1.0 - ((double)font_size/(double)MAX_FONT_SIZE))/2.0; if(bias>0.4) bias = 0.4; dy = (double)(*y)/(double)DEFAULT_HEIGHT; if(dy > bias && dy < (1-bias)) return 1; if(*y > (DEFAULT_HEIGHT/2)){ (*y)-=DEFAULT_REPOS_H; }else { (*y)+=DEFAULT_REPOS_H; } return 0;}static int check_overlap(int x, int y, int w, int h){ unsigned char *data; int row,offset; int i; if(y<0){ //printf("check_overlap: %i,%i,%i,%i\n",x,y,w,h); 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+1) ; 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_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); if(rv)break; if(!check_overlap(nx+extents.x_bearing, y+extents.y_bearing, extents.width, extents.height))break; } ny = y; for(tries=0;;tries++){ ry = ny; rv = reposition_y(&ny,font_size); if(rv)break; if(!check_overlap(rx+extents.x_bearing, ny+extents.y_bearing, extents.width, extents.height))break; } //printf("tires = %i\n",tries); cairo_move_to(CONTEXT, rx + (pw/2), ry + (ph/2)); 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); 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;}