⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairotwisted.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 2 页
字号:
 *     http://en.wikipedia.org/wiki/B%C3%A9zier_curve * *   - The Gradient (aka multi-dimensional derivative) of the above *     http://en.wikipedia.org/wiki/Gradient * * The parametric forms are used to answer the question of "where will I be * if I walk a distance of X on this path".  The Gradient is used to answer * the question of "where will I be if then I stop, rotate left for 90 * degrees and walk straight for a distance of Y". */static voidpoint_on_path (parametrized_path_t *param,	       double *x, double *y){  int i;  double ratio, the_y = *y, the_x = *x, dx, dy;  cairo_path_data_t *data, current_point;  cairo_path_t *path = param->path;  parametrization_t *parametrization = param->parametrization;  for (i=0; i + path->data[i].header.length < path->num_data &&	    (the_x > parametrization[i] ||	     path->data[i].header.type == CAIRO_PATH_MOVE_TO);       i += path->data[i].header.length) {    the_x -= parametrization[i];    data = &path->data[i];    switch (data->header.type) {    case CAIRO_PATH_MOVE_TO:	current_point = data[1];	break;    case CAIRO_PATH_LINE_TO:	current_point = data[1];	break;    case CAIRO_PATH_CURVE_TO:	current_point = data[3];	break;    case CAIRO_PATH_CLOSE_PATH:	break;    default:	g_assert_not_reached ();    }  }  data = &path->data[i];  switch (data->header.type) {  case CAIRO_PATH_MOVE_TO:      break;  case CAIRO_PATH_LINE_TO:      {	ratio = the_x / parametrization[i];	/* Line polynomial */	*x = current_point.point.x * (1 - ratio) + data[1].point.x * ratio;	*y = current_point.point.y * (1 - ratio) + data[1].point.y * ratio;	/* Line gradient */	dx = -(current_point.point.x - data[1].point.x);	dy = -(current_point.point.y - data[1].point.y);	/*optimization for: ratio = the_y / sqrt (dx * dx + dy * dy);*/	ratio = the_y / parametrization[i];	*x += -dy * ratio;	*y +=  dx * ratio;      }      break;  case CAIRO_PATH_CURVE_TO:      {	/* FIXME the formulas here are not exactly what we want, because the	 * Bezier parametrization is not uniform.  But I don't know how to do	 * better.  The caller can do slightly better though, by flattening the	 * Bezier and avoiding this branch completely.  That has its own cost	 * though, as large y values magnify the flattening error drastically.	 */        double ratio_1_0, ratio_0_1;	double ratio_2_0, ratio_0_2;	double ratio_3_0, ratio_2_1, ratio_1_2, ratio_0_3;	double _1__4ratio_1_0_3ratio_2_0, _2ratio_1_0_3ratio_2_0;	ratio = the_x / parametrization[i];	ratio_1_0 = ratio;	ratio_0_1 = 1 - ratio;	ratio_2_0 = ratio_1_0 * ratio_1_0; /*      ratio  *      ratio  */	ratio_0_2 = ratio_0_1 * ratio_0_1; /* (1 - ratio) * (1 - ratio) */	ratio_3_0 = ratio_2_0 * ratio_1_0; /*      ratio  *      ratio  *      ratio  */	ratio_2_1 = ratio_2_0 * ratio_0_1; /*      ratio  *      ratio  * (1 - ratio) */	ratio_1_2 = ratio_1_0 * ratio_0_2; /*      ratio  * (1 - ratio) * (1 - ratio) */	ratio_0_3 = ratio_0_1 * ratio_0_2; /* (1 - ratio) * (1 - ratio) * (1 - ratio) */	_1__4ratio_1_0_3ratio_2_0 = 1 - 4 * ratio_1_0 + 3 * ratio_2_0;	_2ratio_1_0_3ratio_2_0    =     2 * ratio_1_0 - 3 * ratio_2_0;	/* Bezier polynomial */	*x = current_point.point.x * ratio_0_3	   + 3 *   data[1].point.x * ratio_1_2	   + 3 *   data[2].point.x * ratio_2_1	   +       data[3].point.x * ratio_3_0;	*y = current_point.point.y * ratio_0_3	   + 3 *   data[1].point.y * ratio_1_2	   + 3 *   data[2].point.y * ratio_2_1	   +       data[3].point.y * ratio_3_0;	/* Bezier gradient */	dx =-3 * current_point.point.x * ratio_0_2	   + 3 *       data[1].point.x * _1__4ratio_1_0_3ratio_2_0	   + 3 *       data[2].point.x * _2ratio_1_0_3ratio_2_0	   + 3 *       data[3].point.x * ratio_2_0;	dy =-3 * current_point.point.y * ratio_0_2	   + 3 *       data[1].point.y * _1__4ratio_1_0_3ratio_2_0	   + 3 *       data[2].point.y * _2ratio_1_0_3ratio_2_0	   + 3 *       data[3].point.y * ratio_2_0;	ratio = the_y / sqrt (dx * dx + dy * dy);	*x += -dy * ratio;	*y +=  dx * ratio;      }      break;  case CAIRO_PATH_CLOSE_PATH:      break;  default:      g_assert_not_reached ();  }}/* Projects the current path of cr onto the provided path. */static voidmap_path_onto (cairo_t *cr, cairo_path_t *path){  cairo_path_t *current_path;  parametrized_path_t param;  param.path = path;  param.parametrization = parametrize_path (path);  current_path = cairo_copy_path (cr);  cairo_new_path (cr);  transform_path (current_path,		  (transform_point_func_t) point_on_path, &param);  cairo_append_path (cr, current_path);}typedef void (*draw_path_func_t) (cairo_t *cr);static voiddraw_text (cairo_t *cr,	   double x,	   double y,	   const char *font,	   const char *text){  PangoLayout *layout;  PangoLayoutLine *line;  PangoFontDescription *desc;  cairo_font_options_t *font_options;  font_options = cairo_font_options_create ();  cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);  cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);  cairo_set_font_options (cr, font_options);  cairo_font_options_destroy (font_options);  layout = pango_cairo_create_layout (cr);  desc = pango_font_description_from_string (font);  pango_layout_set_font_description (layout, desc);  pango_font_description_free (desc);  pango_layout_set_text (layout, text, -1);  /* Use pango_layout_get_line() instead of pango_layout_get_line_readonly()   * for older versions of pango   */  line = pango_layout_get_line_readonly (layout, 0);  cairo_move_to (cr, x, y);  pango_cairo_layout_line_path (cr, line);  g_object_unref (layout);}static voiddraw_twisted (cairo_t *cr,	      double x,	      double y,	      const char *font,	      const char *text){  cairo_path_t *path;  cairo_save (cr);  /* Decrease tolerance a bit, since it's going to be magnified */  cairo_set_tolerance (cr, 0.01);  /* Using cairo_copy_path() here shows our deficiency in handling   * Bezier curves, specially around sharper curves.   *   * Using cairo_copy_path_flat() on the other hand, magnifies the   * flattening error with large off-path values.  We decreased   * tolerance for that reason.  Increase tolerance to see that   * artifact.   */  path = cairo_copy_path_flat (cr);/*path = cairo_copy_path (cr);*/  cairo_new_path (cr);  draw_text (cr, x, y, font, text);  map_path_onto (cr, path);  cairo_fill_preserve (cr);  cairo_save (cr);  cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);  cairo_stroke (cr);  cairo_restore (cr);  cairo_restore (cr);}static voiddraw_dream (cairo_t *cr){  cairo_move_to (cr, 50, 650);  cairo_rel_line_to (cr, 250, 50);  cairo_rel_curve_to (cr, 250, 50, 600, -50, 600, -250);  cairo_rel_curve_to (cr, 0, -400, -300, -100, -800, -300);  cairo_set_line_width (cr, 1.5);  cairo_set_source_rgba (cr, 0.3, 0.3, 1.0, 0.3);  fancy_cairo_stroke_preserve (cr);  draw_twisted (cr,		0, 0,		"Serif 72",		"It was a dream... Oh Just a dream...");}static voiddraw_wow (cairo_t *cr){  cairo_move_to (cr, 400, 780);  cairo_rel_curve_to (cr, 50, -50, 150, -50, 200, 0);  cairo_scale (cr, 1.0, 2.0);  cairo_set_line_width (cr, 2.0);  cairo_set_source_rgba (cr, 0.3, 1.0, 0.3, 1.0);  fancy_cairo_stroke_preserve (cr);  draw_twisted (cr,		-20, -150,		"Serif 60",		"WOW!");}int main (int argc, char **argv){  cairo_t *cr;  char *filename;  cairo_status_t status;  cairo_surface_t *surface;  if (argc != 2)    {      g_printerr ("Usage: cairotwisted OUTPUT_FILENAME\n");      return 1;    }  filename = argv[1];  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,					1000, 800);  cr = cairo_create (surface);  cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);  cairo_paint (cr);  draw_dream (cr);  draw_wow (cr);  cairo_destroy (cr);  status = cairo_surface_write_to_png (surface, filename);  cairo_surface_destroy (surface);  if (status != CAIRO_STATUS_SUCCESS)    {      g_printerr ("Could not save png to '%s'\n", filename);      return 1;    }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -