[pango/pango2: 4/6] Update examples in the docs




commit fc68046f3e6b02079fe9287a59beb98fbcc13a6d
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jun 26 11:23:38 2022 -0400

    Update examples in the docs
    
    Sucks that we have to do this manually.

 docs/first_steps.md  |  25 +--
 docs/migrating.md    |   4 +-
 docs/pango_cairo.md  |  37 +++--
 docs/pango_layout.md | 100 ++++++------
 docs/pango_user.md   | 433 ++++++++++++++++++++++++++++-----------------------
 5 files changed, 328 insertions(+), 271 deletions(-)
---
diff --git a/docs/first_steps.md b/docs/first_steps.md
index a863fc336..7e369a5d9 100644
--- a/docs/first_steps.md
+++ b/docs/first_steps.md
@@ -22,29 +22,29 @@ Useful next steps would be:
 
 ```
 #include <math.h>
-#include <pango/pangocairo.h>
+#include <pango2/pangocairo.h>
 
 #define SIZE 150
 
 static void
 draw_text (cairo_t *cr)
 {
-  PangoLayout *layout;
-  PangoFontDescription *desc;
+  Pango2Layout *layout;
+  Pango2FontDescription *desc;
 
-  /* Create a PangoLayout */
-  layout = pango_cairo_create_layout (cr);
+  /* Create a Pango2Layout */
+  layout = pango2_cairo_create_layout (cr);
 
   /* Set the text */
-  pango_layout_set_text (layout, "Text", -1);
+  pango2_layout_set_text (layout, "Text", -1);
 
   /* Set a font for the layout */
-  desc = pango_font_description_from_string ("Sans Bold 20");
-  pango_layout_set_font_description (layout, desc);
-  pango_font_description_free (desc);
+  desc = pango2_font_description_from_string ("Sans Bold 20");
+  pango2_layout_set_font_description (layout, desc);
+  pango2_font_description_free (desc);
 
   /* Show the layout */
-  pango_cairo_show_layout (cr, layout);
+  pango2_cairo_show_layout (cr, layout);
 
   /* Free the layout object */
   g_object_unref (layout);
@@ -85,7 +85,12 @@ main (int argc, char **argv)
 
   cairo_destroy (cr);
 
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
   status = cairo_surface_write_to_png (surface, filename);
+#else
+  status = CAIRO_STATUS_PNG_ERROR; /* Not technically correct, but... */
+#endif
+
   cairo_surface_destroy (surface);
 
   if (status != CAIRO_STATUS_SUCCESS)
diff --git a/docs/migrating.md b/docs/migrating.md
index 7c1e3b372..a7e7a5d7e 100644
--- a/docs/migrating.md
+++ b/docs/migrating.md
@@ -46,8 +46,8 @@ prefix as well:
 
 The big advantage of this change is that the two libraries can be used
 side-by-side in the same process without symbol or type clashes. The downside
-is, of course, that you have to adapt your code to change all uses of
-Pango API. Thankfully, this is largely a mechanical change.
+is, of course, that you have to adapt all uses of Pango API in your code.
+Thankfully, this is largely a mechanical change.
 
 ### Build setup changes
 
diff --git a/docs/pango_cairo.md b/docs/pango_cairo.md
index 309b7d022..afd59ae97 100644
--- a/docs/pango_cairo.md
+++ b/docs/pango_cairo.md
@@ -32,7 +32,7 @@ point units used in Cairo divide by `PANGO_SCALE`.
 
 ```
 #include <math.h>
-#include <pango/pangocairo.h>
+#include <pango2/pangocairo.h>
 
 #define RADIUS 150
 #define N_WORDS 10
