From: Jouni K S. <jk...@ik...> - 2006-04-23 10:50:34
|
I hacked some more on the PDF backend, and now it embeds TrueType fonts. The positioning is still a bit off, but what looks like a bigger problem is how to get the /Widths array required by PDF. I've tried both the width and horiAdvance properties of font.load_char(ch), and in either case Acrobat Reader tells me the array is invalid. Opening the file in Mac OS X's Preview, adding an annotation and then saving the file changes the array to something acroread does not complain about (and it also subsets the font). It doesn't look like it's a simple scaling problem, since the ratio of correct width to either of my guesses is not constant. Any ideas? -- Jouni |
From: Jouni K S. <jk...@ik...> - 2006-04-25 20:09:05
|
Jouni K Seppanen <jk...@ik...> writes: > what looks like a bigger problem is how to get the /Widths array > required by PDF. I've tried both the width and horiAdvance > properties of font.load_char(ch), and in either case Acrobat Reader > tells me the array is invalid. It apparently has to be font.load_char(ch, LOAD_NO_SCALE), or at least that produces width values that look similar to those in files saved by Preview.app. But acroread still complains... I hacked the load_char method to accept a "flags" keyword parameter. I hope I didn't break anything; is it safe to use PyArg_ParseTupleAndKeywords with the C++ interface? -- Jouni |
From: John H. <jdh...@ac...> - 2006-04-25 20:15:55
|
>>>>> "Jouni" == Jouni K Seppanen <jk...@ik...> writes: Jouni> I hacked the load_char method to accept a "flags" keyword Jouni> parameter. I hope I didn't break anything; is it safe to Jouni> use PyArg_ParseTupleAndKeywords with the C++ interface? You shouldn't need to with the ft2font extension code, because it uses pycxx which has support for kwarg handling. Eg in the _image.cpp src Py::Object resize(const Py::Tuple& args, const Py::Dict& kwargs); Py::Object Image::resize(const Py::Tuple& args, const Py::Dict& kwargs) { _VERBOSE("Image::resize"); args.verify_length(2); int norm = 1; if ( kwargs.hasKey("norm") ) norm = Py::Int( kwargs["norm"] ); double radius = 4.0; if ( kwargs.hasKey("radius") ) radius = Py::Float( kwargs["radius"] ); //snip snip snip } so you can easily add kwarg handling by changing the declaration to accept a Py::Dict and then use the object with dictionary like semantics. In the init_type function, you'll need to declare your method as a kwarg method, eg add_keyword_method( "resize", &Image::resize, Image::resize__doc__); JDH |
From: Jouni K S. <jk...@ik...> - 2006-04-26 10:06:12
|
John Hunter <jdh...@ac...> writes: > You shouldn't need to with the ft2font extension code, because it uses > pycxx which has support for kwarg handling. Eg in the _image.cpp src > > Py::Object resize(const Py::Tuple& args, const Py::Dict& kwargs); [...] > args.verify_length(2); > > int norm = 1; > if ( kwargs.hasKey("norm") ) norm = Py::Int( kwargs["norm"] ); This seems to mean that the function cannot be called using the normal Python convention: >>> img.resize(10,10,1) Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: Unexpected SeqBase<T> length. Instead you have to do img.resize(10,10,norm=1). This is handled transparently by PyArg_ParseTupleAndKeywords: if you set the format string to "ii|ii" and list the names of all parameters as keywords, you automatically get the normal Python convention where the last two args are optional and all args are specifiable with their names. But I guess this is not so important in extension code that only gets called by matplotlib internals and not end users, so I changed load_char to use the pycxx convention. -- Jouni |
From: John H. <jdh...@ac...> - 2006-04-26 13:40:05
|
>>>>> "Jouni" == Jouni K Seppanen <jk...@ik...> writes: Jouni> John Hunter <jdh...@ac...> writes: >> You shouldn't need to with the ft2font extension code, because >> it uses pycxx which has support for kwarg handling. Eg in the >> _image.cpp src >> >> Py::Object resize(const Py::Tuple& args, const Py::Dict& >> kwargs); Jouni> [...] >> args.verify_length(2); >> >> int norm = 1; if ( kwargs.hasKey("norm") ) norm = Py::Int( >> kwargs["norm"] ); Jouni> This seems to mean that the function cannot be called using Jouni> the normal Python convention: >>>> img.resize(10,10,1) Jouni> Traceback (most recent call last): File "<stdin>", line Jouni> 1, in ? IndexError: Unexpected SeqBase<T> length. The reason it raises is because I told it too :-) args.verify_length(2); if you want normal python symantics, you could to something something like (untested, freestyle code) int norm(0); if (args.length()==3) norm = Py::Int( args[2] ); elif ( kwargs.hasKey("norm") ) norm = Py::Int( kwargs["norm"] ); Jouni> Instead you have to do img.resize(10,10,norm=1). This is Jouni> handled transparently by PyArg_ParseTupleAndKeywords: if Jouni> you set the format string to "ii|ii" and list the names of Jouni> all parameters as keywords, you automatically get the Jouni> normal Python convention where the last two args are Jouni> optional and all args are specifiable with their names. Jouni> But I guess this is not so important in extension code that Jouni> only gets called by matplotlib internals and not end users, Jouni> so I changed load_char to use the pycxx convention. I do think it is useful in the pycxx extension code to stick where possible to the cxx idioms -- for the most part the code is cleaner to reads and helps with reference counting, etc.... You can check the docs at http://cxx.sourceforge.net/PyCXX.html there may be a cleaner way to handle kwargs than what I suggested. JDH |
From: Jouni K S. <jk...@ik...> - 2006-04-26 15:03:44
|
Jouni K Seppanen <jk...@ik...> writes: > It apparently has to be font.load_char(ch, LOAD_NO_SCALE), or at least > that produces width values that look similar to those in files saved > by Preview.app. But acroread still complains... It seems that I can stop the complaining by forcing the /LastChar entry in the Font dictionary to be 255 instead of 258. The characters (in at least Bitstream Vera Sans) mysteriously seem to be numbered from 3 to 258, so I guess this must be some sort of an encoding issue. Does this ring a bell to anyone? -- Jouni |