/** * SECTION:cairo-user-fonts * @Title:User Fonts * @Short_Description: Font support with font data provided by the user * * The user-font feature allows the cairo user to provide drawings for glyphs * in a font. This is most useful in implementing fonts in non-standard * formats, like SVG fonts and Flash fonts, but can also be used by games and * other application to draw "funky" fonts.
**/
/** * CAIRO_HAS_USER_FONT: * * Defined if the user font backend is available. * This macro can be used to conditionally compile backend-specific code. * The user font backend is always built in versions of cairo that support * this feature (1.8 and later). * * Since: 1.8
**/
/* Set to true after first scaled font is created. At that point,
* the scaled_font_methods cannot change anymore. */
cairo_bool_t immutable;
cairo_bool_t has_color;
cairo_user_scaled_font_methods_t scaled_font_methods;
} cairo_user_font_face_t;
/* space to compute extents in, and factors to convert back to user space */
cairo_matrix_t extent_scale; double extent_x_scale; double extent_y_scale;
/* multiplier for metrics hinting */ double snap_x_scale; double snap_y_scale;
/* Compute extents.x/y/width/height from recording_surface, * in font space.
*/
status = _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface,
&bbox,
&scaled_font->extent_scale); if (unlikely (status)) return status;
/* TODO * extend the glyph cache to support argb glyphs. * need to figure out the semantics and interaction with subpixel * rendering first.
*/
/* Only one info type at a time handled in this function */
assert (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE || info == CAIRO_SCALED_GLYPH_INFO_SURFACE);
if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) {
format = CAIRO_FORMAT_ARGB32;
} else { switch (scaled_font->base.options.antialias) { default: case CAIRO_ANTIALIAS_DEFAULT: case CAIRO_ANTIALIAS_FAST: case CAIRO_ANTIALIAS_GOOD: case CAIRO_ANTIALIAS_GRAY:
format = CAIRO_FORMAT_A8; break; case CAIRO_ANTIALIAS_NONE:
format = CAIRO_FORMAT_A1; break; case CAIRO_ANTIALIAS_BEST: case CAIRO_ANTIALIAS_SUBPIXEL:
format = CAIRO_FORMAT_ARGB32; break;
}
}
surface = cairo_image_surface_create (format, width, height);
/* compute a normalized version of font scale matrix to compute * extents in. This is to minimize error caused by the cairo_fixed_t
* representation. */
{ double fixed_scale, x_scale, y_scale;
/* since glyphs are pretty much 1.0x1.0, we can reduce error by
* scaling to a larger square. say, 1024.x1024. */
fixed_scale = 1024.;
x_scale /= fixed_scale;
y_scale /= fixed_scale;
if (status == CAIRO_STATUS_SUCCESS &&
font_face->scaled_font_methods.init != NULL)
{ /* Lock the scaled_font mutex such that user doesn't accidentally try
* to use it just yet. */
CAIRO_MUTEX_LOCK (user_scaled_font->base.mutex);
/* Give away fontmap lock such that user-font can use other fonts */
status = _cairo_scaled_font_register_placeholder_and_unlock_font_map (&user_scaled_font->base); if (status == CAIRO_STATUS_SUCCESS) {
cairo_surface_t *recording_surface;
cairo_t *cr;
/** * cairo_user_font_face_create: * * Creates a new user font-face. * * Use the setter functions to associate callbacks with the returned * user font. The only mandatory callback is render_glyph. * * After the font-face is created, the user can attach arbitrary data * (the actual font data) to it using cairo_font_face_set_user_data() * and access it from the user-font callbacks by using * cairo_scaled_font_get_font_face() followed by * cairo_font_face_get_user_data(). * * Return value: a newly created #cairo_font_face_t. Free with * cairo_font_face_destroy() when you are done using it. * * Since: 1.8
**/
cairo_font_face_t *
cairo_user_font_face_create (void)
{
cairo_user_font_face_t *font_face;
/** * cairo_user_font_face_set_init_func: * @font_face: A user font face * @init_func: The init callback, or %NULL * * Sets the scaled-font initialization function of a user-font. * See #cairo_user_scaled_font_init_func_t for details of how the callback * works. * * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE * error will occur. A user font-face is immutable as soon as a scaled-font * is created from it. * * Since: 1.8
**/ void
cairo_user_font_face_set_init_func (cairo_font_face_t *font_face,
cairo_user_scaled_font_init_func_t init_func)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return;
}
user_font_face = (cairo_user_font_face_t *) font_face; if (user_font_face->immutable) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) return;
}
user_font_face->scaled_font_methods.init = init_func;
}
/** * cairo_user_font_face_set_render_color_glyph_func: * @font_face: A user font face * @render_glyph_func: The render_glyph callback, or %NULL * * Sets the color glyph rendering function of a user-font. * See #cairo_user_scaled_font_render_glyph_func_t for details of how the callback * works. * * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE * error will occur. A user font-face is immutable as soon as a scaled-font * is created from it. * * The render_glyph callback is the only mandatory callback of a * user-font. At least one of * cairo_user_font_face_set_render_color_glyph_func() or * cairo_user_font_face_set_render_glyph_func() must be called to set * a render callback. If both callbacks are set, the color glyph * render callback is invoked first. If the color glyph render * callback returns %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the * non-color version of the callback is invoked. * * If the callback is %NULL and a glyph is tried to be rendered using * @font_face, a %CAIRO_STATUS_USER_FONT_ERROR will occur. * * Since: 1.18
**/ void
cairo_user_font_face_set_render_color_glyph_func (cairo_font_face_t *font_face,
cairo_user_scaled_font_render_glyph_func_t render_glyph_func)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return;
}
/** * cairo_user_font_face_set_render_glyph_func: * @font_face: A user font face * @render_glyph_func: The render_glyph callback, or %NULL * * Sets the glyph rendering function of a user-font. * See #cairo_user_scaled_font_render_glyph_func_t for details of how the callback * works. * * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE * error will occur. A user font-face is immutable as soon as a scaled-font * is created from it. * * The render_glyph callback is the only mandatory callback of a * user-font. At least one of * cairo_user_font_face_set_render_color_glyph_func() or * cairo_user_font_face_set_render_glyph_func() must be called to set * a render callback. If both callbacks are set, the color glyph * render callback is invoked first. If the color glyph render * callback returns %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the * non-color version of the callback is invoked. * * If the callback is %NULL and a glyph is tried to be rendered using * @font_face, a %CAIRO_STATUS_USER_FONT_ERROR will occur. * * Since: 1.8
**/ void
cairo_user_font_face_set_render_glyph_func (cairo_font_face_t *font_face,
cairo_user_scaled_font_render_glyph_func_t render_glyph_func)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return;
}
user_font_face = (cairo_user_font_face_t *) font_face; if (user_font_face->immutable) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) return;
}
user_font_face->scaled_font_methods.render_glyph = render_glyph_func;
}
/** * cairo_user_font_face_set_text_to_glyphs_func: * @font_face: A user font face * @text_to_glyphs_func: The text_to_glyphs callback, or %NULL * * Sets th text-to-glyphs conversion function of a user-font. * See #cairo_user_scaled_font_text_to_glyphs_func_t for details of how the callback * works. * * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE * error will occur. A user font-face is immutable as soon as a scaled-font * is created from it. * * Since: 1.8
**/ void
cairo_user_font_face_set_text_to_glyphs_func (cairo_font_face_t *font_face,
cairo_user_scaled_font_text_to_glyphs_func_t text_to_glyphs_func)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return;
}
user_font_face = (cairo_user_font_face_t *) font_face; if (user_font_face->immutable) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) return;
}
user_font_face->scaled_font_methods.text_to_glyphs = text_to_glyphs_func;
}
/** * cairo_user_font_face_set_unicode_to_glyph_func: * @font_face: A user font face * @unicode_to_glyph_func: The unicode_to_glyph callback, or %NULL * * Sets the unicode-to-glyph conversion function of a user-font. * See #cairo_user_scaled_font_unicode_to_glyph_func_t for details of how the callback * works. * * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE * error will occur. A user font-face is immutable as soon as a scaled-font * is created from it. * * Since: 1.8
**/ void
cairo_user_font_face_set_unicode_to_glyph_func (cairo_font_face_t *font_face,
cairo_user_scaled_font_unicode_to_glyph_func_t unicode_to_glyph_func)
{
cairo_user_font_face_t *user_font_face; if (font_face->status) return;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return;
}
user_font_face = (cairo_user_font_face_t *) font_face; if (user_font_face->immutable) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) return;
}
user_font_face->scaled_font_methods.unicode_to_glyph = unicode_to_glyph_func;
}
/* User-font method getters */
/** * cairo_user_font_face_get_init_func: * @font_face: A user font face * * Gets the scaled-font initialization function of a user-font. * * Return value: The init callback of @font_face * or %NULL if none set or an error has occurred. * * Since: 1.8
**/
cairo_user_scaled_font_init_func_t
cairo_user_font_face_get_init_func (cairo_font_face_t *font_face)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return NULL;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return NULL;
}
/** * cairo_user_font_face_get_render_color_glyph_func: * @font_face: A user font face * * Gets the color glyph rendering function of a user-font. * * Return value: The render_glyph callback of @font_face * or %NULL if none set or an error has occurred. * * Since: 1.18
**/
cairo_user_scaled_font_render_glyph_func_t
cairo_user_font_face_get_render_color_glyph_func (cairo_font_face_t *font_face)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return NULL;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return NULL;
}
/** * cairo_user_font_face_get_render_glyph_func: * @font_face: A user font face * * Gets the glyph rendering function of a user-font. * * Return value: The render_glyph callback of @font_face * or %NULL if none set or an error has occurred. * * Since: 1.8
**/
cairo_user_scaled_font_render_glyph_func_t
cairo_user_font_face_get_render_glyph_func (cairo_font_face_t *font_face)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return NULL;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return NULL;
}
/** * cairo_user_font_face_get_text_to_glyphs_func: * @font_face: A user font face * * Gets the text-to-glyphs conversion function of a user-font. * * Return value: The text_to_glyphs callback of @font_face * or %NULL if none set or an error occurred. * * Since: 1.8
**/
cairo_user_scaled_font_text_to_glyphs_func_t
cairo_user_font_face_get_text_to_glyphs_func (cairo_font_face_t *font_face)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return NULL;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return NULL;
}
/** * cairo_user_font_face_get_unicode_to_glyph_func: * @font_face: A user font face * * Gets the unicode-to-glyph conversion function of a user-font. * * Return value: The unicode_to_glyph callback of @font_face * or %NULL if none set or an error occurred. * * Since: 1.8
**/
cairo_user_scaled_font_unicode_to_glyph_func_t
cairo_user_font_face_get_unicode_to_glyph_func (cairo_font_face_t *font_face)
{
cairo_user_font_face_t *user_font_face;
if (font_face->status) return NULL;
if (! _cairo_font_face_is_user (font_face)) { if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) return NULL;
}
/** * cairo_user_scaled_font_get_foreground_marker: * @scaled_font: A user scaled font * * Gets the foreground pattern of the glyph currently being * rendered. A #cairo_user_scaled_font_render_glyph_func_t function * that has been set with * cairo_user_font_face_set_render_color_glyph_func() may call this * function to retrieve the current foreground pattern for the glyph * being rendered. The function should not be called outside of a * cairo_user_font_face_set_render_color_glyph_func() callback. * * The foreground marker pattern contains an internal marker to * indicate that it is to be substituted with the current source when * rendered to a surface. Querying the foreground marker will reveal a * solid black color, however this is not representative of the color * that will actually be used. Similarly, setting a solid black color * will render black, not the foreground pattern when the glyph is * painted to a surface. Using the foreground marker as the source * instead of cairo_user_scaled_font_get_foreground_source() in a * color render callback has the following benefits: * * 1. Cairo only needs to call the render callback once as it can * cache the recording. Cairo will substitute the actual foreground * color when rendering the recording. * * 2. On backends that have the concept of a foreground color in fonts such as * PDF, PostScript, and SVG, cairo can generate more optimal * output. The glyph can be included in an embedded font. * * The one drawback of the using foreground marker is the render * callback can not access the color components of the pattern as the * actual foreground pattern is not available at the time the render * callback is invoked. If the render callback needs to query the * foreground pattern, use * cairo_user_scaled_font_get_foreground_source(). * * If the render callback simply wants to call cairo_set_source() with * the foreground pattern, * cairo_user_scaled_font_get_foreground_marker() is the preferred * function to use as it results in better performance than * cairo_user_scaled_font_get_foreground_source(). * * Return value: the current foreground source marker pattern. This * object is owned by cairo. This object must not be modified or used * outside of a color render callback. To keep a reference to it, * you must call cairo_pattern_reference(). * * Since: 1.18
**/
cairo_pattern_t *
cairo_user_scaled_font_get_foreground_marker (cairo_scaled_font_t *scaled_font)
{
cairo_user_scaled_font_t *user_scaled_font;
if (scaled_font->backend != &_cairo_user_scaled_font_backend) return _cairo_pattern_create_in_error (CAIRO_STATUS_FONT_TYPE_MISMATCH);
/** * cairo_user_scaled_font_get_foreground_source: * @scaled_font: A user scaled font * * Gets the foreground pattern of the glyph currently being * rendered. A #cairo_user_scaled_font_render_glyph_func_t function * that has been set with * cairo_user_font_face_set_render_color_glyph_func() may call this * function to retrieve the current foreground pattern for the glyph * being rendered. The function should not be called outside of a * cairo_user_font_face_set_render_color_glyph_func() callback. * * This function returns the current source at the time the glyph is * rendered. Compared with * cairo_user_scaled_font_get_foreground_marker(), this function * returns the actual source pattern that will be used to render the * glyph. The render callback is free to query the pattern and * extract color components or other pattern data. For example if the * render callback wants to create a gradient stop based on colors in * the foreground source pattern, it will need to use this function in * order to be able to query the colors in the foreground pattern. * * While this function does not have the restrictions on using the * pattern that cairo_user_scaled_font_get_foreground_marker() has, it * does incur a performance penalty. If a render callback calls this * function: * * 1. Cairo will call the render callback whenever the current pattern * of the context in which the glyph is rendered changes. * * 2. On backends that support font embedding (PDF, PostScript, and * SVG), cairo can not embed this glyph in a font. Instead the glyph * will be emitted as an image or sequence of drawing operations each * time it is used. * * Return value: the current foreground source pattern. This object is * owned by cairo. To keep a reference to it, you must call * cairo_pattern_reference(). * * Since: 1.18
**/
cairo_pattern_t *
cairo_user_scaled_font_get_foreground_source (cairo_scaled_font_t *scaled_font)
{
cairo_user_scaled_font_t *user_scaled_font;
if (scaled_font->backend != &_cairo_user_scaled_font_backend) return _cairo_pattern_create_in_error (CAIRO_STATUS_FONT_TYPE_MISMATCH);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.