summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-09-02 21:02:18 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-09-02 21:02:18 +0100
commitfcbb288e7cf2f5914c0d2b66ee6d81b694de6de6 (patch)
treef93c69c5003e9a2f27bf87cf6e2ccbba54869f68
parent2c03dfa0b406565fca798214a842bac69b042017 (diff)
[script] Attempt to select a font if ! CAIRO_HAS_FT_FONT
In order to enable replay of traces on machines that do not use FreeType as the native font system, we need to convert a type42 font into something similar. Currently the fallback is just to select a font with the same name - this ignores weight and slant, and many other details.
-rw-r--r--util/cairo-script/cairo-script-operators.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index de5dd40c..684c7212 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -2029,6 +2029,108 @@ _ft_type42_create (csi_t *ctx,
#define _ft_type42_create(ctx, font, face_out) CSI_INT_STATUS_UNSUPPORTED
#endif
+static char *
+_fc_strcpy (csi_t *ctx, const char *str)
+{
+ char *ret;
+ int len;
+
+ ret = strchr (str, ':');
+ if (ret != NULL)
+ len = ret - str;
+ else
+ len = strlen (str);
+
+ ret = _csi_alloc (ctx, len+1);
+ if (_csi_unlikely (ret == NULL))
+ return NULL;
+
+ memcpy (ret, str, len);
+ ret[len] = '\0';
+
+ return ret;
+}
+static csi_status_t
+_ft_fallback_create_for_pattern (csi_t *ctx,
+ csi_string_t *string,
+ cairo_font_face_t **font_face_out)
+{
+ char *str, *name;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ str = string->string;
+#if 0
+ name = strstr (str, "fullname=");
+ if (name != NULL)
+ str = name + 9;
+#endif
+
+ name = _fc_strcpy (ctx, str);
+ if (_csi_unlikely (name == NULL))
+ return _csi_error (CSI_STATUS_NO_MEMORY);
+
+ /* create a dummy context to choose a font */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_select_font_face (cr, name,
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ *font_face_out = cairo_font_face_reference (cairo_get_font_face (cr));
+ cairo_destroy (cr);
+
+ _csi_free (ctx, name);
+
+ return CSI_STATUS_SUCCESS;
+}
+
+static csi_status_t
+_ft_type42_fallback_create (csi_t *ctx,
+ csi_dictionary_t *font,
+ cairo_font_face_t **font_face_out)
+{
+ csi_object_t key;
+ csi_status_t status;
+
+ /* attempt to select a similar font */
+
+ /* two basic sub-types, either an FcPattern or embedded font */
+ status = csi_name_new_static (ctx, &key, "pattern");
+ if (_csi_unlikely (status))
+ return status;
+
+ if (csi_dictionary_has (font, key.datum.name)) {
+ csi_object_t obj;
+ int type;
+
+ status = csi_dictionary_get (ctx, font, key.datum.name, &obj);
+ if (_csi_unlikely (status))
+ return status;
+
+ type = csi_object_get_type (&obj);
+ switch (type) {
+ case CSI_OBJECT_TYPE_FILE:
+ status = _csi_file_as_string (ctx, obj.datum.file, &obj);
+ if (_csi_unlikely (status))
+ return status;
+ break;
+ case CSI_OBJECT_TYPE_STRING:
+ obj.datum.object->ref++;
+ break;
+ default:
+ return _csi_error (CSI_STATUS_INVALID_SCRIPT);
+ }
+
+ return _ft_fallback_create_for_pattern (ctx,
+ obj.datum.string,
+ font_face_out);
+ }
+
+ return CSI_INT_STATUS_UNSUPPORTED;
+}
+
static csi_status_t
_font_type42 (csi_t *ctx, csi_dictionary_t *font, cairo_font_face_t **font_face)
{
@@ -2038,6 +2140,10 @@ _font_type42 (csi_t *ctx, csi_dictionary_t *font, cairo_font_face_t **font_face)
if (_csi_likely (status != CSI_INT_STATUS_UNSUPPORTED))
return status;
+ status = _ft_type42_fallback_create (ctx, font, font_face);
+ if (_csi_likely (status != CSI_INT_STATUS_UNSUPPORTED))
+ return status;
+
return _csi_error (CSI_STATUS_INVALID_SCRIPT);
}