codice:
#include <iostream>
#define FONT "Sans"
#define TEXTFACTOR 0.8
#define AUTHORSCALEFACTOR 0.7
#define MAX_TRANSFORM_X 100
#define MAX_TRANSFORM_Y 100
class line
{
public:
line(char*, char*, int, int, int, int, int);
void SetTextColor(float,float,float);
bool Step(cairo_t*);
private:
cairo_matrix_t matrix, backupmatrix;
int fade_in_max, stay_on_max, fade_out_max;
float fade_in_step, fade_out_step;
int current_step;
int max_transform_y, max_transform_x;
float transform_x_step, transform_y_step;
char* text;
char* author;
int win_x, win_y;
void Draw(cairo_t*);
void GetRows(cairo_t*);
float colormatrix[4];
float size;
char font[100];
int numrows;
struct row_t
{
int x;
int y;
char text[100];
} rows[50];
};
line::line(char *textin, char *authorin, int width, int height, int fade_in, int stay_on, int fade_out)
{
text = (char*) malloc(sizeof(char) * (strlen(textin) + 1)); //allocating space for the text and author
author = (char*) malloc(sizeof(char) * (strlen(authorin) + 1));
strcpy(text, textin); //copy the input strings into the private string
strcpy(author, authorin);
colormatrix[0] = 0; //default text color black
colormatrix[1] = 0;
colormatrix[2] = 0;
colormatrix[4] = 1;
size = 50.0;
strcpy(font, FONT);
numrows = 0;
win_x = height;
win_y = width;
fade_in_max = fade_in;
stay_on_max = stay_on;
fade_out_max = fade_out;
fade_in_step = 1/fade_in_max; //calculate the speed of fade in effect, the more the total effect time, the less the step;
fade_out_step = 1/fade_out_max; //calculate the speed of fade in effect, the more the total effect time, the less the step;
current_step = 0;
max_transform_y = (rand()%(2*MAX_TRANSFORM_Y)) - MAX_TRANSFORM_Y; //generate transformation matrix, we allow negative translations.
max_transform_x = (rand()%(2*MAX_TRANSFORM_X)) - MAX_TRANSFORM_X;
transform_x_step = max_transform_x/fade_in_max+stay_on_max+fade_out_max; //calculate the speed of translation, total distance / total steps
transform_y_step = max_transform_y/fade_in_max+stay_on_max+fade_out_max;
cairo_matrix_init_identity(&matrix);
}
bool line::Step(cairo_t *cr)
{
cairo_get_matrix(cr, &backupmatrix); //make a backup copy of the current matrix
cairo_set_matrix(cr, &matrix); //use our matrix
if (current_step < fade_in_max)
{ puts(cairo_status_to_string(cairo_status(cr)));
colormatrix[3] += fade_in_step;
cairo_translate(cr, transform_x_step, transform_y_step);
}
else if (current_step - fade_in_max < stay_on_max)
{
cairo_translate(cr, transform_x_step, transform_y_step);
}
else if (current_step - fade_in_max - stay_on_max < fade_out_max)
{
colormatrix[3] -= fade_out_step;
cairo_translate(cr, transform_x_step, transform_y_step);
}
else return false;
Draw(cr);
cairo_get_matrix(cr, &matrix); //save our matrix
cairo_set_matrix(cr, &backupmatrix); // reset the backup matrix
current_step++;
}
void line::SetTextColor(float r, float g, float b)
{
if (r > 1) r = 1; //max and min value for the colormatrix
if (r < 0) r = 0;
if (g > 1) g = 1;
if (g < 0) g = 0;
if (b > 1) b = 1;
if (b < 0) b = 0;
colormatrix[0] = r; //update colormatrix with new values
colormatrix[1] = g;
colormatrix[2] = b;
}
void line::GetRows(cairo_t *cr)
{
char *buff;
int x,y;
int y_size = 0;
cairo_text_extents_t extents;
cairo_text_extents_t buffextents;
cairo_select_font_face(cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, size);
buff = strtok(text, " "); //get the frist tok and copy it in the frsit line
strcpy(rows[numrows].text, buff);
strcat(rows[numrows].text, " ");
while(1)
{
buff = strtok(NULL, " "); //get a new tok
if (buff == NULL) break; //if we've reached the end exit the while
cairo_text_extents(cr, rows[numrows].text, &extents); //lenght of the current row
cairo_text_extents(cr, buff, &buffextents);
if (extents.width + buffextents.width > win_x*TEXTFACTOR) //if the row is too wide use another row
{
y_size += extents.height; //increase the text global heighth
numrows++; //change the current row
strcpy(rows[numrows].text, buff); //write buff
strcat(rows[numrows].text, " ");
}
else
{
strcat(rows[numrows].text, buff); //append buff at the row
strcat(rows[numrows].text, " ");
}
}
numrows++; //numrows starts form 0, we have to add 1 to get the real number of rows
int y_start = (win_y-y_size)/2; //the starting printing pos
for (int i = 0; i < numrows; i++) //for each row
{
cairo_text_extents(cr, rows[i].text, &extents); //calculate the printing pos of each row
rows[i].x = (win_x - extents.width)/2;
rows[i].y = y_start;
y_start += extents.height + size/4;
}
}
void line::Draw(cairo_t *cr)
{
GetRows(cr); //Split the text in varous rows;
int w,h;
cairo_set_source_rgba(cr, colormatrix[0], colormatrix[1],colormatrix[2], colormatrix[3]); //setup text rendering
cairo_select_font_face(cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, size);
for (int i = 0; i < numrows; i++) //print each row
{
cairo_move_to(cr, rows[i].x, rows[i].y);
cairo_show_text(cr, rows[i].text);
}
cairo_text_extents_t extents; //Print the author string;
cairo_set_font_size(cr, size*AUTHORSCALEFACTOR);
cairo_text_extents(cr, author, &extents);
int x,y;
x = (w-extents.width)*0.80;
y = (h+rows[numrows-1].y)/2;
cairo_move_to(cr, x, y);
cairo_show_text(cr, author);
}