@@ -41,21 +41,21 @@ point units used in Cairo divide by `PANGO_SCALE`.
 static void
 draw_text (cairo_t *cr)
 {
-  PangoLayout *layout;
-  PangoLines *lines;
-  PangoFontDescription *desc;
+  Pango2Layout *layout;
+  Pango2Lines *lines;
+  Pango2FontDescription *desc;
   int i;
 
   /* Center coordinates on the middle of the region we are drawing */
   cairo_translate (cr, RADIUS, RADIUS);
 
-  /* Create a PangoLayout, set the font and text */
-  layout = pango_cairo_create_layout (cr);
+  /* Create a Pango2Layout, set the font and text */
+  layout = pango2_cairo_create_layout (cr);
 
-  pango_layout_set_text (layout, "Text", -1);
-  desc = pango_font_description_from_string (FONT);
-  pango_layout_set_font_description (layout, desc);
-  pango_font_description_free (desc);
+  pango2_layout_set_text (layout, "Text", -1);
+  desc = pango2_font_description_from_string (FONT);
+  pango2_layout_set_font_description (layout, desc);
+  pango2_font_description_free (desc);
 
   /* Draw the layout N_WORDS times in a circle */
   for (i = 0; i < N_WORDS; i++)
@@ -72,14 +72,14 @@ draw_text (cairo_t *cr)
 
       cairo_rotate (cr, angle * G_PI / 180.);
 
-      /* Inform Pango to re-layout the text with the new transformation */
-      pango_cairo_update_layout (cr, layout);
+      /* Inform Pango2 to re-layout the text with the new transformation */
+      pango2_cairo_update_layout (cr, layout);
 
-      lines = pango_layout_get_lines (layout);
+      lines = pango2_layout_get_lines (layout);
 
-      pango_lines_get_size (lines, &width, &height);
-      cairo_move_to (cr, - ((double) width / PANGO_SCALE) / 2, - RADIUS);
-      pango_cairo_show_layout (cr, layout);
+      pango2_lines_get_size (lines, &width, &height);
+      cairo_move_to (cr, - ((double) width / PANGO2_SCALE) / 2, - RADIUS);
+      pango2_cairo_show_layout (cr, layout);
 
       cairo_restore (cr);
     }
@@ -113,7 +113,12 @@ main (int argc, char **argv)
   draw_text (cr);
   cairo_destroy (cr);
 
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
   status = cairo_surface_write_to_png (surface, filename);
+#else
+  status = CAIRO_STATUS_PNG_ERROR; /* Not technically correct, but... */
+#endif
+
   cairo_surface_destroy (surface);
 
   if (status != CAIRO_STATUS_SUCCESS)
diff --git a/docs/pango_layout.md b/docs/pango_layout.md
index a4d8e122b..e723c6592 100644
--- a/docs/pango_layout.md
+++ b/docs/pango_layout.md
@@ -4,75 +4,74 @@ Title: Complex layout
 
 # Complex layout
 
-The central object in high-level Pango API is [class@Pango.Layout].
+The central object in high-level Pango API is [class@Pango2.Layout].
 It is well-suited for breaking text into lines that fill a rectangular
 area, since that is commonly how paragraphs are formatted in books.
 But in real-life situations, text does not always fit in a box.
 Examples of more complicated requirements are fitting text around
 an image, or flowing text between multiple frames.
 
-For cases like these, it is better to use [class@Pango.LineBreaker]
-directly instead of `PangoLayout` (`PangoLayout` is using a line
-breaker internally). The way `PangoLineBreaker` works is to let
+For cases like these, it is better to use [class@Pango2.LineBreaker]
+directly instead of `Pango2Layout` (`Pango2Layout` is using a line
+breaker internally). The way `Pango2LineBreaker` works is to let
 applications access the formatted result one line at a time, place
 it, and change parameters such as the line width before requesting
 the next one.
 
-The following example shows how to use `PangoLineBreaker` to
+The following example shows how to use `Pango2LineBreaker` to
 produce an unusually shaped paragraph with a hole in the middle.
 
