Advertisement
Guest User

pangocairo unicode smileys

a guest
Dec 22nd, 2014
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.67 KB | None | 0 0
  1. /* Example code to show how to use pangocairo to render arbitrary shapes
  2.  * inside a text layout, positioned by Pango.  This has become possibly
  3.  * using the following API added in Pango 1.18:
  4.  *
  5.  *  pango_cairo_context_set_shape_renderer ()
  6.  *
  7.  * This examples uses a small parser to convert shapes in the format of
  8.  * SVG paths to cairo instructions.  You can typically extract these from
  9.  * the SVG file's <path> elements directly.
  10.  *
  11.  * The code then searches for the Unicode bullet character in the layout
  12.  * text and automatically adds PangoAttribtues to the layout to replace
  13.  * each of the with a rendering of the GNOME Foot logo.
  14.  *
  15.  *
  16.  * Written by Behdad Esfahbod, 2007
  17.  *
  18.  * Permission to use, copy, modify, distribute, and sell this example
  19.  * for any purpose is hereby granted without fee.
  20.  * It is provided "as is" without express or implied warranty.
  21.  */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26.  
  27. #include <pango/pangocairo.h>
  28.  
  29. #define BULLET "*"
  30.  
  31. const char text[] =
  32. "The GNOME project provides two things:\n"
  33. "\n"
  34. "  * The \x28\x20\xCD\xA1\xC2\xB0\x20\xCD\x9C\xCA\x96\x20\xCD\xA1\xC2\xB0\x29 desktop environment\n"
  35. "  * The \xD9\xA9\xE0\xB9\x8F\xCC\xAF\xCD\xA1\xE0\xB9\x8F\x29\xDB\xB6 development platform\n"
  36. "  * Planet \x28\xE2\x98\x9E\xEF\xBE\x9F\xE3\x83\xAE\xEF\xBE\x9F\x29\xE2\x98\x9E \xF0\x9F\x99\x8F";
  37.  
  38. typedef struct {
  39.   double width, height;
  40.   const char *path;
  41. } MiniSvg;
  42.  
  43. static MiniSvg GnomeFootLogo = {
  44.   96.2152, 118.26,
  45.   "M 86.068,1 C 61.466,0 56.851,35.041 70.691,35.041 C 84.529,35.041 110.671,0 86.068,0 z "
  46.   "M 45.217,30.699 C 52.586,31.149 60.671,2.577 46.821,4.374 C 32.976,6.171 37.845,30.249 45.217,30.699 z "
  47.   "M 11.445,48.453 C 16.686,46.146 12.12,23.581 3.208,29.735 C -5.7,35.89 6.204,50.759 11.445,48.453 z "
  48.   "M 26.212,36.642 C 32.451,35.37 32.793,9.778 21.667,14.369 C 10.539,18.961 19.978,37.916 26.212,36.642 L 26.212,36.642 z "
  49.   "M 58.791,93.913 C 59.898,102.367 52.589,106.542 45.431,101.092 C 22.644,83.743 83.16,75.088 79.171,51.386 C 75.86,31.712 15.495,37.769 8.621,68.553 C 3.968,89.374 27.774,118.26 52.614,118.26 C 64.834,118.26 78.929,107.226 81.566,93.248 C 83.58,82.589 57.867,86.86 58.791,93.913 L 58.791,93.913 z "
  50.   "\0"
  51. };
  52.  
  53. static void
  54. mini_svg_render (MiniSvg  *shape,
  55.          cairo_t  *cr,
  56.          gboolean  do_path)
  57. {
  58.   double x, y;
  59.   const char *p;
  60.   char op[2];
  61.   int len;
  62.  
  63.   cairo_get_current_point (cr, &x, &y);
  64.   cairo_translate (cr, x, y);
  65.  
  66.   for (p = shape->path; sscanf (p, "%1s %n", op, &len), p += len, *p;)
  67.     switch (*op)
  68.     {
  69.       case 'M':
  70.         {
  71.       sscanf (p, "%lf,%lf %n", &x, &y, &len); p += len;
  72.       cairo_move_to (cr, x, y);
  73.       break;
  74.     }
  75.       case 'L':
  76.         {
  77.       sscanf (p, "%lf,%lf %n", &x, &y, &len); p += len;
  78.       cairo_line_to (cr, x, y);
  79.       break;
  80.     }
  81.       case 'C':
  82.         {
  83.       double x1, y1, x2, y2, x3, y3;
  84.       sscanf (p, "%lf,%lf %lf,%lf %lf,%lf %n", &x1, &y1, &x2, &y2, &x3, &y3, &len); p += len;
  85.       cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
  86.       break;
  87.     }
  88.       case 'z':
  89.         {
  90.       cairo_close_path (cr);
  91.       break;
  92.     }
  93.       default:
  94.         {
  95.       //g_warning ("Invalid MiniSvg operation '%c'", *op);
  96.       break;
  97.     }
  98.     }
  99.  
  100.   if (!do_path)
  101.     cairo_fill (cr);
  102. }
  103.  
  104. static void
  105. mini_svg_shape_renderer (cairo_t        *cr,
  106.              PangoAttrShape *attr,
  107.              gboolean        do_path,
  108.              gpointer        data G_GNUC_UNUSED)
  109. {
  110.   MiniSvg *shape = (MiniSvg *) attr->data;
  111.   double scale_x, scale_y;
  112.  
  113.   scale_x = (double) attr->ink_rect.width  / (PANGO_SCALE * shape->width );
  114.   scale_y = (double) attr->ink_rect.height / (PANGO_SCALE * shape->height);
  115.  
  116.   cairo_rel_move_to (cr,
  117.              (double) attr->ink_rect.x / PANGO_SCALE,
  118.              (double) attr->ink_rect.y / PANGO_SCALE);
  119.   cairo_scale (cr, scale_x, scale_y);
  120.  
  121.   mini_svg_render (shape, cr, do_path);
  122. }
  123.  
  124.  
  125. static PangoLayout *
  126. get_layout (cairo_t *cr)
  127. {
  128.   PangoLayout *layout;
  129.   PangoAttrList *attrs;
  130.   PangoRectangle ink_rect     = {1 * PANGO_SCALE, -11 * PANGO_SCALE,  8 * PANGO_SCALE, 10 * PANGO_SCALE};
  131.   PangoRectangle logical_rect = {0 * PANGO_SCALE, -12 * PANGO_SCALE, 10 * PANGO_SCALE, 12 * PANGO_SCALE};
  132.   const char *p;
  133.  
  134.   /* Create a PangoLayout, set the font and text */
  135.   layout = pango_cairo_create_layout (cr);
  136.  
  137.   pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout),
  138.                       mini_svg_shape_renderer, NULL, NULL);
  139.  
  140.   pango_layout_set_text (layout, text, -1);
  141.  
  142.   attrs = pango_attr_list_new ();
  143.  
  144.   /* Set gnome shape attributes for all bullets */
  145.   for (p = text; (p = strstr (p, BULLET)); p += strlen (BULLET))
  146.     {
  147.       PangoAttribute *attr;
  148.      
  149.       attr = pango_attr_shape_new_with_data (&ink_rect,
  150.                          &logical_rect,
  151.                          &GnomeFootLogo,
  152.                          NULL, NULL);
  153.  
  154.       attr->start_index = p - text;
  155.       attr->end_index = attr->start_index + strlen (BULLET);
  156.  
  157.       pango_attr_list_insert (attrs, attr);
  158.     }
  159.  
  160.   pango_layout_set_attributes (layout, attrs);
  161.   pango_attr_list_unref (attrs);
  162.  
  163.   return layout;
  164. }
  165.  
  166. static void
  167. draw_text (cairo_t *cr, int *width, int *height)
  168. {
  169.  
  170.   PangoLayout *layout = get_layout (cr);
  171.  
  172.   /* Adds a fixed 10-pixel margin on the sides. */
  173.  
  174.   if (width || height)
  175.     {
  176.       pango_layout_get_pixel_size (layout, width, height);
  177.       if (width)
  178.         *width += 20;
  179.       if (height)
  180.         *height += 20;
  181.     }
  182.  
  183.   cairo_move_to (cr, 10, 10);
  184.   pango_cairo_show_layout (cr, layout);
  185.  
  186.   g_object_unref (layout);
  187. }
  188.  
  189. int main (int argc, char **argv)
  190. {
  191.   cairo_t *cr;
  192.   char *filename;
  193.   cairo_status_t status;
  194.   cairo_surface_t *surface;
  195.   int width, height;
  196.  
  197.   if (argc != 2)
  198.     {
  199.      filename="output.png";
  200.       //return 1;
  201.     }
  202.  
  203.   else filename = argv[1];
  204.  
  205.   /* First create and use a 0x0 surface, to measure how large
  206.    * the final surface needs to be */
  207.   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
  208.                     0, 0);
  209.   cr = cairo_create (surface);
  210.   draw_text (cr, &width, &height);
  211.   cairo_destroy (cr);
  212.   cairo_surface_destroy (surface);
  213.  
  214.   /* Now create the final surface and draw to it. */
  215.   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
  216.                     width, height);
  217.   cr = cairo_create (surface);
  218.  
  219.   cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
  220.   cairo_paint (cr);
  221.   cairo_set_source_rgb (cr, 0.0, 0.0, 0.5);
  222.   draw_text (cr, NULL, NULL);
  223.   cairo_destroy (cr);
  224.  
  225.   /* Write out the surface as PNG */
  226.   status = cairo_surface_write_to_png (surface, filename);
  227.   cairo_surface_destroy (surface);
  228.  
  229.   if (status != CAIRO_STATUS_SUCCESS)
  230.     {
  231.       //g_printerr ("Could not save png to '%s'\n", filename);
  232.       return 1;
  233.     }
  234.   {
  235.     FILE *fd = fopen("output.txt","wb");
  236.     assert(fd);
  237.     fwrite(text,strlen(text),1,fd);
  238.     fclose(fd);
  239. }
  240.   return 0;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement