Hi Timo,

Timo Boehme schrieb:
AFAIU the spec, we have to use a combination of byte 1, 2 and 4. As it is
a two's complement, we have to build the one complement. And after that
we have to cut that result to a 16bit value. I've tried to implement some
code
to follow that path, but it didn't work yet. Probably I'm just wrong with
my
interpretation of the spec.

Villus implementation only uses byte 1 and 2. Looking at the spec it
seems
to be insufficient, but it works. So, at least it is a workaround.

I have written a CFF parser with a converter to Type1. From this I
copied the following lines which handle the 5 byte charstring number
encoding:

int val;
// ---- b0 == 255; 5 byte operand; signed fixpoint - lower 16 bit fraction;
// ---- since Type1 has no real type we ignore fraction here !
// ---- At least we warn if there is a fraction.
val  = _rawIn.read() << 24;
val |= _rawIn.read() << 16;
val |= _rawIn.read() << 8;
val |= _rawIn.read();
                                
if ( ( val & 0xffff ) != 0 ) {
        if ( logger.isLoggable( Level.FINE) )
                logger.fine( "Fraction will be rounded: " + ( ( val & 0xffff ) /
(float) 0x10000 ) );
        if ( ( val & 0x8000 ) != 0 ) {
                // highest fraction bit set - add 1 (should also be ok for 
negative
values)
                cmd.args.add( ( val >> 16 ) + 1 );
                                                
        } else {
                // fraction < 0.5 - ignore
                cmd.args.add( val >> 16 );
        }
} else
        cmd.args.add( val >> 16 );
}

As you can see I first read all bytes with the 2 integer bytes at high
order bits thus negative values are handled correctly (same two's
complement structure as in Java). Now I test if fraction bits are set.
Since in Type1 there is no number type 'real' I can't use fraction but
try to round it. In the end the integer part is shifted by two bytes
(sign bit remains unchanged).
You are welcome to adapt this code to your implementation. I don't have
the time yet but could do it in the next days.
After studying Timos code I finally understood the specification. The first
2 bytes are representing the digits on the left of the decimal point and the
other 2 bytes the digits after the decimal point. The bottom line is we
have to leave the last two bytes alone and just use the first two bytes.
So, Villus proposal hits the bull's eye.

Sorry for being slow on the uptake. Thanks to Timo and Maruan for their help.

BR
Andreas Lehmkühler


Reply via email to