Closed Bug 78211 Opened 23 years ago Closed 3 years ago

add: Is there a glyph for this character on this system?

Categories

(Core :: DOM: Core & HTML, enhancement)

x86
All
enhancement
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: endico, Assigned: rbs)

Details

Attachments

(3 files, 1 obsolete file)

From: Dawn Endico <endico@mozilla.org>
  To: rbs@maths.uq.edu.au

I've come to the conclusion that it would be really nice if you could
determine in javascript whether or not a string is printable on a user's
system. Hand the function a unicode string and if the user's system has a 
glyph for each of the characters then it returns true.


Here's what I actually want to do.  On the credits page
http://mozilla.org/credits/ I want to print people's names in ascii and for some
people, in their native language. The problem with doing this directly is that
i'd be mixing so many charsets on one page that hardly anyone would be able to
view all the names properly and lots of question marks would show up and i'd get
lots of mail sent to webmaster.

If i had a function like that i could print only the native names that would be
properly displayed and skip the rest.

-----------------------
From: "Roger B. Sidje" <rbs@maths.uq.edu.au>
To:   Dawn Endico <endico@mozilla.org>

Dawn Endico wrote:
> 
> If i had a function like that i could print only the native names that
> would be
> properly displayed and skip the rest.

Yes, it is known when no glyphs are found for particular characters on a 
particular configuration. That's where they get substituted to question marks.
But, it is deep down in GFX that this is known, with no way to report it back
to the user... There are some bugzilla bugs to popup a window in which to 
propose to the user to download fonts which are known to contain the glyphs,
but it is not high in the agenda of the GFX people to implement this. So there
is a long way to go before this happens.

Anyway, having a JS function like the one you mentioned could be highly 
useful in many contexts: r = representable(s) could return a boolean array
where r[i] is true if s[i] is representable (or return true if there are
glyphs for each of the characters).

In the scriptable interface gfx/idl/nsIFontEnumerator.idl, there is this method:

  /*
    @param  aLangGroup language group
    @return bool do we have a font for this language group
   */
  void HaveFontFor(in string aLangGroup, [retval] out boolean aResult);

It doesn't do exactly what you want :-) But it shows the IDL spot where it
might be possible to add an additional function that will do the job...
So all the ingredients for this are already there, sitting in the tree
reassigning to Roger. He has a patch. Roger, does your patch allow js to
obtain a list of all fonts installed on the system? If it did, i think that
would be bad.
Assignee: jst → rbs
Attached image example
From: "Roger B. Sidje" <rbs@maths.uq.edu.au>
  To: endico@mozilla.org

I got it working. I added a CanRepresent() function:
  /*
    @param  aString a Unicode string
    @return aResult do we have all the glyphs to represent this string
   */
  void CanRepresent(in wstring aString, [retval] out boolean aResult);

I am attaching some files for illustration how it works in the JS
side...
> Roger, does your patch allow js to
> obtain a list of all fonts installed on the system? If it did, i think that
> would be bad.

Yes, the interface (not my patch) already provides hooks to list the fonts:
  void EnumerateAllFonts();
  void EnumerateFonts()
  void HaveFontFor();

