After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 511130 - Extending standard attributes
Extending standard attributes
Status: RESOLVED OBSOLETE
Product: pango
Classification: Platform
Component: general
unspecified
Other All
: Normal enhancement
: ---
Assigned To: Cody Russell
pango-maint
Depends on:
Blocks: 508810
 
 
Reported: 2008-01-21 21:18 UTC by Behdad Esfahbod
Modified: 2018-05-22 12:39 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Unfinished patch (3.10 KB, patch)
2008-11-11 16:33 UTC, Cody Russell
none Details | Review
Updates (still unfinished) (9.43 KB, patch)
2008-11-15 20:06 UTC, Cody Russell
none Details | Review
Minor cleanup (9.41 KB, patch)
2008-11-15 20:12 UTC, Cody Russell
none Details | Review
Updated patch (19.74 KB, patch)
2008-12-23 23:52 UTC, Cody Russell
none Details | Review
Bitmask fixes, function renames (19.70 KB, patch)
2008-12-25 05:34 UTC, Cody Russell
none Details | Review

Description Behdad Esfahbod 2008-01-21 21:18:25 UTC
PangoAttribute is not a GType type and I seem to need to reinvent GType here...

Basic way to summarize the missing feature is: pango hardcodes some attribute types in code, basically all the predefined attribute types.  A user-define attribute never has a chance to be treated similar to PANGO_ATTR_SHAPE for example.  I want to fix that.

Concrete usecase for this is: currently PANGO_ATTR_SHAPE is very hard to use, much harder than it needs to be.  I added pango_cairo_context_set_shape_renderer() which greatly simplifies that, so one doesn't have to implement a PangoRenderer to use shape attributes meaningfully anymore (ok, one didn't have to, see GtkTextView for example), but the biggest caveat still remains: It's hard for custom renders in libraries (like gdkpango) to add useful shape renderers (like rendering a GdkPixbuf) without taking full control of ATTR_SHAPE out of user's hand.



Instead of bandaiding that around ATTR_SHAPE I want to fix it properly (to the extent possible by compatibility).  Here is my proposal:


  - Currently PangoAttrType's are assigned to predefined attributes from 0 (in the PangoAttrType enum) and allocated from 1000 up for custom attributes, in pango_attr_type_register().  We logically divide that integer "type" value into two parts: lowest byte as base type, three other bytes as instance type.


  - New API for creating new instances of other attribute types.  We can only support shallow one-level subtyping here but that's all we care about.  Proposed API:

PangoAttrType    pango_attr_type_register_similar (const gchar   *name,
                                                   PangoAttrType  similar_type);

Not sure about the name... What this does is to set the lower byte of the returned attr type to the lower byte of the base_type.

And a getter:

PangoAttrType    pango_attr_type_get_base_type (PangoAttrType  attr_type);

Base types are defined as those defined by Pango.  An attribute registered using pango_attr_type_register() has base type PANGO_ATTR_INVALID.


  - New API for attribute type similarity checking.  This checks that the lower byte of attribute types for equality, but this is just the implementation detail and private, publicly just a function:

gboolean        pango_attr_type_similar (PangoAttrType first_type,
                                         PangoAttrType second_type);

And a convenience one for actual attributes:

gboolean        pango_attr_similar_to (PangoAttribute *attr,
                                       PangoAttrType   other_type);

Note that this test only means that the type of attr and other_type have the same base type.  attr is not necessarily of type other_type.  As I said, shallow typing only...


  - Change Pango internals to always check for attribute base type instead of exact type.  For example, in pango-renderer.c, instead of this:

      switch (attr->klass->type)
        {
        case PANGO_ATTR_SHAPE:
          if (shape_attr)
            *shape_attr = (PangoAttrShape *)attr;
          break;

        ...
        }

We'll have:

      switch (pango_attr_type_get_base_type (attr->klass->type))
        {
        case PANGO_ATTR_SHAPE:
          if (shape_attr)
            *shape_attr = (PangoAttrShape *)attr;
          break;

        ...
        }


  - pango_cairo_context_set_shape_renderer() only sets shape renderer for ATTR_SHAPE.  Add new API for setting shape renderer for custom shape attributes:

void
pango_cairo_context_set_shape_renderer_for_attr_type
                                       (PangoContext                *context,
                                        PangoAttrType                attr_type,
                                        PangoCairoShapeRendererFunc  func,
                                        gpointer                     data,
                                        GDestroyNotify               dnotify)
{
  g_return_if_fail (pango_attr_type_get_base_type (attr_type) != PANGO_ATTR_SHAPE);

  ...
}


