RE : layout patch - transform handling needed

From: Tomas Frydrych (tomas@frydrych.uklinux.net)
Date: Wed Feb 19 2003 - 05:04:25 EST

  • Next message: Kenneth J. Davis: "Re: Win32 STABLE build needed"

    Hi guys,

    This is rather a longish posting, but please bear with me to the end
    where I make some practical suggestions.

    Joaquin wrote:
    > > > Again, this is not right. In particular, requesting screen font at
    > > > real_size = size*zoom results in incorrect scaling (because font
    > > > metric does not scale linearly with size). This seems to me to be
    > > > precisely what we have done in the past, and what does not work.
    >
    > Tomas, here you're slightly wrong.
    > If we have a font at 12pt, then the requested "size" of the font
    > should be 12 points, whatever the zoom. To get a bigger font (still
    > at 12pt), you can change the resolution in which you want the font.
    > Now, except for some MM fonts with optical scaling (if computer modern
    > had a MM version, then it will qualify), that's exactly equivalent to
    > requesting the font at size * zoom.

    You are right, Joaquin, that to get the bigger font we have to
    notionally adjust the resolution, but adjusting the size by the zoom
    factor is _not_ equivalent to changing the resolution by the zoom
    factor. To avoid the non-linearity, the scaling has to be done
    (knowingly) by the font renderer, it cannot be done by ourselves
    before the rendering.

    So, if we have 8pt font and 72dpi device and want zoom of 500%,
    the font renderer has to be rendering 8pt font as if the device used
    360dpi and then output the bit image on the 72dpi device. We can
    either use some kind of a tranform mechanism the renderer
    provides to achieve this, or, we have to make the renderer believe
    that the device resolution is 360dpi. What we do now is ask the
    renderer to render 40pt font to 72dpi device.

    The non-linearity _does_ matter because although we now do the
    layout with the correct metrics (and that is obvoiously a major step
    forward), at zoom other than 100% the system is using different
    metrics for drawing on screen than that which we used to calculate
    the layout.

    Dom wrote:
    > Yeah, we all know what transforms are. And, with a
    > teensy bit of work, the PS class could support such
    > things trivially. However, our GDK/FontConfig drawing
    > functions are *incapable* of doing that.

    FT2 has an api for transforms, and so if xft does not, we should file
    an xft bug. However, just because we cannot do this on Unix, we
    should not force the Unix limitations on the XP code. Since
    transform is the standard, and also most efficient, way in which
    scaling should be handled, we should have the XP code assuming
    transforms and then the platform code implementing the behaviour in
    whatever manner is best on the given platform.

    The present approach de facto penalises platforms that can handle
    transforms properly. On such a system once you set a transform for
    the canvas, you need not to worry about anything to do with zoom:
    one zoom event == one system call that applies until the next zoom
    event. The present approach does not allow us to do that, since it
    assumes that the zoom factor is taken into account on each
    individual drawing operation. The effect of scaling via a system
    transform is that the physical size of the device unit changes, but
    not the relationship between the number of layout units and device
    units. This means that the current XP versions of the ::tdu() and
    ::tlu() would not work. It would seem to me that the correct thing to
    do is to have the the 'normal' case in the XP versions and the
    'abnormal' cases in the platform code. The 'normal' case (using
    transform) is

        DU = layoutUnits * getDeviceResolution() / getResolution();

    The basic assumption in handling zoom in the XP code should be
    that zoom is an event, rather than a state; the zoom mechanism
    should work like this:

    zoom event -> create transform -> pass down to gr_Graphics -> let
    the platform GR class decide what to do about it:
        - on platforms supporting transforms issue system call and
          forget all about it
        - on other platforms, do whatever it takes (e.g., use the trasform
          inside platform-specific ::tdu() and ::tlu(), etc.).

    This seems to me to be the most generic approach. The changes
    requried are quite small, initially just making use of the transform
    class and shifting the zoom calculations from gr_Graphics to
    platform code. Unless there are any serious objections, I am going
    to do this.

    Tomas



    This archive was generated by hypermail 2.1.4 : Wed Feb 19 2003 - 05:12:00 EST