-## Using GtkLineBreaker
+## Using Pango2LineBreaker
 
 ```
-#include <pango/pango.h>
-#include <pango/pangocairo.h>
+#include <pango2/pangocairo.h>
 
-static PangoLines *
+static Pango2Lines *
 format_text (const char *text)
 {
-  PangoContext *context;
-  PangoLineBreaker *breaker;
-  PangoLines *lines;
+  Pango2Context *context;
+  Pango2LineBreaker *breaker;
+  Pango2Lines *lines;
   int x, y, width;
   int inc, m, w, w2;
 
-  context = pango_font_map_create_context (pango_font_map_get_default ());
-  breaker = pango_line_breaker_new (context);
+  context = pango2_context_new ();
+  breaker = pango2_line_breaker_new (context);
 
-  pango_line_breaker_add_text (breaker, text, -1, NULL);
+  pango2_line_breaker_add_text (breaker, text, -1, NULL);
 
-  lines = pango_lines_new ();
+  lines = pango2_lines_new ();
 
   m = 200;
   w = 10;
   w2 = -200;
   inc = 40;
 
-  y = 40 * PANGO_SCALE;
-  x = (m - w / 2) * PANGO_SCALE;
-  width = w * PANGO_SCALE;
+  y = 40 * PANGO2_SCALE;
+  x = (m - w / 2) * PANGO2_SCALE;
+  width = w * PANGO2_SCALE;
 
-  while (pango_line_breaker_has_line (breaker))
+  while (pango2_line_breaker_has_line (breaker))
     {
-      PangoLine *line;
-      PangoRectangle ext;
+      Pango2Line *line;
+      Pango2Rectangle ext;
       gboolean ltr;
 
-      line = pango_line_breaker_next_line (breaker,
+      line = pango2_line_breaker_next_line (breaker,
                                            x, width,
-                                           PANGO_WRAP_CHAR,
-                                           PANGO_ELLIPSIZE_NONE);
+                                           PANGO2_WRAP_CHAR,
+                                           PANGO2_ELLIPSIZE_NONE);
 
-      pango_line_get_extents (line, NULL, &ext);
-      line = pango_line_justify (line, width);
-      pango_lines_add_line (lines, line, x, y - ext.y);
+      pango2_line_get_extents (line, NULL, &ext);
+      line = pango2_line_justify (line, width);
+      pango2_lines_add_line (lines, line, x, y - ext.y);
 
-      ltr = pango_line_breaker_get_direction (breaker) == PANGO_DIRECTION_LTR;
+      ltr = pango2_line_breaker_get_direction (breaker) == PANGO2_DIRECTION_LTR;
 
-      if (w2 > 0 && ltr && x <= m * PANGO_SCALE)
-        x = (m + w2 / 2) * PANGO_SCALE;
-      else if (w2 > 0 && !ltr && x > m * PANGO_SCALE)
-        x = (m - w2 / 2) * PANGO_SCALE;
+      if (w2 > 0 && ltr && x <= m * PANGO2_SCALE)
+        x = (m + w2 / 2) * PANGO2_SCALE;
+      else if (w2 > 0 && !ltr && x > m * PANGO2_SCALE)
+        x = (m - w2 / 2) * PANGO2_SCALE;
       else
         {
           y += ext.height;
@@ -83,14 +82,14 @@ format_text (const char *text)
             inc = - inc;
 
           if (w2 > 0)
-            width = ((w - w2) / 2) * PANGO_SCALE;
+            width = ((w - w2) / 2) * PANGO2_SCALE;
           else
-            width = w * PANGO_SCALE;
+            width = w * PANGO2_SCALE;
 
           if (ltr)
-            x = (m - w / 2) * PANGO_SCALE;
+            x = (m - w / 2) * PANGO2_SCALE;
           else
-            x = (m + w / 2) * PANGO_SCALE;
+            x = (m + w / 2) * PANGO2_SCALE;
         }
     }
 
@@ -101,18 +100,18 @@ format_text (const char *text)
 }
 
 static void
-draw_lines (cairo_t *cr, PangoLines *lines)
+draw_lines (cairo_t *cr, Pango2Lines *lines)
 {
-  for (int i = 0; i < pango_lines_get_line_count (lines); i++)
+  for (int i = 0; i < pango2_lines_get_line_count (lines); i++)
     {
-      PangoLine *line = pango_lines_get_lines (lines)[i];
+      Pango2Line *line = pango2_lines_get_lines (lines)[i];
       int x, y;
 
-      pango_lines_get_line_position (lines, i, &x, &y);
+      pango2_lines_get_line_position (lines, i, &x, &y);
 
       cairo_save (cr);
-      cairo_move_to (cr, x / (double)PANGO_SCALE, y / (double)PANGO_SCALE);
-      pango_cairo_show_line (cr, line);
+      cairo_move_to (cr, x / (double)PANGO2_SCALE, y / (double)PANGO2_SCALE);
+      pango2_cairo_show_line (cr, line);
       cairo_restore (cr);
     }
 }
@@ -121,12 +120,13 @@ int
 main (int argc, char *argv[])
 {
   const char *filename;
-  PangoLines *lines;
+  Pango2Lines *lines;
   cairo_surface_t *surface;
   cairo_t *cr;
   char *text;
   gsize length;
   GError *error = NULL;
+  cairo_status_t status;
 
   if (argc != 3)
     {
@@ -152,8 +152,16 @@ main (int argc, char *argv[])
   draw_lines (cr, lines);
   g_object_unref (lines);
 
-  cairo_surface_write_to_png (surface, filename);
-  g_print ("Output written to %s\n", filename);
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+  status = cairo_surface_write_to_png (surface, filename);
+#else
+  status = CAIRO_STATUS_PNG_ERROR; /* Not technically correct, but... */
+#endif
+
+  if (status != CAIRO_STATUS_SUCCESS)
+    g_printerr ("Could not save png to '%s'\n", filename);
+  else
+    g_print ("Output written to %s\n", filename);
 
   cairo_surface_destroy (surface);
   cairo_destroy (cr);
diff --git a/docs/pango_user.md b/docs/pango_user.md
index c1e0f9857..760b20a8e 100644
--- a/docs/pango_user.md
+++ b/docs/pango_user.md
@@ -11,173 +11,121 @@ not support. And sometimes, it is more convenient to use a drawing API to render
 glyphs on-the-spot, maybe with fancy effects.
 
 For these cases, Pango provides the [class@Pango2.UserFace] implementation of
-`PangoFontFace` that uses callbacks for its functionality. This lets you embed
+`Pango2FontFace` that uses callbacks for its functionality. This lets you embed
 custom drawing into your text, fully integrated with Pango's text layout
 capabilities.
 
 ## A user font example
 
 ```
