This is a write-up of observations on reading through the Xr
and Xc header files and a bit of the sources; I haven't actually
tried using the APIs in practice. I also haven't done a
point-by-point comparison with similar API's; something that
I think would be interesting.
The comments below range from very specific points to some
things which most likely count as "wild ideas".
Regards,
Owen
===
I have some general reservations about using a postscript-type API. I
believe that on the low end, such an API is rather hard for
programmers to use -- they want "draw_circle", "draw_rectangle" type
primitives. And on the high end, postscript needs considerable
extension to be competitive with current rendering models such as
Java2D, SVG, PDF versions.
On the other hand, a postscript-like API is conducive to being able to
write code that targets either Xr or Postscript/PDF, so that's a plus.
On to specific comments.
On Xr:
* Shouldn't there be XrSetSurface (XrState *xrs, XcSurface *surface)
instead of or in addition to XrSetDrawable, XrSetVisual?
- Even on X not all XcSurface's have corresponding visuals ...
obvious case is a 32-bit ARGB pixmap.
- It would be useful to be able to create entirely client side
XcSurfaces for in-memory rendering.
- If we add a a Xr/Xc dependency to GTK+, we might well want
to actually use the non-X-dependent portions of the Xr/Xc code on
non-X platforms.
* I'd like to have XrFormat for gdk-pixbuf's weird default
format: big-endian-premultiplied-rgba. (I can supply the
implementation.)
* I think fonts are one area where following the lead of postscript
is clearly a mistake. For one thing, the text operators in
Postscript just aren't that good ... they were done with 8-bit
font encodings in mind, then gradually fixed up one way or
another. For a second thing, we have a good font system now
in fontconfig, and we should be integrating tightly with this.
For font selection, I would suggest:
/* Set the currently selected font to the specificed FcPattern
*/
XrSetFontPattern (XrState *xrs,
FcPattern *pattern);
/* Modify particular values of the selected pattern
*/
XrSetFontValues (XrState *xrs,
...);
You could also have a convenience function that took a
string form, but the above should be the primitives; having
to programmatically build strings is something that should
be avoided.
Another possiblity would be to simply have a XcFont object
that paralleled XftFont exactly.
For font rendering, the functions should closely follow the
lead of Xft. I'd simply define double-valued equivalents
to XftCharSpec, XftGlyphSpec, XGlyphInfo then add
XrDrawGlyphs/XrDrawString8/XrDrawString16/XrDrawString32/
XrDrawStringUtf8/XrDrawCharSpec/XrDrawGlyphSpec
XrGlyphExtents/XrTextExtents8/XrTextExtents16/XrTextExtents32/
XrTextExtentsUtf8.
[ I think DrawStringUtf8 would be better as simply DrawString,
is the better name worth a mismatch with Xft? ]
[ Can any of the above be ditched? DrawString8/String16
TextExtents8/TextExtents16 are of marginal utility since
they don't cover all of Unicode ]
[ What to do with XftFontCharSpec, XftFontGlyphSpec? I don't
think they are terribly useful personally, and adding them
would probably require adding the XcFont object. Which perhaps
is right, but certainly going pattern-only is simpler. ]
Along with the more-Xft like interface, the things that the
above gives that are missing from your interface are:
- Ability to draw with glyph codepoints instead of characters
- Ability to draw with offsets for individual characters in the string
- Ability to get metrics for characters and strings
* There should be a control over whether text is hinted
or not. (Actually XrSetFontValues above might be enough)
In applications without zooming, hinting is right,
but if you add zooming, you quickly get into problems
with the fact that hinted text is not a geometry object.
Dealing this in a more sophisticated way then just turning
off hinting requires understanding the text at a
sophisticated manner. (Like justification, you need to
know what white space in is important)
* Clipping is clearly a missing element in the API; without
a clip operator or functional equivalent, retargeting existing
PostScript code at Xr is going to be difficult.
Also, filling shapes with a gradient, image or pattern is
a pretty fundamental operation which doesn't seem to
be currently possible.
[Allowing clipping of a path by a path certainly does
create some implementation difficulties ... either Xr
would need a analytic path intersector like libart has,
or it would need to approximate the operation as perhaps
SRC IN (MASK IN CLIP) OVER DEST
Which is cheap in special-cased software (think RLE), but
possibly expensive via RENDER / in hardware.]
* It looks like the temporary surface created for XrPushGroup
will always have the same format as the parent surface;
I don't think this is right ... there are substantial
performance reasons why the parent surface should not
have alpha, but the temporary surface typically will
need to have alpha.
* I think it's probably necessary to be able to XrPushgroup
with a restricted size; the overhead of creating a full
size temporary pixmap could be sunstantial.
* It looks to me like on XrPopGroup, the group is composited
with the current alpha at the end of drawing the group,
rather than the alpha before pushing the group; I think this
is wrong - operations inside PushGroup/PopGroup shouldn't
affect drawing onto the parent surface.
* One thing that could be interesting would be to use the
current path (the path before PushGroup) as the mask when
compositing at PopGroup; the idea is that groups could
be seen as a generalization of the standard Fill operator
which is "source = color; mask = path/text" to
"source = arbitrary drawing operations; mask = path/text".
* Is it necessary to also generalize the mask in Xr as well?
Expressed "functionally" this would be a generalization of:
(xr-push-group (draw-the-source))
to:
(xr-push-group-mask (draw-the-source) (draw-the-mask))
I'm not sure how that translates to a reasonable C API -
maybe easiest just to expose the temporary buffers of
XrPushGroup/XrPopGroup as first-class objects
* There probably should be a convenience function to set colors
for a XRenderState from a XcColor. (Or maybe the
double/double/double one is the convenience function.)
* Does the stack nature of XrSave/Restore really make sense
outside the context of the Postscript language environment?
Conceptually they are equivalent to a copy operation,
and:
XrState *local = XrStateCopy (xrs);
/* Do stuff with local */
XrStateDestroy (locale);
is not significantly harder to type than the Save/Restore operation,
and considerably easier to map onto a a "graphics context"
concept.
On Xc:
* Once GTK+ is ported to use something like Xr for drawing graphics
primitives, the typical drawing pattern of GTK+ will be:
Create pixmap, fill it with a constant color
Draw on it with client side images, text, and Xr primitives
Blit it to the screen
Note that in this scenario, on legacy X servers, there is no reason
we ever have to get data from the server; which is a huge
win. What seems to be useful here is:
- A way to tell Xc that a newly created surface is a constant
color.
- A way to put Xc surface into a mode where there are explicit
operations to tell Xc:
- to flush it's internal buffers to the server
- to to invalidate it's internal buffers and force
it to refetch data from the server
And in absence of those operations, Xc is allowed to assume
that it can do all operations locally.
* GDK achieves significant efficiency win with unified management
of a cache of shared memory images / pixmaps that are used both
for writing images to the X server and reading data back off
the X server. It pays to use a pretty big cache here (GTK+
uses a 384k) and shared memory images are a scarce resource
on many systems, so it would really make sense not to duplicate
this between Xc and GDK.
There are three ways I can see to avoid this duplication:
1) Provide all operations GDK needs in Xc/Xr so that the GDK
code can be dropped entirely. The trouble here is that
GDK has a pretty big set of operations, with details
of the semantics that may not be desirable to expose
in Xr/Xc.
2) Expose some sort of shared image cache in the Xc
API that GTK+ could then use.
3) Virtualize the operations of getting data from a drawable
and writing data back to the drawable within Xc and allow
GDK to replace them.
Of these, 3) seems like the easiest and most sensible; it would
also provide a natural abstraction for creating non-X
XcSurfaces.
_______________________________________________
Render mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/render