That's all.  With all that, we can then add the following gdkpango API:

PangoAttribute *
gdk_pango_attribute_pixbuf_new (GdkPixbuf  *pixbuf,
                                int width, int height, ...);

Then in gdk_pango_context_get(), register shape renderer for the type GDK_PANGO_ATTR_PIXBUF on the context being returned.

This way they user is free to use ATTR_SHAPE as they wish.
The only problem with this being that all shape renderers need to be set on all PangoContext's.  That's not totally infeasible, but is a bit of a burden.  To fix that, we can provide PangoCairoRenderer API for that too, when we subclass PangoRenderer in gdkpango.


Owen, Matthias, comments?
Comment 1 Behdad Esfahbod 2008-04-21 22:54:25 UTC
Bug 116115 should be resolved at the same time.

Late today, I'll go ahead and give this a try in for the next devel release.
Comment 2 Behdad Esfahbod 2008-08-13 18:23:55 UTC
It occurred to me that attribute extensions can be used to implement things like RGBA color attributes (say, for cairo backend only, or just as an extension of the RGB color attribtues) ala bug 413941.  However, this just reveals that the flat inheritance scheme I described in this bug is suboptimal, as I wasn't thinking about the case of having extension attributes in pango and pango backends themselves.
Comment 3 Cody Russell 2008-11-11 16:33:39 UTC
Created attachment 122430 [details] [review]
Unfinished patch

I think I did the bitwise operators wrong.. I think I've got the base type on the wrong side of int.  Also still need to find all the places that need to switch to use the new API.
Comment 4 Cody Russell 2008-11-15 20:06:51 UTC
Created attachment 122746 [details] [review]
Updates (still unfinished)

This adds the pango_cairo_context_set_shape_renderer_for_attr_type() API and other related changes.
Comment 5 Cody Russell 2008-11-15 20:10:39 UTC
Behdad, you suggested on IRC the other day of doing more than one level of attribute extending.  Is that still something you're interested in doing?  Was the idea that you have the base attribute in one word, then allow up to three levels of attribute extending in the other words?
Comment 6 Cody Russell 2008-11-15 20:12:31 UTC
Created attachment 122747 [details] [review]
Minor cleanup
Comment 7 Cody Russell 2008-11-15 20:45:12 UTC
Uhh, I think I meant to say 'bytes' instead of 'words' in Comment #5. :)
Comment 8 Cody Russell 2008-12-23 23:52:39 UTC
Created attachment 125241 [details] [review]
Updated patch

Okay, getting back to this bug now.  Here is an updated patch, and I added a unit test for the basic attribute inheritance system.  It's not very thorough yet, but it tests to make sure that the basic stuff works.

It creates attributes:
 "German" from PANGO_ATTR_TYPE_LANGUAGE
 "SwissGerman" from "German"
 "French" from PANGO_ATTR_TYPE_LANGUAGE

Then it tests:
  German is a German
  German is a Language
  SwissGerman is a Language
  SwissGerman is a Language
  French is not a German

That's obviously not very thorough, but it's something.  And if you're interested I posted a git branch (based on git-mirror.gnome.org):
  http://github.com/bratsche/pango/tree/extended_attributes
Comment 9 Cody Russell 2008-12-23 23:53:38 UTC
  SwissGerman is a Language
  SwissGerman is a Language

Uhh, that was a typo.  The second one was meant to say "SwissGerman is a German"
Comment 10 Behdad Esfahbod 2008-12-24 20:35:22 UTC
Looks great!

The bitmask operations bother me a bit. "(attr_type & 0xffffff00) >> 8" definitely can simply be "attr_type >> 8".  Otherwise it's doing exactly what it should be.

I suggest we rename create_similar() to create_full(..., parent_type).  And get_base_type() to get_parent_type().

I'll look into landing this when I get back to pango hacking.

Thanks Cody!
Comment 11 Cody Russell 2008-12-25 05:34:55 UTC
Created attachment 125291 [details] [review]
Bitmask fixes, function renames

Hi Behdad, thanks very much for your comments!  This patch I think fixes the things in your comments.  Whenever you get back to Pango hacking, let me know if there's anything else I can do with this.
Comment 12 Cody Russell 2009-04-01 18:31:14 UTC
I deleted my old git branch, because it was based on a git-svn checkout, and I've posted a new git branch that is based on git.gnome.org/pango

http://github.com/bratsche/pango/tree/master
Comment 13 GNOME Infrastructure Team 2018-05-22 12:39:18 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pango/issues/119.