+#include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
-
-#include <pango/pangocairo.h>
-
-#define BULLET "•"
-#define HEART "♥"
-
-const char text[] =
-"The GNOME project provides three things:\n"
-"\n"
-"  • The GNOME desktop environment\n"
-"  • The GNOME development platform\n"
-"  • Planet GNOME\n"
-"  ♥ Lots of love";
-
-typedef struct {
-  double width, height;
-  const char *path;
-} MiniSvg;
-
-static MiniSvg GnomeFootLogo = {
-  96.2152, 118.26,
-  "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 "
-  "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 "
-  "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 "
-  "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 "
-  "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 "
-  "\0"
-};
-
-static void
-mini_svg_render (MiniSvg  *shape, cairo_t  *cr)
-{
-  double x, y;
-  char op[2];
-  int len;
-  double x1, y1, x2, y2, x3, y3;
-  const char *p;
-
-  cairo_get_current_point (cr, &x, &y);
-  cairo_translate (cr, x, y);
-
-  for (p = shape->path; sscanf (p, "%1s %n", op, &len), p += len, *p;)
-    switch (*op)
-      {
-      case 'M':
-        sscanf (p, "%lf,%lf %n", &x, &y, &len); p += len;
-        cairo_move_to (cr, x, y);
-        break;
-      case 'L':
-        sscanf (p, "%lf,%lf %n", &x, &y, &len); p += len;
-        cairo_line_to (cr, x, y);
-        break;
-      case 'C':
-        sscanf (p, "%lf,%lf %lf,%lf %lf,%lf %n", &x1, &y1, &x2, &y2, &x3, &y3, &len); p += len;
-        cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
-        break;
-      case 'z':
-        cairo_close_path (cr);
-        break;
-      default:
-        g_warning ("Invalid MiniSvg operation '%c'", *op);
-        break;
-      }
-
-  cairo_fill (cr);
-}
-
-static PangoLayout *
-get_layout (cairo_t *cr)
-{
-  PangoLayout *layout;
-  PangoAttrList *attrs;
-  PangoFontDescription *font_desc;
-  const char *p;
 
-  /* Create a PangoLayout, set the font and text */
-  layout = pango_cairo_create_layout (cr);
-  pango_layout_set_text (layout, text, -1);
+#include <pango2/pangocairo.h>
 
-  font_desc = pango_font_description_from_string ("Cantarell 12");
-  pango_layout_set_font_description (layout, font_desc);
-  pango_font_description_free (font_desc);
-
-  attrs = pango_attr_list_new ();
-
-  font_desc = pango_font_description_from_string ("Bullets 12");
-
-  for (p = text; (p = strstr (p, BULLET)); p += strlen (BULLET))
-    {
-      PangoAttribute *attr;
-
-      attr = pango_attr_font_desc_new (font_desc);
-      attr->start_index = p - text;
-      attr->end_index = attr->start_index + strlen (BULLET);
-      pango_attr_list_insert (attrs, attr);
-    }
-
-  for (p = text; (p = strstr (p, HEART)); p += strlen (HEART))
-    {
-      PangoAttribute *attr;
-
-      attr = pango_attr_font_desc_new (font_desc);
-      attr->start_index = p - text;
-      attr->end_index = attr->start_index + strlen (HEART);
-      pango_attr_list_insert (attrs, attr);
-    }
+static Pango2FontMap *fontmap;
 
-  pango_font_description_free (font_desc);
+#define END_GLYPH 0
+#define STROKE 126
+#define CLOSE 127
 
-  pango_layout_set_attributes (layout, attrs);
-  pango_attr_list_unref (attrs);
+/* Simple glyph definition: 1 - 15 means lineto (or moveto for first
+ * point) for one of the points on this grid:
+ *
+ *      1  2  3
+ *      4  5  6
+ *      7  8  9
+ * ----10 11 12----(baseline)
+ *     13 14 15
+ */
+typedef struct
+{
+  gunichar ucs4;
+  int width;
+  char data[16];
+} test_scaled_font_glyph_t;
+
+/* Simple glyph definition: 1 - 15 means lineto (or moveto for first
+ * point) for one of the points on this grid:
+ *
+ *      1  2  3
+ *      4  5  6
+ *      7  8  9
+ * ----10 11 12----(baseline)
+ *     13 14 15
+ */
+static const test_scaled_font_glyph_t glyphs [] = {
+  { 'a',  3, { 4, 6, 12, 10, 7, 9, STROKE, END_GLYPH } },
+  { 'c',  3, { 6, 4, 10, 12, STROKE, END_GLYPH } },
+  { 'e',  3, { 12, 10, 4, 6, 9, 7, STROKE, END_GLYPH } },
+  { 'f',  3, { 3, 2, 11, STROKE, 4, 6, STROKE, END_GLYPH } },
+  { 'g',  3, { 12, 10, 4, 6, 15, 13, STROKE, END_GLYPH } },
+  { 'h',  3, { 1, 10, STROKE, 7, 5, 6, 12, STROKE, END_GLYPH } },
+  { 'i',  1, { 1, 1, STROKE, 4, 10, STROKE, END_GLYPH } },
+  { 'l',  1, { 1, 10, STROKE, END_GLYPH } },
+  { 'n',  3, { 10, 4, STROKE, 7, 5, 6, 12, STROKE, END_GLYPH } },
+  { 'o',  3, { 4, 10, 12, 6, CLOSE, END_GLYPH } },
+  { 'p',  3, { 4, 10, 12, 6, CLOSE, 4, 13, STROKE, END_GLYPH } },
+  { 'r',  3, { 4, 10, STROKE, 7, 5, 6, STROKE, END_GLYPH } },
+  { 's',  3, { 6, 4, 7, 9, 12, 10, STROKE, END_GLYPH } },
+  { 't',  3, { 2, 11, 12, STROKE, 4, 6, STROKE, END_GLYPH } },
+  { 'u',  3, { 4, 10, 12, 6, STROKE, END_GLYPH } },
+  { 'y',  3, { 4, 10, 12, 6, STROKE, 12, 15, 13, STROKE, END_GLYPH } },
+  { 'z',  3, { 4, 6, 10, 12, STROKE, END_GLYPH } },
+  { ' ',  1, { END_GLYPH } },
+  { '-',  2, { 7, 8, STROKE, END_GLYPH } },
+  { '.',  1, { 10, 10, STROKE, END_GLYPH } },
+  { 0xe000, 3, { 3, 2, 11, STROKE, 4, 6, STROKE, 3, 3, STROKE, 6, 12, STROKE, END_GLYPH } }, /* fi */
+  { -1,  0, { END_GLYPH } },
+};
 
-  return layout;
-}
+const char text[] = "finally... pango user-font";
 