These are the functions that are currently used in the Prefs -> Fonts dialog. 
Without these, it wouldn't be possible to implement the facility. Only signed 
scripts (or chrome:// stuff) can execute these (and my patch).

If the script comes from a chrome:// source (which is on the user' side), the 
patch will execute in silence. If it comes from any other source, users will be 
prompted with the security dialog asking for permission to peek their 
configuration. And the script will execute only if a user clicks the "grant" 
button.
OS: Linux → All
Summary: addIs there a glyph for this character on this system? → add: Is there a glyph for this character on this system?
What does this API you speak of look like?
http://lxr.mozilla.org/seamonkey/source/gfx/idl/nsIFontEnumerator.idl

To which I added a CanRepresent() function:
  /*
    Return true if installed fonts on the system can represent this string.
    @param  aString a Unicode string
    @return aResult true if there are all the glyphs to represent this string
   */
  void CanRepresent(in wstring aString, [retval] out boolean aResult);
Ah, ok. Any ideas how we'd best expose this to scripts on web content?
Actually, i wanted this to work from a normal web page. For privacy reasons
the list of fonts installed on a system can't be exposed to the world, but 
presumably it would be ok to indicate whether a character is renderable or 
not.  If CanRepresent created its own font enumerator that would make it safe
to expose, wouldn't it?
[mid-air collision, meant to answer jst questions, but it seems that it could be
relevant to dawn questions too]
Currently, it works with the usual XPConnect machinery, i.e., a script will have
to sniff for Mozilla (there isn't much to say about the other browsers...).  It
will be nice though if this particular function could be called without having
to _explicitly_ create the font enumerator object _within the script_ and thus
without requesting additional security privileges to do so (the global list of
fonts is known inside Mozilla anyway). HTML authors will find it more convenient
if they can just call canRepresent(aString) -- but on the other hand, that will
amount to a JS extension. Here is the sample HTML used for the screenshot (the
C++ side resides in GFX):

<html>
<head>
<title>Representable characters</title>
<script type="text/javascript">

// Create a font enumerator which can access the list of all installed fonts
try {
  // Prompt the security dialog to ask for permission to peek the configuration
  // Without this we get the exception "Access to XPConnect service denied"
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

  var fonts =
    Components.classes["@mozilla.org/gfx/fontenumerator;1"].createInstance();
  if (fonts) {
    fonts = fonts.QueryInterface(Components.interfaces.nsIFontEnumerator);
  }
} catch(e) { alert("Caught exception: " + e + "\n")};

//////////////////////////////////////////////
function CanRepresent(string)
{
  return fonts.CanRepresent(string);
}

//////////////////////////////////////////////
function CheckString(string)
{
  if (CanRepresent(string)) {
    alert("GOOD: This system can represent \"" + string + "\"");
  }
  else {
    alert("BAD: This system cannot represent " + string);
  }
}

</script>
</head>

<body onload="CheckString('beta:\u03B2 lambda:\u03BB U+FBAC:\uFBAC')">
Hello World!
</body>
</html>
Maybe the solution to Dawn's problem could be to have the mozilla page contain a
signed script that could have access to XPConnect to use the suggested API,
would that work for you Dawn? If so we don't need to expose this method to web
script.
Of note: the fact that the nsIFontEnumerator (like all other scriptable Mozilla
interfaces) is already exposed anyway (via XPConnect). 

Of note (2): yes if the credits page has a signed script or is placed in the
chrome dir so that it is served as chrome:// then the problem is solved.
Actually, it turned out that Mozilla wouldn't execute the sample script if 
served as "file:" even if I "grant" the privilege (I guess I need to set a pref 
somewhere for the "file:" url to be secure?). 

Cc:ing jband and mstoltz for any inputs they might have on this bug.
Dawn wants a special JS function, say mozCanRepresent(), that can conveniently 
be used on any webpage without much fuss despite the fact this special function 
requires additional security privileges. The implementation on the function 
involves calling a corresponding C++ function built-in Mozilla.
rbs, accessing xpconnect should work from file: as long as you've called
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); in the
same scope as the access to xpconnect. That should be all that's necessary if
you're coming from file:.

If I understand what's going on here, we're not talking about revealing the
user's fonts to web scripts, just whether a particular string is displayable.
This seems reasonable to me. Instead of using a signed script (that's broken
right now), have the object that implements this function implement the
nsISecurityCheckedComponent interface as well; that makes it scriptable by web
scripts.
Attached patch diff on gfx-win32 (obsolete) — Splinter Review
Although I implemented methods from nsISecurityCheckedComponent but it still
requires to explicitly call 
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
before it can run (and this is even throwing an exception BTW).
Updating QA contact to Shivakiran Tummala.
QA Contact: desale → stummala
Attachment #33375 - Attachment is obsolete: true
Following the recent font revamps, I have attached what I have now. Troubles 
with security are still there and they prevent the desired seamless integration 
with web scripts. Also need a helping hand to see how Linux goes -- this way, 
only the security aspect will remain to sort out (Dawn, interested to see how 
the patch goes on your Linux box?).
Component: DOM: Core → DOM: Core & HTML
QA Contact: stummala → general

If still desired this is probably best raised with either WebExtensions or WICG.

Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: