Imported Upstream version 2.3.1
[platform/upstream/harfbuzz.git] / util / helper-cairo.cc
index 8f30eea..b4f94a9 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <cairo-ft.h>
 #include <hb-ft.h>
+#include FT_MULTIPLE_MASTERS_H
 
 #include "helper-cairo-ansi.hh"
 #ifdef CAIRO_HAS_SVG_SURFACE
@@ -63,11 +64,13 @@ _cairo_eps_surface_create_for_stream (cairo_write_func_t  write_func,
 
 static FT_Library ft_library;
 
+#ifdef HAVE_ATEXIT
 static inline
-void free_ft_library (void)
+void free_ft_library ()
 {
   FT_Done_FreeType (ft_library);
 }
+#endif
 
 cairo_scaled_font_t *
 helper_cairo_create_scaled_font (const font_options_t *font_opts)
@@ -76,8 +79,9 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts)
 
   cairo_font_face_t *cairo_face;
   /* We cannot use the FT_Face from hb_font_t, as doing so will confuse hb_font_t because
-   * cairo will reset the face size.  As such, create new face... */
-  FT_Face ft_face = NULL;//hb_ft_font_get_face (font);
+   * cairo will reset the face size.  As such, create new face...
+   * TODO Perhaps add API to hb-ft to encapsulate this code. */
+  FT_Face ft_face = nullptr;//hb_ft_font_get_face (font);
   if (!ft_face)
   {
     if (!ft_library)
@@ -87,10 +91,16 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts)
       atexit (free_ft_library);
 #endif
     }
-    FT_New_Face (ft_library,
-                font_opts->font_file,
-                font_opts->face_index,
-                &ft_face);
+
+    unsigned int blob_length;
+    const char *blob_data = hb_blob_get_data (font_opts->blob, &blob_length);
+
+    if (FT_New_Memory_Face (ft_library,
+                           (const FT_Byte *) blob_data,
+                            blob_length,
+                           font_opts->face_index,
+                           &ft_face))
+      fail (false, "FT_New_Memory_Face fail");
   }
   if (!ft_face)
   {
@@ -100,7 +110,25 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts)
                                             CAIRO_FONT_WEIGHT_NORMAL);
   }
   else
-    cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
+  {
+#ifdef HAVE_FT_SET_VAR_BLEND_COORDINATES
+    unsigned int num_coords;
+    const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
+    if (num_coords)
+    {
+      FT_Fixed *ft_coords = (FT_Fixed *) calloc (num_coords, sizeof (FT_Fixed));
+      if (ft_coords)
+      {
+       for (unsigned int i = 0; i < num_coords; i++)
+         ft_coords[i] = coords[i] << 2;
+       FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
+       free (ft_coords);
+      }
+    }
+#endif
+
+    cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, font_opts->ft_load_flags);
+  }
   cairo_matrix_t ctm, font_matrix;
   cairo_font_options_t *font_options;
 
@@ -307,7 +335,7 @@ const char *helper_cairo_supported_formats[] =
     "eps",
    #endif
   #endif
-  NULL
+  nullptr
 };
 
 cairo_t *
@@ -319,12 +347,12 @@ helper_cairo_create_context (double w, double h,
   cairo_surface_t *(*constructor) (cairo_write_func_t write_func,
                                   void *closure,
                                   double width,
-                                  double height) = NULL;
+                                  double height) = nullptr;
   cairo_surface_t *(*constructor2) (cairo_write_func_t write_func,
                                    void *closure,
                                    double width,
                                    double height,
-                                   cairo_content_t content) = NULL;
+                                   cairo_content_t content) = nullptr;
 
   const char *extension = out_opts->output_format;
   if (!extension) {
@@ -453,8 +481,8 @@ helper_cairo_line_from_buffer (helper_cairo_line_t *l,
   memset (l, 0, sizeof (*l));
 
   l->num_glyphs = hb_buffer_get_length (buffer);
-  hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, NULL);
-  hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, NULL);
+  hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, nullptr);
+  hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, nullptr);
   l->glyphs = cairo_glyph_allocate (l->num_glyphs + 1);
 
   if (text) {