-static void
-measure_text (cairo_t *cr, int *width, int *height)
+static Pango2Layout *
+get_layout (void)
 {
-  PangoLayout *layout = get_layout (cr);
-  PangoLines *lines = pango_layout_get_lines (layout);
-  PangoRectangle ext;
+  Pango2Context *context;
+  Pango2Layout *layout;
+  Pango2FontDescription *desc;
 
-  pango_lines_get_extents (lines, NULL, &ext);
-  pango_extents_to_pixels (&ext, NULL);
+  /* Create a Pango2Layout, set the font and text */
+  context = pango2_context_new_with_font_map (fontmap);
+  layout = pango2_layout_new (context);
+  g_object_unref (context);
 
-  *width = ext.width + 20;
-  *height = ext.height + 20;
-}
+  pango2_layout_set_text (layout, text, -1);
 
-static void
-draw_text (cairo_t *cr)
-{
-  PangoLayout *layout = get_layout (cr);
-  PangoLines *lines = pango_layout_get_lines (layout);
+  desc = pango2_font_description_from_string ("Userfont 20");
+  pango2_layout_set_font_description (layout, desc);
+  pango2_font_description_free (desc);
 
-  cairo_move_to (cr, 10, 10);
-  pango_cairo_show_lines (cr, lines);
+  pango2_layout_write_to_file (layout, "out.layout");
 
-  g_object_unref (layout);
+  return layout;
 }
 
 static gboolean
