GnomeFont RFC III



Hello

here are presented outlines of my current work. At the end, there is
listed some comments and problems, I have.
If you prefer to read, code, take a look into gnome CVS module
gnome-font. There you can find also some test programs, illustrating the
proposed use of gnome-font library, including constructing glyph lists for
different outut devices and rendering those in device-independent way.
Currently only TrueTypes via FreeType1 are supported

Existing API so far:

GnomeVFont - abstract base class for collections of glyphs

-- Class methods:

  GnomeFontGlyph * get_glyph (GnomeVFont * vfont, gint code)

Retrieves glyph object, given its font-specific code

-- Methods:

  GnomeFontGlyph * gnome_vfont_get_glyph (GnomeVFont * vfont, gint code)

Retrieves glyph object from vfont. NB! The exact interpretation of glyph
object depends on vfont implementation (whether it is face, font or rfont)



GnomeFontFace : GnomeVFont - base class for unsized typeface

Face can be thought as general handle to unscaled typeface. Most
font-format specific implementations use face as handle to actual
file. Still - probably face will have some additional constraints, such as
specified text direction.

-- Class methods:

  GnomeFontFaceDesc * description (GnomeFontFace * face,
	const gchar * language)

THIS IS EXPERIMENTAL
Retrieves localized face description (family name, face name, etc.), in
given language ("en_US", "fr_FR"), using standard rules (fallback to "C")

  GnomeFont * get_font (GnomeFontFace * face,
	gdouble size, gdouble transform[]);

Retrieves GnomeFont, adapted for given pointsize and output
resolution. Transform matrix is affine transformation from font base
coordinates (xy oriented typographic points) to master output device
actual raster matrix. Usually this involves some kind of scaling - but
theoretically it can be whatever matrix (in libart format)

  gboolean set_encoding (GnomeFontFace * face, gint id,
	const gchar * name, const gchar * encoding)

THIS IS HIGHLY EXPERIMENTAL
Sets face charcode->glyph mapping to certain known value. In usual
occasions you simply can use Unicode mapping, but there are cases, when it
has to be more specific (language specific variants, ligatures, etc.)
Certian vfont can have many parallel encoding tables, which are specified,
using either integer id or string name.
This is experimental and hopefully will be changed to complex api, capable
of presenting OpenType glyph substitution/composition rules
NB! Such things are specific to face, not vfont, because GnomeFont and
GnomeRFont are forced to use their parent face encodings.

  gint lookup (GnomeFontFace * face, gint encoding, gint code)

THIS IS EXPERIMENTAL
Retrieves font-specific glyph code, given encoding id and charcode

-- Methods:

  GnomeFontFamily * gnome_font_face_get_family (GnomeFontFace * face)
  const gchar * gnome_font_face_get_family_name (GnomeFontFace * face,
	const gchar * language)
  const gchar * gnome_font_face_get_species_name (GnomeFontFace * face,
	const gchar * language)
  const gchar * gnome_font_face_get_canonical_name (GnomeFontFace * face,
	const gchar * language)

These should be obvious :)

  GnomeFont * gnome_font_face_get_font (GnomeFontFace * face,
	gdouble size, gdouble xres, gdouble yres);
  GnomeFont * gnome_font_face_get_font_full (GnomeFontFace * face,
	gdouble size, gdouble transform[]);

Retrieve specific GnomeFont, given either scaling values or full matrix

  gboolean gnome_font_face_set_encoding (GnomeFontFace * face,
	gint id, const gchar * name, const gchar * encoding)

EXPERIMENTAL, see above

  gint gnome_font_face_lookup (GnomeFontFace * face,
	gint encoding, gint code)

See above



GnomeFont : GnomeVFont - base class for resolution-adjusted typefaces

GnomeFont is derived form unsized face, specifying its pointsize (fonts
can have different glyph shapes for different pointsizes) and master
output resolution. If font format is hintable, its metrics are then
hinted, to give best results (uniform glyph distances etc.) on that
resolution. Font can still be rendered to whatever
transformation/resolution, and it is completely user's responsibility, to
request correct fonts for given situation. Hopefully in most occasions he
does not need to bother, and can live well with single font for every
occasion (and it is the only way, if exact output medium is not
known).

-- Attributes

GnomeFontFace * face  - the parent face
gdouble size
gdouble affine[6]

-- Class methods

  GnomeRFont * get_rfont (GnomeFont * font, gdouble affine[]);

