GNOME Bugzilla – Bug 107668
Rendering to outlines
Last modified: 2005-07-21 22:20:49 UTC
I'm mainly wanting this for use in librsvg, but it has general applicability. What I'd like to do is get FT_Outline data instead of a FT_Bitmap returned from the pango_ft2_render_xxx functions. Since font data is vector in nature anyway, and pango's ft2 backend doesn't load bitmap fonts (FT_LOAD_NO_BITMAP), I think that doing this would be feasible. What I'd like to do with the returned outline is to decompose the outline into a SVG path (or array of paths, if necessary). This will be useful for: *) Clipping text out/clipping to text *) Masking text *) Applying patterns to text as opposed to solid colors or gradients *) Easily getting things like a "2 pixel red border, blue fill" correct *) Ease in applying transforms to the text. Easier and faster than applying an affine to the base image, drawing a FT_Bitmap, and then rotating the base image back. There are probably another few reasons why this would be useful for me. Thanks.
What I'd like to see here is something more flexible along the lines of: void pango_layout_render (PangoLayout *layout, PangoGlyphRenderFunction func, gpointer user_data); void (*PangoGlyphRenderFunction) (PangoFont *font, PangoGlyph glyph, PangoColor fg, int x, int y, gpointer user_data); A) It probably needs to be a bit more complex than this, B) I'm not completely sure it can be generic; it might have to be backend-specific. But the basic idea is that I'd rather let the user choose what they want to to do with the glyphs, rather than have one render-to-a-bitmap, another render-to-an-outline, another render-to-a-differently-formatted-bitmap, and so on ad infinitum.
Putting on future, though I'm willing to move it back to 1.4 if we come up with API/patch we're happy with in time.
See also bug #94791.
Just for your information: I am now implementing this functionality in gimp-1.3 and I will try to use an API that is similar to what was suggested here. Perhaps we can later move that code into Pango.
In case anyone is interested, the code is in gimp/app/text and it seems to work just fine. I'd be interested in moving this functionality back into Pango at some point.
As already outlined in bug #94791 I'm pretty sure that Pango needs exacty two additional facilities to be really useful for advanced application needs (e.g. The Gimp and Dia) - A backend specific gray level bitmap rendering function as already available for Ft2 and if the patch in #94791 gets accepted even for win32 - A generic way to get on the glyph vectors. This could either be done by having some basic Pango specific vector struct definitions or - what I like more - with the Renderer Interface declared below. With it the application does provide a concrete implementation of PangoGlypRenderer and could even use it to render the vectors to a bitmap again. The reason why I think the latter should not be the only way is that backends already provide some advanced anti aliasing algorithms to get 'optimal' rendering to bitmap. I'm even offering to implement the backend specific renderer feeding for both paltforms which need them most : Ft2 (which I would like not to be forced to use) and the win32 one. For win32 the implementation would be around GetGlyphOutline(), for Ft2 it would mean some refactorng of Svens gimp/app/text/gimptext-vectors.c But before wasting time with a patch which will finally be rejected - as happened at least one time too often - I'd like to get some confidence about the approach being accepted. #ifndef __PANGO_GLYPHRENDERER_H__ #define __PANGO_GLYPHRENDERER_H__ #include <pango/pango-font.h> G_BEGIN_DECLS typedef _PangoPosition PangoPosition; struct _PangoPosition { int x; int y; }; /* feeds the glyphs vector data into the glyph renderer */ void pango_render_glyph (PangoGlyphRenderer *renderer, PangoFont *font, PangoGlyph *glyph, PangoContext *context); #define PANGO_TYPE_GLYPH_RENDERER (pango_glyph_renderer_get_type ()) #define PANGO_GLYPH_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_GLYPH_RENDERER, PangoGlypRenderer)) #define PANGO_IS_GLYPH_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_GLYPH_RENDERER)) typedef struct _PangoGlyphRenderer PangoGlyphRenderer; GType pango_glyph_renderer_get_type (void) G_GNUC_CONST; #ifdef PANGO_ENABLE_BACKEND #define PANGO_GLYPH_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_GLYPH_RENDERER, PangoGlyphRendererClass)) #define PANGO_IS_GLYPH_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_GLYPH_RENDERER)) #define PANGO_GLYPH_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_GLYPH_RENDERER, PangoGlyphRendererClass)) typedef struct _PangoGlyphRendererClass PangoGlyphRendererClass; struct _PangoGlyphRenderer { GObject parent_instance; }; struct _PangoGlyphRendererClass { GObjectClass parent_class; /*< public >*/ gboolean (*move_to) (PangoGlyphRenderer *renderer, PangoPosition *to); gboolean (*line_to) (PangoGlyphRenderer *renderer, PangoPosition *to); gboolean (*conic_to) (PangoGlyphRenderer *renderer, PangoPosition *control, PangoPosition *to); gboolean (*cubic_to) (PangoGlyphRenderer *renderer, PangoPosition *control1, PangoPosition *control2, PangoPosition *to); /*< private >*/ void *backend_data; } #endif /* PANGO_ENABLE_BACKEND */ G_END_DECLS #endif /* __PANGO_GLYPHRENDERER_H__ */
http://mail.gnome.org/archives/gtk-i18n-list/2004-July/msg00014.html describes my current PangoRenderer work which is scheduled for 1.8. It should be pretty easy to subclass that to create an outline-renderer for the FT2 backend.
I'm going to consider the Cairo changes in Pango-1.9.x to resolve this, since you can render layouts, layout lines, and glyph strings to paths, and you can query Cairo for the path (cairo_copy_path()) I could see some use case for being able to get a rawer representation, or not dragging in Cairo, but I'd rather keep the API small for now.