Forums > MaxMSP

Typographical Teaser

January 26, 2008 | 1:05 am

I’m making an interface using LCD which has a selection of different words printed at different locations. The words are written using differing font sizes (as sprites). I want to be able to select a word by moving the mouse over it in order to move or size it depending on where on the word is clicked. I’m finding this to be quite tricky as i don’t know how work out how much space the word occupies on the screen. The people i’m working with have not decided on a particular font yet – and we may even end up using varying fonts. Is there something i’m overlooking? (apart from using fixed-width fonts, which i’d like to avoid if possible).

If anyone has any ideas i’m all ears…

Thanks,

John.


January 26, 2008 | 7:32 am

On 26 janv. 08, at 02:05, Leafcutter John wrote:

> I’m making an interface using LCD which has a selection of different
> words printed at different locations. The words are written using
> differing font sizes (as sprites). I want to be able to select a
> word by moving the mouse over it in order to move or size it
> depending on where on the word is clicked. I’m finding this to be
> quite tricky as i don’t know how work out how much space the word
> occupies on the screen. The people i’m working with have not decided
> on a particular font yet – and we may even end up using varying
> fonts. Is there something i’m overlooking? (apart from using fixed-
> width fonts, which i’d like to avoid if possible).

If you assign a different color to each text, It might be easy to use
the getpixel message to get the color value, unless transparency is
involved…

ej


January 26, 2008 | 10:09 am

On 26-jan-2008, at 1:05, Leafcutter John wrote:

>
> I’m making an interface using LCD which has a selection of
> different words printed at different locations. The words are
> written using differing font sizes (as sprites). I want to be able
> to select a word by moving the mouse over it in order to move or
> size it depending on where on the word is clicked. I’m finding this
> to be quite tricky as i don’t know how work out how much space the
> word occupies on the screen. The people i’m working with have not
> decided on a particular font yet – and we may even end up using
> varying fonts. Is there something i’m overlooking? (apart from
> using fixed-width fonts, which i’d like to avoid if possible).
>
> If anyone has any ideas i’m all ears…
>
> Thanks,
>
> John.

One way to do this is to keep a record of the bounding box of each word.
the bounding box you may calculate as follows:
- get the pen loc just before and right after drawing the text
string. the difference is the width of the bounding box
- the height of the bounding box you estimate by using the font size.
this may not be entirely acurate.

then you have to do a "hit detection" by comparing the mouse location
to the bounding boxes.
If you do this in a straightforward linear search, you may run into
performance problems.
One option is to have two additional data structures, one that keeps
the bounding boxes sorted on their X
coordiante and one that is sorted on Y. This allows you to quickly
eliminate boxes that you need not try to match.
This is a textbook problem in interactive computer graphics, but it
may seem overwhelming when you do not have
a computer science background. I do not know what yours is.

The other option is to have a second LCD (off screen) where you
actually draw the bounding boxes, each with a different color,
and you keep a coll of what colour belongs to what word. For every
mouse move in the first lcd, you move the pen to the same position in
the
second and query the pixel colour and look it up in the coll.
This I expect would have a much more performance than the first option.

HtH
-jennek


January 26, 2008 | 4:55 pm

Leafcutter John schrieb:
> I’m finding this to be quite tricky as i don’t know how work out how
> much space the word occupies on the screen.

I am longing for this for a long time as well, indispensible for
scripting. It would alow me to make my MaxOverview a bit nicer…

> If anyone has any ideas i’m all ears…

As it doesn’t seem to exist, I would look for reading in a complete
font, somewhere in the font description must be an information about the
size of each letter. Depending on the overall length of the text, a
rough estimation could be sufficient as well. We all know that an "i" is
shorter than an "A"…
Maybe ther does exist a Java library which does that already…???

I am all ears as well…

Stefan


Stefan Tiedje————x——-
–_____———–|————–
–(_|_ —-|—–|—–()——-
– _|_)—-|—–()————–
———-()——–www.ccmix.com


January 27, 2008 | 1:28 am

ej,

I had tried that idea – in theory its a good one – but i found it was difficult to select words with thin letter stems esp at lower font sizes. Also the area between the letter and the background causes problems as the text is anti aliased and colour readings change there.

