diff options
Diffstat (limited to 'pango2/pango-hbface.c')
-rw-r--r-- | pango2/pango-hbface.c | 519 |
1 files changed, 313 insertions, 206 deletions
diff --git a/pango2/pango-hbface.c b/pango2/pango-hbface.c index 5f8486b2..dbe68e17 100644 --- a/pango2/pango-hbface.c +++ b/pango2/pango-hbface.c @@ -279,38 +279,6 @@ ensure_faceid (Pango2HbFace *self) g_free (str); } -static const char * -style_from_font_description (const Pango2FontDescription *desc) -{ - Pango2Style style = pango2_font_description_get_style (desc); - Pango2Weight weight = pango2_font_description_get_weight (desc); - - switch (style) - { - case PANGO2_STYLE_ITALIC: - if (weight == PANGO2_WEIGHT_BOLD) - return "Bold Italic"; - else - return "Italic"; - break; - case PANGO2_STYLE_OBLIQUE: - if (weight == PANGO2_WEIGHT_BOLD) - return "Bold Oblique"; - else - return "Oblique"; - break; - case PANGO2_STYLE_NORMAL: - if (weight == PANGO2_WEIGHT_BOLD) - return "Bold"; - else - return "Regular"; - break; - default: ; - } - - return NULL; -} - /* }}} */ /* {{{ Pango2FontFace implementation */ @@ -660,7 +628,7 @@ pango2_hb_face_set_matrix (Pango2HbFace *self, } /* }}} */ - /* {{{ Public API */ + /* {{{ Public API */ /** * pango2_hb_face_new_from_hb_face: @@ -783,179 +751,6 @@ pango2_hb_face_new_from_file (const char *file, } /** - * pango2_hb_face_new_synthetic: - * @face: a `Pango2HbFace` - * @transform: (nullable): the transform to apply - * @embolden: `TRUE` to render the font bolder - * @name: (nullable): name for the face - * @description: a `Pango2FontDescription` to override fields from @face's description - * - * Creates a new `Pango2HbFace` that is a synthetic variant of @face. - * - * Here, 'synthetic' means that the variant is implemented by rendering - * the glyphs differently, not by using data from the original @face. - * See [method@Pango2.HbFace.new_instance] for that. - * - * @transform can be used to specify a non-trivial font matrix for creating - * synthetic italics or synthetic condensed variants of an existing face. - * - * If @embolden is `TRUE`, Pango will render the glyphs bolder, creating - * a synthetic bold variant of the face. - * - * If a @name is not specified, the name for the face will be derived - * from the @description. - * - * Apart from setting the style that this face will be used for, - * @description can provide an alternative family name. This can - * be used to create generic aliases such as 'sans' or 'monospace'. - * - * Note that only the following fields in @description should be set: - * - * + style or stretch, to indicate a transformed style - * + weight, to indicate a bolder weight - * + family, to provide an alternative family name - * - * [method@Pango2.FontFace.is_synthesized] will return `TRUE` for objects - * created by this function. - * - * Returns: (transfer full): a newly created `Pango2HbFace` - */ -Pango2HbFace * -pango2_hb_face_new_synthetic (Pango2HbFace *face, - const Pango2Matrix *transform, - gboolean embolden, - const char *name, - const Pango2FontDescription *description) -{ - Pango2HbFace *self; - Pango2FontDescription *desc; - - g_return_val_if_fail (PANGO2_IS_HB_FACE (face), NULL); - g_return_val_if_fail (description != NULL, NULL); - g_return_val_if_fail ((pango2_font_description_get_set_fields (description) & - ~(PANGO2_FONT_MASK_FAMILY| - PANGO2_FONT_MASK_STYLE| - PANGO2_FONT_MASK_STRETCH| - PANGO2_FONT_MASK_WEIGHT)) == 0, NULL); - - self = g_object_new (PANGO2_TYPE_HB_FACE, NULL); - - self->file = g_strdup (face->file); - if (face->face) - self->face = hb_face_reference (face->face); - - self->index = face->index; - self->instance_id = face->instance_id; - self->variations = g_memdup2 (face->variations, sizeof (hb_variation_t) * face->n_variations); - self->n_variations = face->n_variations; - - if (transform) - pango2_hb_face_set_matrix (self, transform); - - self->embolden = embolden; - self->synthetic = self->embolden || (self->transform != NULL); - - desc = pango2_font_description_copy (PANGO2_FONT_FACE (face)->description); - pango2_font_description_merge (desc, description, TRUE); - - if (!name) - name = style_from_font_description (desc); - - set_name_and_description (self, name, desc); - - pango2_hb_face_set_language_set (self, face->languages); - - pango2_font_description_free (desc); - - return self; -} - -/** - * pango2_hb_face_new_instance: - * @face: a `Pango2HbFace` - * @variations: (nullable) (array length=n_variations): font variations to apply - * @n_variations: length of @variations - * @name: (nullable): name for the face - * @description: a `Pango2FontDescription` to override fields from @face's description - * - * Creates a new `Pango2HbFace` that is a variant of @face. - * - * The @variations provide values for variation axes of @face. Axes that - * are not included in @variations will keep the values they have in @face. - * @variations that refer to axes that the face does not have are ignored. - * - * Conceptually, this is similar to a named instance of the face, except - * that the mapping of the name to a set of coordinates on the variation - * axes is provided externally, and not by the face itself. - * - * If a @name is not specified, the name for the face will be derived - * from the @description. - * - * Apart from setting the style that this face will be used for, - * @description can provide an alternative family name. This can - * be used to create generic aliases such as 'sans' or 'monospace'. - * - * Note that only the following fields in @description should be set: - * - style or stretch, to indicate a transformed style - * - weight, to indicate a bolder weight - * - family, to provide an alternative family name - * - * Returns: (transfer full): a newly created `Pango2HbFace` - */ -Pango2HbFace * -pango2_hb_face_new_instance (Pango2HbFace *face, - const hb_variation_t *variations, - unsigned int n_variations, - const char *name, - const Pango2FontDescription *description) -{ - Pango2HbFace *self; - Pango2FontDescription *desc; - - g_return_val_if_fail (PANGO2_IS_HB_FACE (face), NULL); - g_return_val_if_fail (description != NULL, NULL); - g_return_val_if_fail ((pango2_font_description_get_set_fields (description) & - ~(PANGO2_FONT_MASK_FAMILY| - PANGO2_FONT_MASK_STYLE| - PANGO2_FONT_MASK_STRETCH| - PANGO2_FONT_MASK_WEIGHT)) == 0, NULL); - - self = g_object_new (PANGO2_TYPE_HB_FACE, NULL); - - self->file = g_strdup (face->file); - if (face->face) - self->face = hb_face_reference (face->face); - - self->index = face->index; - self->instance_id = face->instance_id; - - if (face->transform) - { - self->transform = g_memdup2 (face->transform, sizeof (Pango2Matrix)); - self->x_scale = face->x_scale; - self->y_scale = face->y_scale; - } - - self->embolden = face->embolden; - self->synthetic = self->embolden || (self->transform != NULL); - - self->variations = g_memdup2 (variations, sizeof (hb_variation_t) * n_variations); - self->n_variations = n_variations; - - desc = pango2_font_description_copy (PANGO2_FONT_FACE (face)->description); - pango2_font_description_merge (desc, description, TRUE); - - if (!name) - name = style_from_font_description (desc); - - set_name_and_description (self, name, desc); - - pango2_font_description_free (desc); - - return self; -} - -/** * pango2_hb_face_get_hb_face: * @self: a `Pango2HbFace` * @@ -1083,5 +878,317 @@ pango2_hb_face_get_transform (Pango2HbFace *self) } /* }}} */ +/* {{{ Pango2HbFaceBuilder */ + +/** + * Pango2HbFaceBuilder: + * + * An auxiliary object to build `Pango2HbFace` objects. + */ + +struct _Pango2HbFaceBuilder { + hb_face_t *hb_face; + Pango2HbFace *face; + Pango2Matrix *transform; + gboolean embolden; + int instance_id; + hb_variation_t *variations; + unsigned int n_variations; + char *name; + Pango2FontDescription *description; +}; + +G_DEFINE_BOXED_TYPE (Pango2HbFaceBuilder, pango2_hb_face_builder, + pango2_hb_face_builder_copy, + pango2_hb_face_builder_free); + +static Pango2HbFaceBuilder * +face_builder_new (void) +{ + Pango2HbFaceBuilder *builder; + + builder = g_new (Pango2HbFaceBuilder, 1); + builder->hb_face = NULL; + builder->face = NULL; + builder->transform = NULL; + builder->embolden = FALSE; + builder->instance_id = 0; + builder->variations = NULL; + builder->n_variations = 0; + builder->name = NULL; + builder->description = NULL; + + return builder; +} + +/** + * pango2_hb_face_builder_copy: + * @src: a `Pango2HbFaceBuilder` + * + * Copy a `Pango2HbFaceBuilder`. + * + * Returns: (transfer full): a copy of @src + */ +Pango2HbFaceBuilder * +pango2_hb_face_builder_copy (const Pango2HbFaceBuilder *src) +{ + Pango2HbFaceBuilder *builder; + + builder = face_builder_new (); + if (src->face) + builder->face = g_object_ref (src->face); + if (src->hb_face) + builder->hb_face = hb_face_reference (src->hb_face); + builder->transform = g_memdup2 (src->transform, sizeof (Pango2Matrix)); + builder->embolden = src->embolden; + builder->instance_id = src->instance_id; + builder->variations = g_memdup2 (src->variations, sizeof (hb_variation_t) * src->n_variations); + builder->n_variations = src->n_variations; + builder->name = g_strdup (src->name); + if (src->description) + builder->description = pango2_font_description_copy_static (src->description); + + return builder; +} + +/** + * pango2_hb_face_builder_free: + * @builder: a `Pango2HbFaceBuilder` + * + * Frees the `PangoHbFaceBuilder`. + */ +void +pango2_hb_face_builder_free (Pango2HbFaceBuilder *builder) +{ + if (builder->hb_face) + hb_face_destroy (builder->hb_face); + if (builder->face) + g_object_unref (builder->face); + g_free (builder->transform); + g_free (builder->variations); + g_free (builder->name); + if (builder->description) + pango2_font_description_free (builder->description); + + g_free (builder); +} + +/** + * pango2_hb_face_builder_new_for_hb_face: + * @hb_face: a `hb_face_t` + * + * Creates a new `Pango2HbFaceBuilder` that will + * produce `Pango2HbFace` objects wrapping @hb_face. + * + * Returns: (transfer full): a new `Pango2HbFaceBuilder` + */ +Pango2HbFaceBuilder * +pango2_hb_face_builder_new_for_hb_face (hb_face_t *hb_face) +{ + Pango2HbFaceBuilder *builder; + + g_return_val_if_fail (hb_face_is_immutable (hb_face), NULL); + + builder = face_builder_new (); + builder->hb_face = hb_face_reference (hb_face); + + return builder; +} + +/** + * pango2_hb_face_builder_new: + * @face: a `Pango2HbFace` + * + * Creates a new `Pango2HbFaceBuilder` that will + * produce `Pango2HbFace` objects wrapping @face. + * + * Returns: (transfer full): a new `Pango2HbFaceBuilder` + */ +Pango2HbFaceBuilder * +pango2_hb_face_builder_new (Pango2HbFace *face) +{ + Pango2FontFace *font_face = PANGO2_FONT_FACE (face); + Pango2HbFaceBuilder *builder; + + g_return_val_if_fail (PANGO2_IS_HB_FACE (face), NULL); + + builder = face_builder_new (); + builder->face = g_object_ref (face); + if (face->transform) + { + builder->transform = g_memdup2 (face->transform, sizeof (Pango2Matrix)); + pango2_matrix_scale (builder->transform, face->x_scale, face->y_scale); + } + builder->embolden = face->embolden; + builder->instance_id = face->instance_id; + builder->variations = g_memdup2 (face->variations, sizeof (hb_variation_t) * face->n_variations); + builder->n_variations = face->n_variations; + builder->name = g_strdup (font_face->name); + builder->description = pango2_font_description_copy_static (font_face->description); + + return builder; +} + +/** + * pango2_hb_face_builder_get_face: + * @builder: a `Pango2HbFaceBuilder` + * + * Gets a new `Pango2HbFace` instance with the current builder data. + * + * Returns: (transfer full): a new `Pango2HbFace` + */ +Pango2HbFace * +pango2_hb_face_builder_get_face (Pango2HbFaceBuilder *builder) +{ + Pango2HbFace *self; + + self = g_object_new (PANGO2_TYPE_HB_FACE, NULL); + if (builder->face) + { + self->file = g_strdup (builder->face->file); + self->index = builder->face->index; + self->instance_id = builder->face->instance_id; + if (builder->face->face) + self->face = hb_face_reference (builder->face->face); + pango2_hb_face_set_language_set (self, builder->face->languages); + } + else if (builder->hb_face) + { + self->face = hb_face_reference (builder->hb_face); + } + + self->instance_id = builder->instance_id; + + if (builder->transform) + pango2_hb_face_set_matrix (self, builder->transform); + + self->embolden = builder->embolden; + self->synthetic = self->embolden || (self->transform != NULL); + + self->variations = g_memdup2 (builder->variations, sizeof (hb_variation_t) * builder->n_variations); + self->n_variations = builder->n_variations; + + set_name_and_description (self, builder->name, builder->description); + + return self; +} + +/** + * pango2_hb_face_builder_set_instance_id: + * @builder: a `Pango2HbFaceBuilder` + * @instance_id: named instance id, or -1 for the default instance + * or -2 for no instance + * + * Sets the instance ID to use for the face. + */ +void +pango2_hb_face_builder_set_instance_id (Pango2HbFaceBuilder *builder, + int instance_id) +{ + g_return_if_fail (instance_id >= -2); + + builder->instance_id = instance_id; +} + +/** + * pango2_hb_face_builder_set_name: + * @builder: a `Pango2HbFaceBuilder` + * @name: (nullable): name for the face + * + * Sets the name to use for the face. + * + * If @name is `NULL`, the name of the underlying object is used. + */ +void +pango2_hb_face_builder_set_name (Pango2HbFaceBuilder *builder, + const char *name) +{ + g_free (builder->name); + builder->name = g_strdup (name); +} + +/** + * pango2_hb_face_builder_set_description: + * @builder: a `Pango2HbFaceBuilder` + * @desc: (nullable): `Pango2FontDescription` for the face + * + * Sets the description to use for the face. + * + * If @desc is `NULL`, the description of the underlying object is used. + */ +void +pango2_hb_face_builder_set_description (Pango2HbFaceBuilder *builder, + const Pango2FontDescription *desc) +{ + g_return_if_fail (desc == NULL || + (pango2_font_description_get_set_fields (desc) & + ~(PANGO2_FONT_MASK_FAMILY| + PANGO2_FONT_MASK_STYLE| + PANGO2_FONT_MASK_STRETCH| + PANGO2_FONT_MASK_WEIGHT)) == 0); + + if (builder->description) + pango2_font_description_free (builder->description); + + if (builder->face) + builder->description = pango2_font_description_copy (PANGO2_FONT_FACE (builder->face)->description); + + if (desc) + { + if (builder->description) + pango2_font_description_merge (builder->description, desc, TRUE); + else + builder->description = pango2_font_description_copy (desc); + } +} + +/** + * pango2_hb_face_builder_set_transform: + * @builder: a `Pango2HbFaceBuilder` + * @transform: (nullable): `Pango2Matrix` for the font matrix + * + * Sets the font matrix to use for the face. + */ +void +pango2_hb_face_builder_set_transform (Pango2HbFaceBuilder *builder, + const Pango2Matrix *transform) +{ + g_free (builder->transform); + builder->transform = g_memdup2 (transform, sizeof (Pango2Matrix)); +} + +/** + * pango2_hb_face_builder_set_embolden: + * @builder: a `Pango2HbFaceBuilder` + * @embolden: `TRUE` to render the font bolder + * + * Sets whether the face should be artificially emboldened. + */ +void +pango2_hb_face_builder_set_embolden (Pango2HbFaceBuilder *builder, + gboolean embolden) +{ + builder->embolden = embolden; +} + +/** + * pango2_hb_face_builder_set_variations: + * @builder: a `Pango2HbFaceBuilder` + * @variations: (nullable) (array length=n_variations): font variations to apply + * @n_variations: length of @variations + * + * Sets variations to use for the face. + */ +void +pango2_hb_face_builder_set_variations (Pango2HbFaceBuilder *builder, + const hb_variation_t *variations, + unsigned int n_variations) +{ + g_free (builder->variations); + builder->variations = g_memdup2 (variations, sizeof (hb_variation_t) * n_variations); + builder->n_variations = n_variations; +} + +/* }}} */ /* vim:set foldmethod=marker expandtab: */ |