| Reply | « Previous Thread | Next Thread » |
|
I've been playing with graphics.text() function lately
text(coordseq, text [, fill=0, font=u”LatinBold12” ]) I noticed that the fill (color) and font are not sticky, so if you don't want the black default font, you need to specify those for each call. Personally, I'd prefer those to be sticky, so once changed it would stay until changed again. Another change I'd like to see is the is the ability to specify a sequence of text items, corresponding to coordseq in the beginning. Now I can do: g.text([(0,10), (0,30)], "hello") which will write me 'hello' twice. In addition to this I'd like to have the following: g.text([(0,10), (0,30)], ["hello","girl"]) Something to measure the text size would also be nice. I've actually implemented for my own use textsize(text, [font]) which returns the (width,height) tuple of the text. I can implement all of the above and provide a patch if there is interest. Btw. I wonder if I should post this as a sf tracker item instead of here? /bacademy PS. I've gone through the hoops to successfully compile appui and graphics modules on Linux with sdk2unix for 1st and 2nd edition phones. In case there is more general interest, I could document that process. |
|
The APIs we have so far aren't perfect - they're first drafts and could be changed in the future after the 1.4 release. I'm thinking out loud here - comments are welcomed.
Stateful or stateless - that is the question we thought about a lot when defining the graphics module API. Eventually we decided on a stateless API. Some benefits include: - being able to see the behaviour of a given call exactly from the parameters - not having to deal with saving, restoring or representing state on Python side I've been having some second thoughts though, since there are valid reasons for having a separate graphics context object with state: - Support for clipping and scaling is naturally stateful, and being able to draw to the same surface through two contexts with different scaling and clipping parameters is often useful for example to deal with different screen sizes. (Support for a generic affine transform would be cool, but I don't know if there are significant use cases beyond function graphing and games utilizing retro vector graphics.) - There are performance advantages to not having to parse as many parameters at each call. - The native side graphics context is itself stateful. For state management there are a few options: 1. Remove arguments that set state from all drawing primitives. All state must be set before invoking the primitives. + clear, simple code: well aligned with the current native OS code + code clearly divided into functions that alter state and functions that don't + clean drawing primitive function signatures - a bit more calls needed for most operations. - necessary API breakage 2. Keep the possibility to pass keyword arguments that set state to drawing primitives. In this case there are two options: 2a. State setting arguments in primitives act on that primitive alone, and the state of the context is restored after the call + possibility for compatibility with existing API + code clearly divided into functions that alter state and functions that don't + compact, easy to read Python code - more complexity in wrapper code: need to maintain and save/restore state. performance implications? - messy function signatures, complex argument parsing. 2b. State setting arguments in primitives change the state of the context. The change is persistent and applies to all subsequent primitives that don't themselves specify different state parameters. + simple to implement: just leave out state restoration from the existing wrapper code. - no possibility of compatibility with old Python code - all functions potentially mess up state. - necessary API breakage. - messy function signatures, complex argument parsing. N.b. What we have now is 2a without any state changing functions. Now, if we were to make some changes, some problems come to mind: - API breakage. Is it possible to reconcile this with existing usage in a way that doesn't break old code? If not, should we just remove the old API or keep it for old apps for some time? How should we introduce the new API? Should we dig up the old graphics.Draw() function and have it return a "new style" graphics context and keep the existing Image and Canvas methods as such? - The native side graphics context doesn't provide the possibility to read back its state. Choice 2a would force us to maintain a separate copy of the state in the Python wrapper object so we could restore it. The way how the state is set is a matter of taste and subject to bikeshed arguments. Should it be: Code:
d.fill=0xff0000
d.font='title'
d.text((10,10),u'Foo')
d.text((10,30),u'Bar')
or
d.setfill(0xff0000)
d.setfont('title')
d.text((10,10),u'Foo')
d.text((10,30),u'Bar')
or
d.set(fill=0xff0000, font='title')
d.text((10,10),u'Foo')
d.text((10,30),u'Bar')
PS. Yes, the scalable font support and text measuring support is coming. |
|
A few more notes on drawing text...
There already is an implementation of both scalable font support for text and measure_text, a function that returns the extents of a given piece of text rendered with the given font. However, I think what people really want is not the ability to measure how large a given piece of text is as such - that's just a tool to perform some higher level task, and for performance and convenience reasons I think we should provide to Python as high level an API as we can. The question is now what are the higher level use cases? The primary one I have on my mind is rendering a block of text to a given area on the screen, with different fonts for different parts of the text. Instead of using measure_text directly would it be better to directly provide a native primitive that renders as much of the given text as possible into a given area, starting from the given cursor position and returning the number of characters consumed, and the new cursor position? This function could provide the possibility to write a relatively efficient rich text widget in Python. Are there other important use cases that wouldn't be a subset of that? |
|
bacademy, I have tinkered something to graphics myself too.
Check it out at: http://jtoivola.googlepages.com/pyth...hancedgraphics Or forum thread: http://discussion.forum.nokia.com/fo...anced+graphics ---- Quote:
Quote:
Quote:
Quote:
Last edited by GameDude : 2007-05-23 at 17:57.
|
|
I'd vote for stateful API, with some reasonable default state existing.
As to initialization, I'd go for keyword args based approach. My current use case is text layout, something what a word processor preview or HTML rendering would require. GameDude, your enhanced module seems to do pretty much everything I was looking for. I just hadn't noticed that you had added 2nd edition support. /bacademy |
|
Quote:
The Graphics API should be mainly stateless, because you can always make a stateful wrapper around the API. Doing it other way around you'll just create a mess. Example for a stateful wrapper: http://discussion.forum.nokia.com/fo...t=textrenderer Complex operations, which cannot be described with one function call, shoud have stateful parameter classes. For example, this kind of operations are image transforms (matrix, set-up, color spaces) and so on. Mikko Ohtamaa Twinapex Research http://www.twinapex.com |
| Reply | « Previous Thread | Next Thread » |
| Thread Tools | Search this Thread |
|---|---|
| Rate This Thread | |
| Thread | Thread Starter | Forum | Replies | Last Post |
|---|---|---|---|---|
| Is there a C++ API for the video player | avbrozhko | General Symbian C++ | 9 | 2008-06-06 15:34 |
| Cryptography (cryptalg) API on Series 60? | cbrueckner | Symbian Networking & Messaging | 20 | 2006-10-31 13:05 |
| Cryptography (cryptalg) API on Series 60? | cbrueckner | General Symbian C++ | 0 | 2003-05-08 12:16 |
| Cryptography (cryptalg) API on Series 60? | cbrueckner | Symbian Tools & SDKs | 0 | 2003-05-08 12:12 |
| Change to NMSS SDK API and Library | jhayc | General Messaging | 0 | 2003-04-11 12:46 |