Jennek,

I actually dreamt the penloc solution last night after starting this thread i woke up with a picture of the LCD entry in the Max reference manual in my mind (my subconscious was screaming RTFM!). I am very grateful to you for taking the time to explain the offscreen LCD idea as i had never heard of this before. I’m sure it will be much more efficient that the linear search i was doing before. So thanks a million you have really helped me.

Best to all,

John.


January 28, 2008 | 10:22 pm

jennek geels schrieb:
> – get the pen loc just before and right after drawing the text string.
> the difference is the width of the bounding box

This might not affect the original problem of that thread, as there the
LCD will be visible, but:
I tried to make an abstraction to measure the size of a given text by
writing it into a LCD, and then send it the penloc command. That works
wonderful, as long as the patcher containing the LCD is open. If the
patcher is closed, penloc will not report anything. This is very
unfortunate, because opening a window and then closing it again only to
get the pen location seems very awkward…
I’d love to see a way to force LCD doing its drawing also if the patcher
is closed…
At the moment it seems to wait till it gets an update command from Max
to start its drawing… (which is optimal if you want to see the LCD,
but I want to abuse the LCD to get the size… :-(

This for an explanation:

save this as textsize.mxb

#P window setfont "Sans Serif" 9.;
#P window linecount 2;
#P newex 83 79 44 196617 prepend textface;
#P outlet 162 209 15 0;
#P inlet 37 37 15 0;
#P newex 37 79 41 196617 prepend font;
#P window linecount 1;
#P newex 37 57 102 196617 route font textface;
#P newex 162 187 50 196617 unpack;
#P newex 162 165 62 196617 route penloc;
#P newex 161 124 73 196617 prepend write;
#P newex 129 79 74 196617 t getpenloc l b;
#P message 193 101 73 196617 moveto 0 -10;
#P user lcd 129 152 43 8 0 1 0 1 1;
#P connect 8 0 6 0;
#P connect 6 0 7 0;
#P connect 6 1 10 0;
#P connect 6 2 2 0;
#P fasten 10 0 0 0 88 146 134 146;
#P fasten 7 0 0 0 42 146 134 146;
#P fasten 1 0 0 0 198 120 134 120;
#P connect 2 0 0 0;
#P fasten 3 0 0 0 166 146 134 146;
#P connect 2 1 3 0;
#P connect 0 3 4 0;
#P connect 4 0 5 0;
#P connect 5 0 9 0;
#P connect 2 2 1 0;
#P window clipboard copycount 11;

And this as textsize.help…

#P button 81 199 15 0;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 201 78 89 196617 prepend textface;
#P user umenu 201 57 53 196647 1 64 73 1;
#X add normal;
#X add bold;
#X add italic;
#X add underline;
#X add outline;
#X add shadow;
#X add condense;
#X add extend;
#P number 163 57 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 81 15 46 196617 loadbang;
#P user umenu 81 56 80 196647 1 192 72 1;
#X add;
#P newex 81 35 46 196617 fontlist;
#P newex 81 79 92 196617 pak font Arial 18;
#P message 158 101 83 196617 A LOT OF AAAAs;
#P number 81 178 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 81 149 50 196617 textsize;
#P message 91 101 64 196617 a lot of iiiis;
#P window linecount 3;
#P comment 145 150 151 196617 this will only work after opening the
textsize subpatcher with a double click;
#P connect 3 0 12 0;
#P connect 4 0 2 0;
#P connect 1 0 2 0;
#P fasten 11 0 2 0 206 98 86 98;
#P connect 5 0 2 0;
#P connect 2 0 3 0;
#P fasten 10 1 11 0 249 75 206 75;
#P connect 9 0 5 2;
#P fasten 7 1 5 1 156 75 127 75;
#P connect 6 0 7 0;
#P connect 8 0 6 0;
#P window clipboard copycount 13;


Stefan Tiedje————x——-
–_____———–|————–
–(_|_ —-|—–|—–()——-
– _|_)—-|—–()————–
———-()——–www.ccmix.com


January 28, 2008 | 11:35 pm

On 28-jan-2008, at 23:22, Stefan Tiedje wrote:

> I tried to make an abstraction to measure the size of a given text
> by writing it into a LCD, and then send it the penloc command. That
> works wonderful, as long as the patcher containing the LCD is open.
> If the patcher is closed, penloc will not report anything. This is
> very unfortunate, because opening a window and then closing it
> again only to get the pen location seems very awkward…
> I’d love to see a way to force LCD doing its drawing also if the
> patcher is closed…
> At the moment it seems to wait till it gets an update command from
> Max to start its drawing… (which is optimal if you want to see
> the LCD, but I want to abuse the LCD to get the size… :-(

ah, this is very unfortunate indeed.
maybe you can force drawing by sending a "writepict /dev/null" ?
but this is becoming more and more tricky.

anyway, what you really want is a stringwidth message, reporting the
width of a string
with the current font settings without drawing anything. like
PostScript has.

-jennek


January 29, 2008 | 1:10 pm

Quote: Jennek Geels wrote on Mon, 28 January 2008 23:35
—————————————————-

> anyway, what you really want is a stringwidth message, reporting the
> width of a string
> with the current font settings without drawing anything. like
> PostScript has.
>
> -jennek
>
—————————————————-

Yes this would be amazing! In my tests i found the getpenloc reporting to be very slow considering i have to do it for upwards of 100 words.

j.


January 29, 2008 | 6:41 pm

There’s a set of objects called DIPS, making use of openGL. Quite a different route – you might give it a try.

http://dips.dacreation.com/

_
johan


January 29, 2008 | 6:43 pm

>> anyway, what you really want is a stringwidth message,
> Yes this would be amazing! In my tests i found the getpenloc
> reporting to be very slow considering i have to do it for upwards
> of 100 words.

the problem is that it is not easy to build your own on Max.
the string width not only depends on the font metrics (width per
character,
and kerning of character pairs for true typographical sophistication)
but also on the line setting algorithm:
- rounding errors, error diffusion
- subpixel addressing
- and maybe some more tricks
Moreover, this is dependent on the script (western style left to
right, arabic, japanese, …).
In PostScript the stringwidth is an x y pair for that reason.


so make this a feature request for a future release of LCD:
provide a ‘stringwidth’ message that returns an integer
representing the width of the string made up of all the symbols that
follow the
stringwidth keyword, based on the current font settings.

and while we’re at it:
provide a ‘bbox’ message that returns an x y pair of integers
representing the bounding box of the string.

both messages would have to compute even if LCD is hidden.

-jennek


January 29, 2008 | 9:18 pm

DIPS is/are GREAT! Installed easily. Very clear structure. Nice examples
and tutorials. Special help features that make it very easy to explore.

Cheers
Gary Lee Nelson
Oberlin College
http://www.timara.oberlin.edu/GaryLeeNelson

On 1/29/08 1:41 PM, "jvkr" wrote:

>
> There’s a set of objects called DIPS, making use of openGL. Quite a different
> route – you might give it a try.
>
> http://dips.dacreation.com/
>
> _
> johan


January 29, 2008 | 11:02 pm

jennek geels schrieb:
> anyway, what you really want is a stringwidth message, reporting the
> width of a string with the current font settings without drawing
> anything. like PostScript has.

Yes, exactly I hoped this LCD would do the trick, but it doesn’t… :-(

Stefan


Stefan Tiedje————x——-
–_____———–|————–
–(_|_ —-|—–|—–()——-
– _|_)—-|—–()————–
———-()——–www.ccmix.com


January 29, 2008 | 11:23 pm

I have decided to go with jitter to display my floating words but i’m having a problem due to my lack of knowledge in this area.

I’m using jit.gl.text2d to render the words and trying to move them round the jit.pwindow in response to mousedown in the same window. The problem is that the jit.pwindow spits out pixel coordinates like LCD but the jit.gl.text2d objects want a float number as position input. The number seems to be some sort of scaled value related to the size of the jit.pwindow but i cant seem to figure out the relationship – Anyone know??

Thnaks,

John.


January 30, 2008 | 2:52 am

Coordinates in OpenGL originate in the centre point of your drawing
context, going 1 unit to the borders of the drawing area (on the zero
plane, where your z position = 0). That means that the visible area
(on the zero plane) is 2 units wide and high with the origin at its
centre. That said, converting pixels to GLworld is then straight
forward: xGL = xPixel/widthPixel * 2 – 1 and respectively for y.

c

On 29 Jan 2008, at 23:23, Leafcutter John wrote:

>
> I have decided to go with jitter to display my floating words but
> i’m having a problem due to my lack of knowledge in this area.
>
> I’m using jit.gl.text2d to render the words and trying to move them
> round the jit.pwindow in response to mousedown in the same window.
> The problem is that the jit.pwindow spits out pixel coordinates
> like LCD but the jit.gl.text2d objects want a float number as
> position input. The number seems to be some sort of scaled value
> related to the size of the jit.pwindow but i cant seem to figure
> out the relationship – Anyone know??
>
> Thnaks,
>
> John.
> –
> http://www.leafcutterjohn.com
>
> "The Forest And The Sea"
> Out on Staubgold Records
> Staubgold 68 CD/LP


January 30, 2008 | 4:41 am

Quote: c@klingt.org wrote on Wed, 30 January 2008 02:52
—————————————————-
>
> Coordinates in OpenGL originate in the centre point of your drawing
> context, going 1 unit to the borders of the drawing area (on the zero
> plane, where your z position = 0). That means that the visible area
> (on the zero plane) is 2 units wide and high with the origin at its
> centre. That said, converting pixels to GLworld is then straight
> forward: xGL = xPixel/widthPixel * 2 – 1 and respectively for y.
>

Thanks for the explanation, however i’m still having trouble implementing it and it’s a quarter to 5 in the morning which is not helping matters. This is what i have so far – as you can see it is still not tracking correctly. If someone could point out my error i’d be very happy.

#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 188 79 132 196617 expr (($f1/800.) * 2.) -1.;
#P newex 321 79 164 196617 expr ((($f1/300.) * 2.) -1.) *-1.;
#P newex 188 52 58 196617 unpack 0 0;
#P newex 188 31 44 196617 r idleee;
#P flonum 266 106 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 228 106 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 188 106 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P window linecount 2;
#P newex 159 152 256 196617 jit.gl.gridshape display @shape circle @layer 4 @scale 0.01 0.01 0.01 @color 1 0.4 0.6 1 @blend_enable 1;
#B color 5;
#P window linecount 1;
#P newex 159 128 99 196617 pak position 0. 0. 1.;
#P newex 464 587 44 196617 s idleee;
#P newex 465 567 48 196617 pack 0 0;
#P number 502 549 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P number 465 549 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 484 523 249 196617 unpack 0 0 0 0 0 0 0 0;
#P newex 555 497 110 196617 route mouse mouseidle;
#P newex 20 108 43 196617 jit.qball;
#P newex 19 129 50 196617 t b erase;
#P toggle 20 65 15 0;
#P newex 20 87 51 196617 metro 10;
#P newex 19 153 100 196617 jit.gl.render display;
#P user jit.pwindow 0 187 802 302 1 0 1 0 0 0;
#X name display;
#P comment 304 107 100 196617 < - 1?;
#P connect 13 0 14 0;
#P fasten 19 1 20 0 241 74 326 74;
#P fasten 20 0 16 0 326 101 233 101;
#P connect 21 0 15 0;
#P connect 19 0 21 0;
#P fasten 17 0 13 3 271 123 251 123;
#P fasten 16 0 13 2 233 123 222 123;
#P connect 15 0 13 1;
#P connect 9 0 11 0;
#P connect 18 0 19 0;
#P connect 6 0 5 0;
#P connect 4 0 3 0;
#P connect 3 0 6 0;
#P fasten 5 1 2 0 64 149 24 149;
#P connect 5 0 2 0;
#P connect 11 0 12 0;
#P connect 10 0 11 1;
#P fasten 8 0 9 0 489 544 470 544;
#P fasten 1 1 7 0 796 492 560 492;
#P fasten 7 0 8 0 560 518 489 518;
#P fasten 7 1 8 0 610 518 489 518;
#P fasten 8 1 10 0 523 544 507 544;
#P window clipboard copycount 22;


January 30, 2008 | 7:41 am

> Thanks for the explanation, however i’m still having trouble
> implementing it and it’s a quarter to 5 in the morning which is not
> helping matters. This is what i have so far – as you can see it is
> still not tracking correctly. If someone could point out my error
> i’d be very happy.

add @transform_reset 2 to the gridshape object.

now that you go with jitter, you are better off asking questions in
the jitter forum.

HtH
-jennek


January 30, 2008 | 2:09 pm

jvkr schrieb:
> There’s a set of objects called DIPS, making use of openGL. Quite a
> different route – you might give it a try.

Ah, another lib I didn’t know of yet, will include it into my Overview…

Stefan


Stefan Tiedje————x——-
–_____———–|————–
–(_|_ —-|—–|—–()——-
– _|_)—-|—–()————–
———-()——–www.ccmix.com


January 30, 2008 | 6:30 pm

On 30-jan-2008, at 14:29, Stefan Tiedje wrote:

> jennek geels schrieb:
>> so make this a feature request for a future release
>> of LCD: provide a ‘stringwidth’ message that returns an integer
>> representing the width of the string made up of all the symbols that
>> follow the stringwidth keyword, based on the current font settings.
>
> My feature request would be much simpler, instead of blowing up
> LCD, I’d prefer seperate text manglin objects (a lack at the
> moment) a bit like zl, but for text, including a textwidth which
> would give me the width of a text.
> The precision you are talking about, is at least for me, a pretty
> low priority, I would be happy to get it roughly in pixels. Minor
> errors, because of ignorance for kerning an alike would not bug me,
> it would only be some pixels…

OK, let me rephrase the feature request.
the implementor of stringwidth need not write new code.
the same code that is responsible for the actual drawing of the
string has "stringwidth" calculations built in.
just copy and paste – comment out the actual drawing — done (more or
less).

in this way you get exactly the same width — either while drawing or
not.

-jennek


January 30, 2008 | 6:39 pm

DIPS is good stuff…

Lars

Stefan Tiedje skrev:
> jvkr schrieb:
>> There’s a set of objects called DIPS, making use of openGL. Quite a
>> different route – you might give it a try.
>
> Ah, another lib I didn’t know of yet, will include it into my Overview…
>
> Stefan
>


January 31, 2008 | 11:29 pm

Stefan Tiedje schrieb:
> instead of blowing up LCD, I’d prefer seperate text manglin objects

For the time being I’ll use jit.LCD, which works fine. It is already the
requested "blown up" LCD:

the new textsize:

#P window setfont "Sans Serif" 9.;
#P window linecount 2;
#P newex 83 79 44 196617 prepend textface;
#P outlet 230 219 15 0;
#P inlet 37 37 15 0;
#P newex 37 79 41 196617 prepend font;
#P window linecount 1;
#P newex 37 57 102 196617 route font textface;
#P newex 230 197 50 196617 unpack;
#P newex 230 175 64 196617 route penloc;
#P newex 175 125 73 196617 prepend write;
#P newex 129 79 79 196617 t b getpenloc l b;
#P message 198 101 60 196617 moveto 0 0;
#P newex 129 152 111 196617 jit.lcd 4 char 320 64;
#P connect 8 0 6 0;
#P connect 6 0 7 0;
#P connect 6 1 10 0;
#P connect 6 2 2 0;
#P fasten 3 0 0 0 180 146 134 146;
#P fasten 1 0 0 0 203 120 134 120;
#P fasten 7 0 0 0 42 146 134 146;
#P fasten 10 0 0 0 88 146 134 146;
#P connect 2 0 0 0;
#P fasten 2 1 0 0 157 108 134 108;
#P connect 2 2 3 0;
#P connect 2 3 1 0;
#P connect 0 1 4 0;
#P connect 4 0 5 0;
#P connect 5 0 9 0;
#P window clipboard copycount 11;


Stefan Tiedje————x——-
–_____———–|————–
–(_|_ —-|—–|—–()——-
– _|_)—-|—–()————–
———-()——–www.ccmix.com


Viewing 20 posts - 1 through 20 (of 20 total)