[GRASS-dev] iconv a required dependency for using Freetype?

As mentioned in an earlier e-mail, I thought I'd try and see if I can get
Freetype font support working on native Windows. Came across the error
message below in lib/driver. As far as I can see it is because I don't
have iconv installed, but the section of the source is only
conditionalised on HAVE_FT2BUILD_H. I'm wondering if the bits that
reference convert_str (which presumably does translation) could safely be
conditionalised on HAVE_ICONV_H, or does anybody know if the
interdependency between Freetype and iconv goes deeper than that?

sh-2.04$ cd lib/driver
sh-2.04$ make
gcc -I/c/grass/grass6/dist.i686-pc-mingw32/include -I/c/grass/extra/include -g -
O2 -I/c/grass/extra/include -DPACKAGE=\""grasslibs"\" -I/c/grass/extra/inc
lude/freetype2 -DPACKAGE=\""grasslibs"\" -I/c/grass/grass6/dist.i686-pc-ming
w32/include \
          -o OBJ.i686-pc-mingw32/text3.o -c text3.c
text3.c: In function `convert_str':
text3.c:139: error: `iconv_t' undeclared (first use in this function)
text3.c:139: error: (Each undeclared identifier is reported only once
text3.c:139: error: for each function it appears in.)
text3.c:139: error: syntax error before "cd"
text3.c:157: error: `cd' undeclared (first use in this function)
make: *** [OBJ.i686-pc-mingw32/text3.o] Error 1

Paul Kelly wrote:

As mentioned in an earlier e-mail, I thought I'd try and see if I can get
Freetype font support working on native Windows. Came across the error
message below in lib/driver. As far as I can see it is because I don't
have iconv installed, but the section of the source is only
conditionalised on HAVE_FT2BUILD_H. I'm wondering if the bits that
reference convert_str (which presumably does translation) could safely be
conditionalised on HAVE_ICONV_H, or does anybody know if the
interdependency between Freetype and iconv goes deeper than that?

d.text.freetype already handles the lack of iconv(); look at
convert_text() in d.text.freetype/main.c.

You just need a hard-coded conversion to UCS-2 for the case where
iconv() is unavailable. ISO-8859-1 -> UCS-2 (used by d.text.freetype)
is trivial; a built-in UTF-8 -> UCS-2 converter wouldn't be a lot of
work.

Alternatively, you could use mbstowcs() to convert according to the
current locale.

--
Glynn Clements <glynn@gclements.plus.com>

On Sat, 5 May 2007, Glynn Clements wrote:

You just need a hard-coded conversion to UCS-2 for the case where
iconv() is unavailable. ISO-8859-1 -> UCS-2 (used by d.text.freetype)
is trivial; a built-in UTF-8 -> UCS-2 converter wouldn't be a lot of
work.

Thanks for the hint - that seems to have worked out fine and I've already committed the fix.

I've attached a diff of a few more changes I'm considering making, mostly relating to path and filename handling for Windows compatibility in loading fonts. Here's what I've changed so far:

lib/driver/Font.c, COM_Font_get():
* Cross-platform check for absolute path (new gislib function added)
* Check for pathname matching the GRASS stroke fonts made more robust by
   (a) First converting all directory separator characters to '/'
   (b) Doing a case-insensitive comparison

lib/driver/font2.c, read_fontmap():
* Warning message when unable to open font made clearer by specifying
the exact path it was trying to open and giving the system error message.

font_init():
* Convert directory separator characters to '/' so that the way the directory name is stripped off works
* Strip off the ".hmp" extension if it was there. It strikes me as very
weird that I needed to do this, because without that I reall can't see how passing the full path to one of the GRASS stroke fronts would have worked. The full filename has to be given in the GRASS_FONT variable, otherwise the font_exists() check in COM_Font_get() will fail, but the .hmp is never stripped off and then it is added again in read_fontmap(), resulting in it trying to open a file ending in ".hmp.hmp".

I haven't committed the changes yet as they're not complete. Apart from
being unsure about stripping off the .hmp extension, specifying a
font in GRASS_FONT from the freetypecap file doesn't work. I'm just
testing this from the command line on Windows, i.e. using direct
rendering as drivers don't work, and I can't see where/if the freetypecap file is actually being read. Specifying the full path to a Freetype font
works fine, but is the freetypecap file only read when a driver process
is initialised?

(attachments)

diff.txt (3.8 KB)

Paul Kelly wrote:

On Sat, 5 May 2007, Glynn Clements wrote:

I've attached a diff of a few more changes I'm considering making, mostly
relating to path and filename handling for Windows compatibility in
loading fonts. Here's what I've changed so far:

lib/driver/Font.c, COM_Font_get():
* Cross-platform check for absolute path (new gislib function added)
* Check for pathname matching the GRASS stroke fonts made more robust by
   (a) First converting all directory separator characters to '/'
   (b) Doing a case-insensitive comparison

That last point is probably safe, in that you're unlikely to have
another directory which differs only in case on Unix.

Although, in this case, I'd be inclined to simply remove the option to
specify a stroke font using a full path. Personally, I doubt that this
feature would ever be used.

FWIW, the robust way to check whether two paths are equivalent is to
stat() (or lstat()) both of them, and check whether the device and
inode numbers match.

That handles all of the different ways that you can make multiple
paths refer to the same file/directory (case sensitivity, symlinks,
hard links, mount points, use of . and .., etc).

However, I don't know whether it works on Windows, i.e. whether the
device/inode numbers are meaningful.

I haven't committed the changes yet as they're not complete. Apart from
being unsure about stripping off the .hmp extension, specifying a
font in GRASS_FONT from the freetypecap file doesn't work. I'm just
testing this from the command line on Windows, i.e. using direct
rendering as drivers don't work, and I can't see where/if the freetypecap
file is actually being read. Specifying the full path to a Freetype font
works fine, but is the freetypecap file only read when a driver process
is initialised?

parse_freetypecap() is called from LIB_init(), in lib/driver/init.c.
For direct rendering, this is called from LOC_open_driver(); for a
standalone driver it's called from main().

Also, I'd guess that using a colon as the field separator is likely to
be problematic on Windows.

--
Glynn Clements <glynn@gclements.plus.com>

On Sun, 6 May 2007, Glynn Clements wrote:

lib/driver/Font.c, COM_Font_get():
* Cross-platform check for absolute path (new gislib function added)
* Check for pathname matching the GRASS stroke fonts made more robust by
   (a) First converting all directory separator characters to '/'
   (b) Doing a case-insensitive comparison

That last point is probably safe, in that you're unlikely to have
another directory which differs only in case on Unix.

Although, in this case, I'd be inclined to simply remove the option to
specify a stroke font using a full path. Personally, I doubt that this
feature would ever be used.

I thought it might be used in the gis.m font chooser, where it opens a file browse dialog in the $GISBASE/etc/fonts directory and after choosing puts the full path to the stroke font into the text box in the dialog widget. But I'm not 100% sure if it does that. Just appears to.

FWIW, the robust way to check whether two paths are equivalent is to
stat() (or lstat()) both of them, and check whether the device and
inode numbers match.

Interesting; here we are comparing the directory the fonts are stored in rather than the font files themselves but perhaps still of use? I suppose I could test it on Windows.

That handles all of the different ways that you can make multiple
paths refer to the same file/directory (case sensitivity, symlinks,
hard links, mount points, use of . and .., etc).

However, I don't know whether it works on Windows, i.e. whether the
device/inode numbers are meaningful.

[...]

parse_freetypecap() is called from LIB_init(), in lib/driver/init.c.
For direct rendering, this is called from LOC_open_driver(); for a
standalone driver it's called from main().

Also, I'd guess that using a colon as the field separator is likely to
be problematic on Windows.

Yes, that was it. If I use a semi-colon instead all works great - maybe we could change mkftcap to generate a file with semi-colon separators? And change parse_freetypecap() to handle both for backwards compatibility? Is the last character on a line in freetypecap always a separator character? If so that would be a quick way to check. Or could scan the first line and whichever appeared first between : and ; use that as the separator?

It seems we're nearly there.

Paul Kelly wrote:

> FWIW, the robust way to check whether two paths are equivalent is to
> stat() (or lstat()) both of them, and check whether the device and
> inode numbers match.

Interesting; here we are comparing the directory the fonts are stored in
rather than the font files themselves but perhaps still of use?

Yes; in the case of COM_Font_get(), you would need to remove the last
part of the path and check whether the directory part refers to the
same device/inode as $GISBASE/fonts.

> That handles all of the different ways that you can make multiple
> paths refer to the same file/directory (case sensitivity, symlinks,
> hard links, mount points, use of . and .., etc).
>
> However, I don't know whether it works on Windows, i.e. whether the
> device/inode numbers are meaningful.
>
[...]
>
> parse_freetypecap() is called from LIB_init(), in lib/driver/init.c.
> For direct rendering, this is called from LOC_open_driver(); for a
> standalone driver it's called from main().
>
> Also, I'd guess that using a colon as the field separator is likely to
> be problematic on Windows.

Yes, that was it. If I use a semi-colon instead all works great - maybe we
could change mkftcap to generate a file with semi-colon separators? And
change parse_freetypecap() to handle both for backwards compatibility? Is
the last character on a line in freetypecap always a separator character?
If so that would be a quick way to check. Or could scan the first line and
whichever appeared first between : and ; use that as the separator?

If it's going to be changed, one option is to use a vertical bar
(which isn't a legal filename character on Windows), and make the face
index a separate column.

That would eliminate the possibility of using a non-zero index when
specifying a font by a pathname, but that's problematic for other
reasons (e.g. gisprompt = "old_file,..." should probably check for
file existence, which would rule out the option of using something
which is "almost" a filename).

AFAIK, the trailing separator is an artifact of the time that style
information (colour, size) was included in the freetypecap file.

BTW, the encoding field isn't used either (d.font.freetype and
d.text.freetype used it, but the driver doesn't).

Note that d.font has code which parses the freetypecap file in order
to generate the option list for font=, and to implement the -l switch,
so that will need to be updated if the format changes.

d.font.freetype and d.text.freetype have similar code, but they no
longer need to be maintained; they have been replaced by scripts which
call d.font and d.text (which is actually d.text.new) respectively.

--
Glynn Clements <glynn@gclements.plus.com>

On Sun, 6 May 2007, Glynn Clements wrote:

Paul Kelly wrote:

FWIW, the robust way to check whether two paths are equivalent is to
stat() (or lstat()) both of them, and check whether the device and
inode numbers match.

Interesting; here we are comparing the directory the fonts are stored in
rather than the font files themselves but perhaps still of use?

Yes; in the case of COM_Font_get(), you would need to remove the last
part of the path and check whether the directory part refers to the
same device/inode as $GISBASE/fonts.

OK well it doesn't work on Windows anyway. The device number corresponds to the drive letter but it appears the inode number is always 0. So I suppose we can just keep the string comparison of the directory names. Or remove the option of specifying the full path to a GRASS stroke font - I generally feel unhappy with the idea of removing functionality but maybe it is the best option here?

Also, I'd guess that using a colon as the field separator is likely to
be problematic on Windows.

Yes, that was it. If I use a semi-colon instead all works great - maybe we
could change mkftcap to generate a file with semi-colon separators? And
change parse_freetypecap() to handle both for backwards compatibility? Is
the last character on a line in freetypecap always a separator character?
If so that would be a quick way to check. Or could scan the first line and
whichever appeared first between : and ; use that as the separator?

If it's going to be changed, one option is to use a vertical bar
(which isn't a legal filename character on Windows), and make the face
index a separate column.

I can't see an easy way though of keeping old freetypecap files compatible with the current reading code that way though - just recognising an alternative separator character doesn't seem to be too disruptive (apart from adding extra code and requiring it to be kept there for ever.)

That would eliminate the possibility of using a non-zero index when
specifying a font by a pathname, but that's problematic for other

Yes but that's quite neat and an easy and simple way of specifying a non-zero index if you need to, I thought.

reasons (e.g. gisprompt = "old_file,..." should probably check for
file existence, which would rule out the option of using something
which is "almost" a filename).

Yes if the font was being specified through a module like d.font - I suppose an extra parameter could be added to specify the index. But when the font is just being read from an environment variable then it's more complicated and anyway the parser isn't going to be involved here so as far as I can see the check for file existence needs to be done manually anyway as it currently is.

AFAIK, the trailing separator is an artifact of the time that style
information (colour, size) was included in the freetypecap file.

BTW, the encoding field isn't used either (d.font.freetype and
d.text.freetype used it, but the driver doesn't).

Note that d.font has code which parses the freetypecap file in order
to generate the option list for font=, and to implement the -l switch,
so that will need to be updated if the format changes.

d.font.freetype and d.text.freetype have similar code, but they no
longer need to be maintained; they have been replaced by scripts which
call d.font and d.text (which is actually d.text.new) respectively.

OK. Well here is my current proposal, which can be easily added to both d.font and libdriver: dynamically generate the format conversion string (containing either a : or ; as separator) based on the relative position of : and ; characters in the first line of the file that contains either of them.
The code looks like below; it is complicated but I can't see how to make it simpler without losing backwards compatibility. I'm not quite happy enough with it to commit it yet. It can be easily included in both d.font and libdriver as-is, though.

char format[16] = "";

while(fgets(buf, sizeof(buf), fp) && !feof(fp))
{
   char *p;

   p = strchr(buf, '#');
   if(p)
     *p = 0;

   if (!*format)
   {
     char *first_colon = strchr(buf, ':');
     char *first_semi = strchr(buf, ';');

     if (first_colon || first_semi)
     {
       char sep_char;

       if (first_colon == NULL)
         sep_char = ';';
       else if (first_semi == NULL)
         sep_char = ':';
       else
         sep_char = (first_colon < first_semi)? ':' : ';';

       sprintf(format, "%%[^%c]%c%%[^%c]", sep_char, sep_char, sep_char);
     }
     else
       continue;
   }

   if(sscanf(buf, format, iname, ipath) != 2)
     continue;

Paul Kelly wrote:

>>> FWIW, the robust way to check whether two paths are equivalent is to
>>> stat() (or lstat()) both of them, and check whether the device and
>>> inode numbers match.
>>
>> Interesting; here we are comparing the directory the fonts are stored in
>> rather than the font files themselves but perhaps still of use?
>
> Yes; in the case of COM_Font_get(), you would need to remove the last
> part of the path and check whether the directory part refers to the
> same device/inode as $GISBASE/fonts.

OK well it doesn't work on Windows anyway. The device number corresponds
to the drive letter but it appears the inode number is always 0. So I
suppose we can just keep the string comparison of the directory names. Or
remove the option of specifying the full path to a GRASS stroke font - I
generally feel unhappy with the idea of removing functionality but maybe
it is the best option here?

I think so.

Allowing a full path is exposing an implementation detail, it isn't
sufficient for files containing multiple faces, and it may cause
problems with future development.

I would rather just have fonts selected by an abstract identifier.

>>> Also, I'd guess that using a colon as the field separator is likely to
>>> be problematic on Windows.
>>
>> Yes, that was it. If I use a semi-colon instead all works great - maybe we
>> could change mkftcap to generate a file with semi-colon separators? And
>> change parse_freetypecap() to handle both for backwards compatibility? Is
>> the last character on a line in freetypecap always a separator character?
>> If so that would be a quick way to check. Or could scan the first line and
>> whichever appeared first between : and ; use that as the separator?
>
> If it's going to be changed, one option is to use a vertical bar
> (which isn't a legal filename character on Windows), and make the face
> index a separate column.

I can't see an easy way though of keeping old freetypecap files compatible
with the current reading code that way though - just recognising an
alternative separator character doesn't seem to be too disruptive (apart
from adding extra code and requiring it to be kept there for ever.)

I don't think that maintaining compatibility is all that important.
The original freetypecap format is something which Huidae made up on
the spot. It's already lost the colour/size fields, and the encoding
field isn't actually used.

> That would eliminate the possibility of using a non-zero index when
> specifying a font by a pathname, but that's problematic for other

Yes but that's quite neat and an easy and simple way of specifying a
non-zero index if you need to, I thought.

> reasons (e.g. gisprompt = "old_file,..." should probably check for
> file existence, which would rule out the option of using something
> which is "almost" a filename).

Yes if the font was being specified through a module like d.font - I
suppose an extra parameter could be added to specify the index. But when
the font is just being read from an environment variable then it's more
complicated and anyway the parser isn't going to be involved here so as
far as I can see the check for file existence needs to be done manually
anyway as it currently is.

Yes, but we should be able to use a generic file existence check,
without having to worry about hacks. When I was implementing the face
index hack, it took several iterations to get it right (either
forgetting to strip the index for the check, or inadvertantly using
the stripped version when the index was needed). My suspicion is that
the index hack will bite people continuously so long as it's around.

> AFAIK, the trailing separator is an artifact of the time that style
> information (colour, size) was included in the freetypecap file.
>
> BTW, the encoding field isn't used either (d.font.freetype and
> d.text.freetype used it, but the driver doesn't).
>
> Note that d.font has code which parses the freetypecap file in order
> to generate the option list for font=, and to implement the -l switch,
> so that will need to be updated if the format changes.
>
> d.font.freetype and d.text.freetype have similar code, but they no
> longer need to be maintained; they have been replaced by scripts which
> call d.font and d.text (which is actually d.text.new) respectively.

OK. Well here is my current proposal, which can be easily added to both
d.font and libdriver: dynamically generate the format conversion string
(containing either a : or ; as separator) based on the relative position
of : and ; characters in the first line of the file that contains either
of them.
The code looks like below; it is complicated but I can't see how to make
it simpler without losing backwards compatibility. I'm not quite happy
enough with it to commit it yet. It can be easily included in both d.font
and libdriver as-is, though.

Here's my proposal: don't bother maintaining compatibility with the
current freetypecap format or the ability to select fonts by absolute
path. Both of those were made up on the spot without any real
consideration.

--
Glynn Clements <glynn@gclements.plus.com>

On Mon, 7 May 2007, Glynn Clements wrote:

Here's my proposal: don't bother maintaining compatibility with the
current freetypecap format or the ability to select fonts by absolute
path. Both of those were made up on the spot without any real
consideration.

So what about having a totally new file, let's call it fontcap - different name to make it clear there is no backwards compatiblity. It could include the stroke fonts as well as freetype-compatible fonts, with a field to indicate whether the font is stroke or freetype, also absolute filename, index within the file, perhaps a field for a descriptive/long name too.

I wonder if something like this is what Michael had in mind when we started this whole discussion - a simple list of all the avaiable fonts that could be offered to the user to choose from through the GUI?

It would be generated automatically on compilation/installation and then the user could further edit it to add to / strip it down if required.
Wolf said he was interested in writing something to automatically extract information from font files on the system - maybe what he comes up with can be used to generate this fontcap file. And then once we're finished GRASS_FONT can only contain a font id string from this file - nothing else is accepted. Does that sound like it might be workable?

On 5/7/07 7:32 AM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Paul Kelly wrote:

...

OK well it doesn't work on Windows anyway. The device number corresponds
to the drive letter but it appears the inode number is always 0. So I
suppose we can just keep the string comparison of the directory names. Or
remove the option of specifying the full path to a GRASS stroke font - I
generally feel unhappy with the idea of removing functionality but maybe
it is the best option here?

I think so.

Allowing a full path is exposing an implementation detail, it isn't
sufficient for files containing multiple faces, and it may cause
problems with future development.

I would rather just have fonts selected by an abstract identifier.

Could this be the kind of font specification used in native font selection
dialogs for wxPython and TclTk? They *appear* to be quite similar in the way
they specify fonts. But I still have found no way to get back to original
font files from these specifications, suggesting that it happens somewhere
at the system level. If we could somehow tap into that, it could ultimately
make life easier for cross-platform font selection.

...

OK. Well here is my current proposal, which can be easily added to both
d.font and libdriver: dynamically generate the format conversion string
(containing either a : or ; as separator) based on the relative position
of : and ; characters in the first line of the file that contains either
of them.
The code looks like below; it is complicated but I can't see how to make
it simpler without losing backwards compatibility. I'm not quite happy
enough with it to commit it yet. It can be easily included in both d.font
and libdriver as-is, though.

Here's my proposal: don't bother maintaining compatibility with the
current freetypecap format or the ability to select fonts by absolute
path. Both of those were made up on the spot without any real
consideration.

Then I'm not going to worry about implementing a different way of selecting
fonts that uses freetypecap in the TclTk GUI at the moment. It is working OK
now, so I'll leave well enough alone until this gets sorted out further.

But it *is* really nice to see this discussion over improvements in how to
specify display fonts in GRASS. It makes an enormous impact on the
professional look of GRASS output, not to mention its readability in
presentations. Thanks much guys.

Michael

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Paul Kelly wrote:

> Here's my proposal: don't bother maintaining compatibility with the
> current freetypecap format or the ability to select fonts by absolute
> path. Both of those were made up on the spot without any real
> consideration.

So what about having a totally new file, let's call it fontcap - different
name to make it clear there is no backwards compatiblity. It could include
the stroke fonts as well as freetype-compatible fonts, with a field to
indicate whether the font is stroke or freetype, also absolute filename,
index within the file, perhaps a field for a descriptive/long name too.

Sounds reasonable.

Also, built-in PostScript fonts (for the PS driver) might also be
added at some point (although R_get_text_box() will have to be fudged
in that case).

I wonder if something like this is what Michael had in mind when we
started this whole discussion - a simple list of all the avaiable fonts
that could be offered to the user to choose from through the GUI?

You can get that from "d.font -l".

Although, ultimately the raster API should be extended with e.g.
R_list_fonts(); that would eliminate the possibility of mismatch
between the driver's view of which fonts are available and the
client's. In particular, built-in PostScript fonts would only be
available through the PS driver.

Regarding that last point, it should be possible to have multiple
fonts with the same name but different types, e.g. both FreeType and
PostScript versions of Helvetica. The X/PNG drivers would use the
libfreetype rasteriser with the TTF/Type1 file, while the PS driver
would just use "/Helvetica findfont ...".

It would be generated automatically on compilation/installation and then
the user could further edit it to add to / strip it down if required.
Wolf said he was interested in writing something to automatically extract
information from font files on the system - maybe what he comes up with
can be used to generate this fontcap file. And then once we're finished
GRASS_FONT can only contain a font id string from this file - nothing else
is accepted. Does that sound like it might be workable?

Yes.

--
Glynn Clements <glynn@gclements.plus.com>

Would fontlist be a more intuitive name to use?

-----Original Message-----
From: grass-dev-bounces@grass.itc.it [mailto:grass-dev-bounces@grass.itc.it]
On Behalf Of Glynn Clements
Sent: Monday, May 07, 2007 11:30 AM
To: Paul Kelly
Cc: grass-dev@grass.itc.it
Subject: Re: [GRASS-dev] iconv a required dependency for using Freetype?

Paul Kelly wrote:

> Here's my proposal: don't bother maintaining compatibility with the
> current freetypecap format or the ability to select fonts by absolute
> path. Both of those were made up on the spot without any real
> consideration.

So what about having a totally new file, let's call it fontcap - different

name to make it clear there is no backwards compatiblity. It could include

the stroke fonts as well as freetype-compatible fonts, with a field to
indicate whether the font is stroke or freetype, also absolute filename,
index within the file, perhaps a field for a descriptive/long name too.

Sounds reasonable.

Also, built-in PostScript fonts (for the PS driver) might also be
added at some point (although R_get_text_box() will have to be fudged
in that case).

I wonder if something like this is what Michael had in mind when we
started this whole discussion - a simple list of all the avaiable fonts
that could be offered to the user to choose from through the GUI?

You can get that from "d.font -l".

Although, ultimately the raster API should be extended with e.g.
R_list_fonts(); that would eliminate the possibility of mismatch
between the driver's view of which fonts are available and the
client's. In particular, built-in PostScript fonts would only be
available through the PS driver.

Regarding that last point, it should be possible to have multiple
fonts with the same name but different types, e.g. both FreeType and
PostScript versions of Helvetica. The X/PNG drivers would use the
libfreetype rasteriser with the TTF/Type1 file, while the PS driver
would just use "/Helvetica findfont ...".

It would be generated automatically on compilation/installation and then
the user could further edit it to add to / strip it down if required.
Wolf said he was interested in writing something to automatically extract
information from font files on the system - maybe what he comes up with
can be used to generate this fontcap file. And then once we're finished
GRASS_FONT can only contain a font id string from this file - nothing else

is accepted. Does that sound like it might be workable?

Yes.

--
Glynn Clements <glynn@gclements.plus.com>

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

Michael Barton wrote:

>> OK well it doesn't work on Windows anyway. The device number corresponds
>> to the drive letter but it appears the inode number is always 0. So I
>> suppose we can just keep the string comparison of the directory names. Or
>> remove the option of specifying the full path to a GRASS stroke font - I
>> generally feel unhappy with the idea of removing functionality but maybe
>> it is the best option here?
>
> I think so.
>
> Allowing a full path is exposing an implementation detail, it isn't
> sufficient for files containing multiple faces, and it may cause
> problems with future development.
>
> I would rather just have fonts selected by an abstract identifier.

Could this be the kind of font specification used in native font selection
dialogs for wxPython and TclTk? They *appear* to be quite similar in the way
they specify fonts. But I still have found no way to get back to original
font files from these specifications, suggesting that it happens somewhere
at the system level. If we could somehow tap into that, it could ultimately
make life easier for cross-platform font selection.

It cannot be done.

Just because a program can get a list of fonts, get information about
those fonts, and even draw text using those fonts, that doesn't mean
that it can actually access the underlying files (if there are any).

An X application can ask the X server for a list of fonts (XListFonts,
XListFontsWithInfo), can obtain information about a font (XQueryFont,
XGetFontProperty), and can tell the X server to use a specific font
for drawing text (XSetFont, XChangeGC).

It cannot, however, obtain either the raw contents of the underlying
file or it's path (not that it would be much use, given that it may
not have access to the filesystem of the system on which the X server
is running). Even the X server may not have that access if it's
getting its fonts from a font server.

There may not even *be* any underlying files. A font server can
manufacture glyphs on the fly, e.g. automatically generating bold
and/or oblique versions of a font, generating outlines from strokes,
bitmaps from outlines, etc.

IOW, any list of fonts which you can get from X is only useful insofar
as you can pass the name to XLoadFont() etc.

--
Glynn Clements <glynn@gclements.plus.com>

On Mon, 7 May 2007, Michael Barton wrote:

Then I'm not going to worry about implementing a different way of selecting
fonts that uses freetypecap in the TclTk GUI at the moment. It is working OK
now, so I'll leave well enough alone until this gets sorted out further.

If we remove the ability to set a Freetype-compatible font through the GRASS_FONT env var by specifying it's full filename, then it will no longer work though. Just thinking - I don't see any reason why the font selection dialog can not just take the list of font options from
"d.font -l" and present this list in a drop down selection box to the user. It includes the stroke fonts and the Truetype etc. fonts available in freetypecap (or wherever they will be listed in the future), all in one list.

I was thinking perhaps you didn't want to have to rely on users having updated their freetypecap file with fonts on the system, and that is why you've offered the possiblity of choosing Freetype-compatible fonts directly from the directory most of them are typically stored in on the platform gis.m is running on? That would seem to be no longer relevant now that the freetypecap file (and in future, its replacement) are automatically generated to contain the fonts available on the system, i.e. the list from "d.font -l" is now more reliable as an indicator of all possible font choices - and simplifies things too as it doesn't need a separate choice/browsing mode for stroke and freetype fonts.

In that sense, using the d.font -l output directly will be I suppose more future-proof (I'm thinking of the new Python GUI too) than parsing freetypecap directly.

Paul

Actually, I am trying to avoid having to do any more than I need to, to the
TclTk GUI so that I can focus my time on the wxPython development.

Interactive selection of display fonts seemed an important enough function
to add for a relatively small investment in time. But I'm mostly trying to
fix problems and leave new features to wxPython.

So it's more a matter of having to rebuild the widgets from a fairly easy
file selection dialog to a little more complicated listbox. But if this is
what is needed to avoid future breakage, I can try to do this.

Michael

On 5/7/07 10:58 AM, "Paul Kelly" <paul-grass@stjohnspoint.co.uk> wrote:

On Mon, 7 May 2007, Michael Barton wrote:

Then I'm not going to worry about implementing a different way of selecting
fonts that uses freetypecap in the TclTk GUI at the moment. It is working OK
now, so I'll leave well enough alone until this gets sorted out further.

If we remove the ability to set a Freetype-compatible font through the
GRASS_FONT env var by specifying it's full filename, then it will no
longer work though. Just thinking - I don't see any reason why the font
selection dialog can not just take the list of font options from
"d.font -l" and present this list in a drop down selection box to the
user. It includes the stroke fonts and the Truetype etc. fonts available
in freetypecap (or wherever they will be listed in the future), all in one
list.

I was thinking perhaps you didn't want to have to rely on users having
updated their freetypecap file with fonts on the system, and that is why
you've offered the possiblity of choosing Freetype-compatible fonts
directly from the directory most of them are typically stored in on the
platform gis.m is running on? That would seem to be no longer relevant now
that the freetypecap file (and in future, its replacement) are
automatically generated to contain the fonts available on the system, i.e.
the list from "d.font -l" is now more reliable as an indicator of all
possible font choices - and simplifies things too as it doesn't need a
separate choice/browsing mode for stroke and freetype fonts.

In that sense, using the d.font -l output directly will be I suppose more
future-proof (I'm thinking of the new Python GUI too) than parsing
freetypecap directly.

Paul

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

I was afraid that you'd say something like that. Oh well.

Michael

On 5/7/07 10:26 AM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Michael Barton wrote:

OK well it doesn't work on Windows anyway. The device number corresponds
to the drive letter but it appears the inode number is always 0. So I
suppose we can just keep the string comparison of the directory names. Or
remove the option of specifying the full path to a GRASS stroke font - I
generally feel unhappy with the idea of removing functionality but maybe
it is the best option here?

I think so.

Allowing a full path is exposing an implementation detail, it isn't
sufficient for files containing multiple faces, and it may cause
problems with future development.

I would rather just have fonts selected by an abstract identifier.

Could this be the kind of font specification used in native font selection
dialogs for wxPython and TclTk? They *appear* to be quite similar in the way
they specify fonts. But I still have found no way to get back to original
font files from these specifications, suggesting that it happens somewhere
at the system level. If we could somehow tap into that, it could ultimately
make life easier for cross-platform font selection.

It cannot be done.

Just because a program can get a list of fonts, get information about
those fonts, and even draw text using those fonts, that doesn't mean
that it can actually access the underlying files (if there are any).

An X application can ask the X server for a list of fonts (XListFonts,
XListFontsWithInfo), can obtain information about a font (XQueryFont,
XGetFontProperty), and can tell the X server to use a specific font
for drawing text (XSetFont, XChangeGC).

It cannot, however, obtain either the raw contents of the underlying
file or it's path (not that it would be much use, given that it may
not have access to the filesystem of the system on which the X server
is running). Even the X server may not have that access if it's
getting its fonts from a font server.

There may not even *be* any underlying files. A font server can
manufacture glyphs on the fly, e.g. automatically generating bold
and/or oblique versions of a font, generating outlines from strokes,
bitmaps from outlines, etc.

IOW, any list of fonts which you can get from X is only useful insofar
as you can pass the name to XLoadFont() etc.

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Can d.font -l get rid of duplicates and alphabetize (better if it ignored
caps)? Or will I have to do that in the GUI?

Michael

On 5/7/07 10:58 AM, "Paul Kelly" <paul-grass@stjohnspoint.co.uk> wrote:

On Mon, 7 May 2007, Michael Barton wrote:

Then I'm not going to worry about implementing a different way of selecting
fonts that uses freetypecap in the TclTk GUI at the moment. It is working OK
now, so I'll leave well enough alone until this gets sorted out further.

If we remove the ability to set a Freetype-compatible font through the
GRASS_FONT env var by specifying it's full filename, then it will no
longer work though. Just thinking - I don't see any reason why the font
selection dialog can not just take the list of font options from
"d.font -l" and present this list in a drop down selection box to the
user. It includes the stroke fonts and the Truetype etc. fonts available
in freetypecap (or wherever they will be listed in the future), all in one
list.

I was thinking perhaps you didn't want to have to rely on users having
updated their freetypecap file with fonts on the system, and that is why
you've offered the possiblity of choosing Freetype-compatible fonts
directly from the directory most of them are typically stored in on the
platform gis.m is running on? That would seem to be no longer relevant now
that the freetypecap file (and in future, its replacement) are
automatically generated to contain the fonts available on the system, i.e.
the list from "d.font -l" is now more reliable as an indicator of all
possible font choices - and simplifies things too as it doesn't need a
separate choice/browsing mode for stroke and freetype fonts.

In that sense, using the d.font -l output directly will be I suppose more
future-proof (I'm thinking of the new Python GUI too) than parsing
freetypecap directly.

Paul

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

On Mon, 7 May 2007, Michael Barton wrote:

Can d.font -l get rid of duplicates and alphabetize (better if it ignored
caps)? Or will I have to do that in the GUI?

I think that is better handled at the time the font list file is generated. So the answer is no, but when we get this sorted out it won't need to. So I guess no need to rush into any changes right now.

Paul

Paul Kelly wrote:

> Can d.font -l get rid of duplicates and alphabetize (better if it ignored
> caps)? Or will I have to do that in the GUI?

I think that is better handled at the time the font list file is
generated.

Agreed.

Ideally, mkftcap would unique-ify duplicate names, although this isn't
easy to do in a shell script.

I'm not so sure that either mkftcap, "d.font -l" or the GUI should
sort the overall list. It may be better if mkftcap grouped fonts
according to the directory in which they reside, in which case, both
"d.font -l" and the GUI should preserve that ordering. Ditto if the
user manually re-orders the entries.

--
Glynn Clements <glynn@gclements.plus.com>

Just because fonts come from different directories, that doesn't mean that
there is some significance to the grouping. Might be and might not be. Also,
I don't know how to get rid of duplicates unless I sort first. Standard font
dialogs always sort by name. In wxPython, you can start typing the name and
it will automatically scroll to the font.

Michael

On 5/7/07 3:54 PM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Paul Kelly wrote:

Can d.font -l get rid of duplicates and alphabetize (better if it ignored
caps)? Or will I have to do that in the GUI?

I think that is better handled at the time the font list file is
generated.

Agreed.

Ideally, mkftcap would unique-ify duplicate names, although this isn't
easy to do in a shell script.

I'm not so sure that either mkftcap, "d.font -l" or the GUI should
sort the overall list. It may be better if mkftcap grouped fonts
according to the directory in which they reside, in which case, both
"d.font -l" and the GUI should preserve that ordering. Ditto if the
user manually re-orders the entries.

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton