Re: Pango font API problems, gnome-print



OK, I've gone ahead and implemented most of the basic changes that I discussed
in my previous mail. If I posted my entire ~10,000 line Pango and GTK+
diff for this change (and the style->font change), I'm pretty sure nobody
would read it, so instead I"ve summarized the API changes below, in hopes
that people will check through them.

Thanks,
                                              Owen


 * Made pango_font_description opaque and heap allocated,
   adding:

   PangoFontDescription *pango_font_description_new        (void);

   void          pango_font_description_set_family  (PangoFontDescription *desc,
                                                     const char           *family);
   const char *  pango_font_description_get_family  (const PangoFontDescription *desc);
   void          pango_font_description_set_style   (PangoFontDescription *desc,
                                                    PangoStyle            style);
   PangoStyle    pango_font_description_get_style   (const PangoFontDescription *desc);
   void          pango_font_description_set_variant (PangoFontDescription *desc,
                                                     PangoVariant          variant);
   PangoVariant  pango_font_description_get_variant (const PangoFontDescription *desc);
   void          pango_font_description_set_weight  (PangoFontDescription *desc,
                                                     PangoWeight           weight);
   PangoWeight   pango_font_description_get_weight  (const PangoFontDescription *desc);
   void          pango_font_description_set_stretch (PangoFontDescription *desc,
                                                     PangoStretch          stretch);
   PangoStretch  pango_font_description_get_stretch (const PangoFontDescription *desc);
   void          pango_font_description_set_size    (PangoFontDescription *desc,
                                                     gint                  size);
   gint          pango_font_description_get_size    (const PangoFontDescription *desc);

 * PangoFontDescription can now be unspecified for any aspect, not
   just family and size. To support this, I added:

   typedef enum {
   PANGO_FONT_MASK_FAMILY  = 1 << 0,
   PANGO_FONT_MASK_STYLE   = 1 << 1,
   PANGO_FONT_MASK_VARIANT = 1 << 2,
   PANGO_FONT_MASK_WEIGHT  = 1 << 3,
   PANGO_FONT_MASK_STRETCH = 1 << 4,
   PANGO_FONT_MASK_SIZE    = 1 << 5
   } PangoFontMask;

   PangoFontMask pango_font_description_get_mask   (const PangoFontDescription *desc);
   void          pango_font_description_clear_mask (PangoFontDescription       *desc,
   PangoFontMask               to_clear);

 * Also added were a number of convenience functions for manipulating PangFontDescription:

   guint    pango_font_description_hash         (const PangoFontDescription *desc);
   void     pango_font_description_merge        (PangoFontDescription       *desc,
                                                 const PangoFontDescription *desc_to_merge,
                                                 gboolean                    replace_existing);
   gboolean pango_font_description_better_match (const PangoFontDescription *desc,
                                                 const PangoFontDescription *old_match,
                                                 const PangoFontDescription *new_match);

 * Finally, a hacky API was added for manipulating font descriptions while not copying
   family names:

   PangoFontDescription *pango_font_description_copy_static       (const PangoFontDescription *desc);
   void                  pango_font_description_set_family_static (PangoFontDescription       *desc,
                                                                   const char                 *family);
   void                  pango_font_description_merge_static      (PangoFontDescription       *desc,
                                                                   const PangoFontDescription *desc_to_merge,
                                                                   gboolean                    replace_existing);

   I added this because font descriptions are used as "scratchpads" a lot in the internals
   of the PangoLayout code and constantly copying names can get expensive. 

 * PangoFontMetrics is now heap allocated and opaque:

   PangoFontMetrics *pango_font_metrics_ref                         (PangoFontMetrics *metrics);
   void              pango_font_metrics_unref                       (PangoFontMetrics *metrics);
   int               pango_font_metrics_get_ascent                  (PangoFontMetrics *metrics);
   int               pango_font_metrics_get_descent                 (PangoFontMetrics *metrics);
   int               pango_font_metrics_get_approximate_char_width  (PangoFontMetrics *metrics);
   int               pango_font_metrics_get_approximate_digit_width (PangoFontMetrics *metrics);

  With corresponding changes to pango_context_get_metrics() and pango_font_get_metrics() to:

  PangoFontMetrics *pango_font_get_metrics     (PangoFont                    *font,
                                                PangoLanguage                *language);
  PangoFontMetrics *pango_context_get_metrics  (PangoContext                 *context,
                                                const PangoFontDescription   *desc,
                                                PangoLanguage                *language);

 * Added PangoFontFamily and PangoFontFace types, and rewrote font listing API 
   to use them:

   #define PANGO_TYPE_FONT_FAMILY        (pango_font_family_get_type ())
   #define PANGO_FONT_FAMILY(object)     (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONT_FAMILY, PangoFontFamily))
   #define PANGO_IS_FONT_FAMILY(object)  (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONT_FAMILY))

   void        pango_font_family_list_faces (PangoFontFamily  *family,
                                             PangoFontFace  ***faces,
                                              int              *n_faces);
   const char *pango_font_family_get_name   (PangoFontFamily  *family);

   #define PANGO_TYPE_FONT_FACE              (pango_font_face_get_type ())
   #define PANGO_FONT_FACE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONT_FACE, PangoFontFace))
   #define PANGO_IS_FONT_FACE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONT_FACE))

   PangoFontDescription *pango_font_face_describe       (PangoFontFace *face);
   G_CONST_RETURN char  *pango_font_face_get_style_name (PangoFontFace *face);

  -void          pango_context_list_fonts    (PangoContext                 *context,
  -                                           const char                   *family,
  -                                           PangoFontDescription       ***descs,
  -                                           int                          *n_descs);
   void          pango_context_list_families (PangoContext                 *context,
  -                                           gchar                      ***families,
  +                                           PangoFontFamily            ***families,
                                              int                          *n_families);

  -void       pango_font_map_list_fonts    (PangoFontMap                 *fontmap,
  -                                         const gchar                  *family,
  -                                         PangoFontDescription       ***descs,
  -                                         int                          *n_descs);
   void       pango_font_map_list_families (PangoFontMap                 *fontmap,
  -                                         gchar                      ***families,
  +                                         PangoFontFamily            ***families,
                                            int                          *n_families);
  -void       pango_font_map_free_families (gchar                       **families,
  -                                         int                           n_families);

