You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pdfbox.apache.org by Andreas Lehmkühler <an...@lehmi.de> on 2010/03/19 12:23:56 UTC
Re: Re: PDFBox 1.1.0 release plan (Was: Next release & merging of trunks)
----- original Nachricht --------
Betreff: Re: PDFBox 1.1.0 release plan (Was: Next release & merging of trunks)
Gesendet: Fr, 19. Mrz 2010
Von: Maruan Sahyoun<sa...@fileaffairs.de>
> Hi,
>
> I'm inline with your thoughts that the patch works but is not completely
> inline with the spec. Would you mind showing your code so we can take a look
> as I was about starting to come up with something too?
No problem, but it has to wait until I'm back at home later in the evening.
BR
Andreas Lehmkühler
> Kind regards
>
> Maruan Sahyoun
>
>
> Am 19.03.2010 um 10:54 schrieb Andreas Lehmkühler:
>
> > Hi,
> >
> > Betreff: Re: PDFBox 1.1.0 release plan (Was: Next release & merging of
> trunks)
> > Gesendet: Do, 18. Mrz 2010
> > Von: Villu Ruusmann<vi...@gmail.com>
> >> Hello there,
> >>
> >>>
> >>> The following two open issues are currently targeted for 1.1.0:
> >>>
> >>> [PDFBOX-624] Misplaced text
> >>> [PDFBOX-663] Ensuring non-null FontDescriptor for external TrueType
> >> fonts
> >>>
> >>> Both are unassigned. Can we postpone these to later releases?
> >>>
> >>
> >> Both are "mine". They are solved (ie. the patchfiles are available)
> >> and are waiting for approval by other project members.
> >>
> >> Andreas has looked at PDFBOX-624 lately. The patch looked somewhat
> >> suspicious to him, because it employs simple Java casting instead of
> >> more complex bit manipulation. Any more experts here?
> > I puzzled about the specification:
> >
> > The chapter 3.2 "Charstring Number Encoding" contains the following
> statement:
> > "If the charstring byte contains the value 255, the next four bytes
> > indicate a two's complement signed number. The first of these
> > four bytes contains the highest order bits, the second byte
> > contains the next higher order bits and the fourth byte contains
> > the lowest order bits. This number is interpreted as a Fixed; that
> > is, a signed number with 16 bits of fraction."
> >
> > 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.
> >
> > Finally I don't want to object to villus patch. I will keep that issue in
> mind
> > and try to figure out if something is left to do or not.
> >
> > BR
> > Andreas Lehmkühler
>
>
--- original Nachricht Ende ----
PDFBOX-624: Calculating charstring number encoding (was: PDFBox 1.1.0
release plan )
Posted by Andreas Lehmkuehler <an...@lehmi.de>.
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
Re: PDFBox 1.1.0 release plan (Was: Next release & merging
of trunks)
Posted by Timo Boehme <ti...@ontochem.com>.
>>>> Andreas has looked at PDFBOX-624 lately. The patch looked somewhat
>>>> suspicious to him, because it employs simple Java casting instead of
>>>> more complex bit manipulation. Any more experts here?
>>> I puzzled about the specification:
>>>
>>> The chapter 3.2 "Charstring Number Encoding" contains the following
>> statement:
>>> "If the charstring byte contains the value 255, the next four bytes
>>> indicate a two's complement signed number. The first of these
>>> four bytes contains the highest order bits, the second byte
>>> contains the next higher order bits and the fourth byte contains
>>> the lowest order bits. This number is interpreted as a Fixed; that
>>> is, a signed number with 16 bits of fraction."
>>>
>>> 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.
-- Timo
Timo Boehme
OntoChem GmbH
H.-Damerow-Str. 4
06120 Halle/Saale
T: +49 345 4780472
F: +49 345 4780471
timo.boehme@ontochem.com
_____________________________________________________________________
OntoChem GmbH
Geschäftsführer: Dr. Lutz Weber
Sitz: Halle / Saale
Registergericht: Stendal
Registernummer: HRB 215461
_____________________________________________________________________
Re: PDFBox 1.1.0 release plan (Was: Next release & merging of trunks)
Posted by Maruan Sahyoun <sa...@fileaffairs.de>.
Hi,
that´s my approach - could be written a little shorter.
byte b1 = input.readByte();
byte b2 = input.readByte();
byte b3 = input.readByte();
byte b4 = input.readByte();
int retval = 0;
if ((b1 & (1<<3)) == 0) {
retval = (0xFF & b1) << 16;
retval |= (0xFF & b2) << 8;
retval |= (0xFF & b4);
} else {
retval = (0xFF) << 24;
retval |= (0xFF & b1) << 16;
retval |= (0xFF & b2) << 8;
retval |= (0xFF & b4);
}
return Integer.valueOf((short) retval);
Maruan Sahyoun
Am 19.03.2010 um 12:23 schrieb Andreas Lehmkühler:
>
> ----- original Nachricht --------
>
> Betreff: Re: PDFBox 1.1.0 release plan (Was: Next release & merging of trunks)
> Gesendet: Fr, 19. Mrz 2010
> Von: Maruan Sahyoun<sa...@fileaffairs.de>
>
>> Hi,
>>
>> I'm inline with your thoughts that the patch works but is not completely
>> inline with the spec. Would you mind showing your code so we can take a look
>> as I was about starting to come up with something too?
> No problem, but it has to wait until I'm back at home later in the evening.
>
> BR
> Andreas Lehmkühler
>> Kind regards
>>
>> Maruan Sahyoun
>>
>>
>> Am 19.03.2010 um 10:54 schrieb Andreas Lehmkühler:
>>
>>> Hi,
>>>
>>> Betreff: Re: PDFBox 1.1.0 release plan (Was: Next release & merging of
>> trunks)
>>> Gesendet: Do, 18. Mrz 2010
>>> Von: Villu Ruusmann<vi...@gmail.com>
>>>> Hello there,
>>>>
>>>>>
>>>>> The following two open issues are currently targeted for 1.1.0:
>>>>>
>>>>> [PDFBOX-624] Misplaced text
>>>>> [PDFBOX-663] Ensuring non-null FontDescriptor for external TrueType
>>>> fonts
>>>>>
>>>>> Both are unassigned. Can we postpone these to later releases?
>>>>>
>>>>
>>>> Both are "mine". They are solved (ie. the patchfiles are available)
>>>> and are waiting for approval by other project members.
>>>>
>>>> Andreas has looked at PDFBOX-624 lately. The patch looked somewhat
>>>> suspicious to him, because it employs simple Java casting instead of
>>>> more complex bit manipulation. Any more experts here?
>>> I puzzled about the specification:
>>>
>>> The chapter 3.2 "Charstring Number Encoding" contains the following
>> statement:
>>> "If the charstring byte contains the value 255, the next four bytes
>>> indicate a two's complement signed number. The first of these
>>> four bytes contains the highest order bits, the second byte
>>> contains the next higher order bits and the fourth byte contains
>>> the lowest order bits. This number is interpreted as a Fixed; that
>>> is, a signed number with 16 bits of fraction."
>>>
>>> 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.
>>>
>>> Finally I don't want to object to villus patch. I will keep that issue in
>> mind
>>> and try to figure out if something is left to do or not.
>>>
>>> BR
>>> Andreas Lehmkühler
>>
>>
>
> --- original Nachricht Ende ----
>