-glyph_cb (PangoUserFace  *face,
+glyph_cb (Pango2UserFace  *face,
           hb_codepoint_t  unicode,
           hb_codepoint_t *glyph,
-          gpointer        data)
+          gpointer        user_data)
 {
-  if (unicode == 0x2022 || unicode == 0x2665)
+  test_scaled_font_glyph_t *glyphs = user_data;
+
+  for (int i = 0; glyphs[i].ucs4 != (gunichar) -1; i++)
     {
-      *glyph = unicode;
-      return TRUE;
+      if (glyphs[i].ucs4 == unicode)
+        {
+          *glyph = i;
+          return TRUE;
+        }
     }
 
   return FALSE;
 }
 
 static gboolean
-glyph_info_cb (PangoUserFace      *face,
+glyph_info_cb (Pango2UserFace      *face,
                int                 size,
                hb_codepoint_t      glyph,
                hb_glyph_extents_t *extents,
@@ -186,99 +134,179 @@ glyph_info_cb (PangoUserFace      *face,
                gboolean           *is_color,
                gpointer            user_data)
 {
-  if (glyph == 0x2022 || glyph == 0x2665)
+  test_scaled_font_glyph_t *glyphs = user_data;
+
+  extents->x_bearing = 0;
+  extents->y_bearing = 0.75 * size;
+  extents->width = glyphs[glyph].width / 4.0 * size;
+  extents->height = - size;
+
+  *h_advance = *v_advance = glyphs[glyph].width / 4.0 * size;
+
+  *is_color = FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+shape_cb (Pango2UserFace       *face,
+          int                  size,
+          const char          *text,
+          int                  length,
+          const Pango2Analysis *analysis,
+          Pango2GlyphString    *glyphs,
+          Pango2ShapeFlags      flags,
+          gpointer             user_data)
+{
+  int n_chars;
+  const char *p;
+  int cluster = 0;
+  int i, j;
+  int last_cluster;
+  gboolean is_color;
+  hb_glyph_extents_t ext;
+  hb_position_t dummy;
+
+  n_chars = g_utf8_strlen (text, length);
+
+  pango2_glyph_string_set_size (glyphs, n_chars);
+
+  last_cluster = -1;
+
+  p = text;
+  j = 0;
+  for (i = 0; i < n_chars; i++)
     {
-      extents->x_bearing = 0;
-      extents->y_bearing = - size;
-      extents->width = size;
-      extents->height = size;
+      gunichar wc;
+      Pango2Glyph glyph = 0;
+      Pango2Rectangle logical_rect;
+
+      wc = g_utf8_get_char (p);
+
+      if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK)
+        cluster = p - text;
+
+      /* Handle the fi ligature */
+      if (p[0] == 'f' && p[1] == 'i')
+        {
+          p = g_utf8_next_char (p);
+          i++;
+          glyph_cb (face, 0xe000, &glyph, user_data);
+        }
+      else if (pango2_is_zero_width (wc))
+        glyph = PANGO2_GLYPH_EMPTY;
+      else if (!glyph_cb (face, wc, &glyph, user_data))
+        glyph = PANGO2_GET_UNKNOWN_GLYPH (wc);
+
+      glyph_info_cb (face, size, glyph, &ext, &dummy, &dummy, &is_color, user_data);
+      pango2_font_get_glyph_extents (pango2_analysis_get_font (analysis), glyph, NULL, &logical_rect);
+
+      glyphs->glyphs[j].glyph = glyph;
+
+      glyphs->glyphs[j].attr.is_cluster_start = cluster != last_cluster;
+      glyphs->glyphs[j].attr.is_color = is_color;
 
-      *h_advance = size;
-      *v_advance = size;
-      *is_color = glyph == 0x2665;
+      glyphs->glyphs[j].geometry.x_offset = 0;
+      glyphs->glyphs[j].geometry.y_offset = 0;
+      glyphs->glyphs[j].geometry.width = logical_rect.width;
 
-      return TRUE;
+      glyphs->log_clusters[j] = cluster;
+
+      j++;
+
+      last_cluster = cluster;
+
+      p = g_utf8_next_char (p);
     }
 
-  return FALSE;
+  glyphs->num_glyphs = j;
+
+#if 0
+  /* FIXME export this */
+  if (analysis->level & 1)
+    pango2_glyph_string_reverse_range (glyphs, 0, glyphs->num_glyphs);
+#endif
+
+  return TRUE;
 }
 
 static gboolean
-font_info_cb (PangoUserFace     *face,
+font_info_cb (Pango2UserFace     *face,
               int                size,
               hb_font_extents_t *extents,
               gpointer           user_data)
 {
-  extents->ascender = size;
-  extents->descender = 0;
+  extents->ascender = 0.75 * size;
+  extents->descender = - 0.25 * size;
   extents->line_gap = 0;
 
   return TRUE;
 }
 
 static gboolean
-render_cb (PangoUserFace  *face,
+render_cb (Pango2UserFace  *face,
            int             size,
            hb_codepoint_t  glyph,
            gpointer        user_data,
            const char     *backend_id,
            gpointer        backend_data)
 {
+  test_scaled_font_glyph_t *glyphs = user_data;
   cairo_t *cr = backend_data;
+  const char *data;
+  div_t d;
+  double x, y;
 
   if (strcmp (backend_id, "cairo") != 0)
     return FALSE;
 
-  if (glyph == 0x2022)
-    {
-      MiniSvg *shape = &GnomeFootLogo;
-
-      cairo_move_to (cr, 0, -1);
-      cairo_scale (cr, 1. / shape->width, 1. / shape->height);
+  cairo_set_line_width (cr, 0.1);
+  cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+  cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
 
-      mini_svg_render (shape, cr);
-
-      return TRUE;
-    }
-  else if (glyph == 0x2665)
+  data = glyphs[glyph].data;
+  for (int i = 0; data[i] != END_GLYPH; i++)
     {
-      cairo_set_source_rgb (cr, 1., 0., 0.);
-
-      cairo_move_to (cr, .5, .0);
-      cairo_line_to (cr, .9, -.4);
-      cairo_curve_to (cr, 1.1, -.8, .5, -.9, .5, -.5);
-      cairo_curve_to (cr, .5, -.9, -.1, -.8, .1, -.4);
-      cairo_close_path (cr);
-      cairo_fill (cr);
-
-      return TRUE;
+      switch (data[i])
+        {
+        case STROKE:
+          cairo_new_sub_path (cr);
+          break;
+
+        case CLOSE:
+          cairo_close_path (cr);
+          break;
+
+        default:
+          d = div (data[i] - 1, 3);
+          x = d.rem / 4.0 + 0.125;
+          y = d.quot / 5.0 + 0.4 - 1.0;
+          cairo_line_to (cr, x, y);
+        }
     }
 
-  return FALSE;
+  cairo_stroke (cr);
+
+  return TRUE;
 }
 
 static void
-setup_fontmap (void)
+setup_fontmap (Pango2FontMap *fontmap)
 {
-  PangoFontMap *fontmap = pango_font_map_get_default ();
-  PangoFontDescription *desc;
-  PangoUserFace *face;
-
-  desc = pango_font_description_new ();
-  pango_font_description_set_family (desc, "Bullets");
+  Pango2FontDescription *desc;
+  Pango2UserFace *face;
 
-  /* Create our fancy user font, "Bullets Black" */
-  face = pango_user_face_new (font_info_cb,
+  desc = pango2_font_description_new ();
+  pango2_font_description_set_family (desc, "Userfont");
+  face = pango2_user_face_new (font_info_cb,
                               glyph_cb,
                               glyph_info_cb,
-                              NULL,
+                              shape_cb,
                               render_cb,
-                              NULL, NULL, "Black", desc);
-
-  /* And add it to the default fontmap */
-  pango_font_map_add_face (fontmap, PANGO_FONT_FACE (face));
-
-  pango_font_description_free (desc);
+                              (gpointer) glyphs, NULL,
+                              "Black", desc);
+  pango2_font_map_add_face (fontmap, PANGO2_FONT_FACE (face));
+  pango2_font_description_free (desc);
 }
 
 int
@@ -288,36 +316,47 @@ main (int argc, char **argv)
   char *filename;
   cairo_status_t status;
   cairo_surface_t *surface;
-  int width, height;
+  Pango2Layout *layout;
+  Pango2Rectangle ext;
 
   if (argc != 2)
     {
-      g_printerr ("Usage: cairoshape OUTPUT_FILENAME\n");
+      g_printerr ("Usage: userfont OUTPUT_FILENAME\n");
       return 1;
     }
 
   filename = argv[1];
 
-  setup_fontmap ();
+  fontmap = PANGO2_FONT_MAP (pango2_font_map_new_default ());
+  setup_fontmap (PANGO2_FONT_MAP (fontmap));
 
-  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
-  cr = cairo_create (surface);
-  measure_text (cr, &width, &height);
-  cairo_destroy (cr);
-  cairo_surface_destroy (surface);
+  layout = get_layout ();
+
+  pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
+  pango2_extents_to_pixels (&ext, NULL);
 
   /* Now create the final surface and draw to it. */
-  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ext.width + 20, ext.height + 20);
   cr = cairo_create (surface);
 
   cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
   cairo_paint (cr);
   cairo_set_source_rgb (cr, 0.0, 0.0, 0.5);
-  draw_text (cr);
+
+  cairo_move_to (cr, 10, 10);
+  pango2_cairo_show_layout (cr, layout);
+
   cairo_destroy (cr);
 
+  g_object_unref (layout);
+
   /* Write out the surface as PNG */
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
   status = cairo_surface_write_to_png (surface, filename);
+#else
+  status = CAIRO_STATUS_PNG_ERROR; /* Not technically correct, but... */
+#endif
+
   cairo_surface_destroy (surface);
 
   if (status != CAIRO_STATUS_SUCCESS)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]