Questions:

 * pango_face_get_style_name() is a bad name, because we've already (following CSS)
   used style to mean normal/italic/oblique. GnomePrint seems to use 
   "species_name" for this purpose. A bit confusing, but perhaps less so
   than using "style" to mean different things.

   "get_name" and "get_face_name" don't strike me as good alternative names
   since they imply a name that specifies the face within all available faces, not 
   the face within the family.

 * Are functions like pango_font_description_set_family_static() worth including.
   They do save a significant number of string copies. On the other hand:

    - For the internals of Pango (pango_itemize(), etc), the same effect could
      be solved with an internal API 

    - The pursuit of efficiency to the following ugliness the pango_attr_iterator_get_font() 
      docs:

     * @desc: a #PangoFontDescription to fill in with the current values.
     *        The family name in this structure will be set using
     *        pango_font_description_set_family_static using values from
     *        an attribute in the #PangoAttrList associated with the iterator,
     *        so if you plan to keep it around, you must call:
     *        pango_font_description_set_family (desc, pango_font_description_get_family (desc)).

Still TODO (most puntable to post-1.0):

 * Divide the public API into:

    1) Really public API
    2) interface between backend implementations and pango core
    3) interface between backend implementations, pango core, and shapers

   And only export 1) unless you #define some magic. (PANGO_ENABLE_EVOLVING)

 * Add:

   PangoFamily *pango_context_find_family (PangoContext         *context,
                                           const char           *family);
   PangoFace   *pango_family_find_face    (PangoFamily          *family,
                                           PangoFontDescription *desc);
   PangoFace   *pango_context_find_face   (PangoContext         *context,
                                           PangoFontDescription *desc);

 * Add support for fully unspecified PangoFontDescription in font_description_to/from_string.
   I think the cleanest way to do this would be to allow:

    "Times Roman style=normal variant=* weight=* stretch=* 12"

   As a font description with family,style and size specified, and other fields specified.

 * Add additional metrics to PangoFontMetrics.





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