Retrieves raster-adjusted font, which is used for actual rendering. Affine
is tranformation from font base coordinates (xy oriented typographic
points) to real raster. Although affine is given in libart format,
translation part is (probably) unused - but array has to contain at least
6 elements anyway.

-- Methods

  GnomeRFont * gnome_font_get_rfont (GnomeFont * font, gdouble affine[]);

See above



GnomeRFont : GnomeVFont - base class for rasterizable fonts
Rfont is derived from GnomeFont, specifying exact base to bitmap
transformation matrix. Thus, given certain GnomeFont, new rfont is created
every time if preview zooming factor, etc. changes.

-- Attributes

GnomeFont * font  - the parent font
gdouble affine[6]

-- Class methods

none

-- Methods

none


GnomeFontGlyph - base class for all kinds of glyphs
Glyphs are separate kind of GtkObjects - see the discussion about it.
Currently there is no distinction between glyphs belonging to Face, Font and
RFont - although the meaning of attributes is slightly different.
For GnomeFontFace glyphs all metrics and outlines are given according to
PostScript coordinates (1000 unit em square)
For GnomeFont glyphs all metrics and outlines are given in base (typographic
points) coordinates
For GnomeRFont glyphs all metrics and outlines are given in device (bitmap)
coordinates


-- Attributes

GnomeVFont * vfont;
gint code

-- Class methods

  void metrics (GnomeFontGlyph * glyph, ArtDRect * bbox, ArtPoint * advance)

Get glyph metrics (bearings and advance). NB! As font direction is specified
already in face, there is no need for different metrics for different
directions.
Metrics are given in doubles and, in case of font and rfont) glyphs,
grid-fitted to corresponding resolution.

  const ArtBpath * bpath (GnomeFontGlyph * glyph)

Retrieves outline bpath

  const GFGGrayMap * graymap (GnomeFontGlyph * glyph)

EXPERIMENTAL

-- Methods

  ArtDRect * gnome_font_glyph_get_dimensions (GnomeFontGlyph * glyph,
	ArtDRect * bbox)
  ArtPoint * gnome_font_glyph_get_stdadvance (GnomeFontGlyph * glyph,
	ArtPoint * advance)
  const ArtBpath * gnome_font_glyph_get_bpath (GnomeFontGlyph * glyph);
  const GFGGrayMap * gnome_font_glyph_get_graymap (GnomeFontGlyph * glyph);

See above

  ArtPoint * gnome_font_glyph_get_kerning (GnomeFontGlyph * a,
	GnomeFontGlyph * b, ArtPoint * p);

EXPERIMENTAL
Get kerning value between 2 glyphs. It is vector, not double, because it is
given in same coordinate system, as glyph metrics (and rfonts can be
rotated)



Discussion

The tree-level font structure (face, font, rfont) models conceptual usage
pattern:
GnomeFontFace is holder of all font typographic data, in case of fonts
loaded from files, it has handles to all ttf, pfb, afm etc. files.
GnomeFont is specific instance of face, having well defined size and shape
in world coordinates. Still it has yet no real shape, as world coordinates
can map to different output device coordinates (zooming etc.)
GnomeRFont is instance of font, having real font -> device mapping

Face metrics are unhinted.
Font metrics and outline is grid-fitted to master coordinates.
RFont metrics are grid-fitted to device coordinates

So, having certain RFont instance, it is possible to compute both device
adjusted, and master adjusted positioning. It is up to implementation
(CanvasItem, PrintContext) how to align these (whether disturb one or the
other)

GnomeFontGlyphs

My problem is, whether making glyphs into separate GtkObjects is overkill
or not.
+ Easy API and functionality grouping
+ Easy refcounting
+ Possibility to derive interesting things, such as composite glyphs
+ Often used data, such as metrics, can be included directly in glyph
  structure
- 12-24 wasted bytes per glyph
- Same glyph class serves face, font and rfont
- To do device-adjusted layout, one has to create 2 instances of every glyph
  one for font, one for rfont
- Doing glyph refcounting is often big pain

Alternative would be to include glyph class methods (such as get_bpath,
get_graymap) to vfont.
Using whatever structure, glyphs are quite fat anyways. There has to be cache
for:
* metrics
* bpaths
* SVP-s
* graymaps
* pixmaps (multiple ones for different fg/bg colors)
* bitmaps
Implementing these as different caches inside font objects is also big
waste - and will make multiple attribute lookups (metrics + graymap) slower.
One possibility would be to subclass RFonts into RFontOutline, RFontGraymap,
etc. - but then there will also be big waste of resources, duplicating
metric information among those.

Lauris Kaplinski
lauris@helixcode.com





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]