[CSSWG] Minutes New York F2F 2015-05-20 Part VI: load/check FontFaceSet, Carto CSS

load/check FontFaceSet
----------------------

  - There was discussion over when check() should return true and
      when it should return false. In particular instances of a
      misspelled font and a system font were heavily debated.
  - The conversation will continue outside the meeting.

Carto CSS
---------

  - Andrey brought up a project that uses CSS-like syntax to style
      maps.
  - The CSSWG is generally in favor of other groups reusing CSS
      syntax, selectors, and cascading/inheritance for non-CSS
      languages. Examples brought up included STTS (Simple Tree
      Transformation Sheets), the CAS (Cascading Attribute Sheets)
      proposal, and a project at MIT.
  - It wasn't clear to what extent coordination with the CSSWG would
      be useful in this particular case.
  - It was also suggested that Houdini should discuss use case of
      building CSS-like languages.

====== FULL MINUTES BELOW ========

  Scribe: fantasai

load/check FontFaceSet
----------------------

  heycam: Think the spec is in reasonably good shape.
  heycam: ... behavior of check() method.
  heycam: Fundamentally unclear to me what the intent of having
          check method is.
  heycam: Not clear to me from description in the spec what it's
          meant to do at a high level.
  heycam: Also not sure what it's intended to do to solve a use case.
  heycam: Would be helpful to see some code snippets that use check
          to accomplish some particular thing,
  heycam: so I can evaluate whether the particular behavior in the
          spec is useful or needs tweaking.
  TabAtkins: I can always put in better introductions.
  TabAtkins: Intent of check method is, e.g. you want to render in
             to canvas, ask each font you want to use, if it's good.
  jdaggett: That's not what actually happens.
  jdaggett: Given a font list, never guaranteed that all the text
            will be rendered with that font.
  jdaggett: This will only tell, if there's a load... [can't hear]
  TabAtkins: No that's not right, because gives you bad behavior in
             a corner case.
  TabAtkins: You've misspelled one of the font faces.
  TabAtkins: ...
  TabAtkins: Getting a no there, yeah check method just fine, it's a
             bad confusing behavior.
  TabAtkins: Semantic of "can I render with this font" works here.
  TabAtkins: It'll return "No" for the typoed font, because it
             doesn't exist.
  jdaggett: Don't understand why misspelling has to do with return
            value on a method.
  jdaggett: Want to flag a developer that there's no font that you
            specified in this list, that's a dev tool feature.
  jdaggett: This introduces inconsistency, has side-effect of making
            ideal API for font fingerprinting.
  jdaggett: That's especially bad.

  TabAtkins: We're not disagreeing on basic behavior.
  TabAtkins: All but the trivial case is easily defined.
  TabAtkins: The case is none of the fonts can render the string you
             describe.
  jdaggett: The trivial case isn't whether font can render a piece
            of text.
  jdaggett: There's about whether there are no fonts that result in
            the font list.
  jdaggett: The wording you're using you're proving fonts for all
            possible strings, which you're not.
  TabAtkins: The only case we're disagreeing on is if you call
             check() with a font listing and a sample string of
             characters you're going to use.
  TabAtkins: If it can't render all characters in the sample string,
             drops font from the list.
  TabAtkins: At the end, whatever fonts are left, get them back.
             Check method returns true or false.
  TabAtkins: Only disagreeing if the list is empty, do you return
             true or false?
  TabAtkins: True is if you can render all the characters with the
             font you gave, false otherwise.
  <jdaggett> check("calibri") ==> returns true on windows, false
             elsewhere
  <jdaggett> check("calibri,sans-serif") ==> returns true always
  <jdaggett> you're making check into an existence check
  <jdaggett> which is *not* the use case
  jdaggett: It says, let's check this font list, and if not true,
            then I need to call load() on the font list.
  jdaggett: Call load, and the promise will immediately resolve if
            the font list is already loaded.
  * scribe sure that's wrong
  <jdaggett> er, no...
  * scribe pls fix, so confused
  <jdaggett> if (!check(fontlist)) load(fontlist)
  jdaggett: Having this behavior that's inconsistent across font
            lists, and behavior that's different from the way load
            works and check works.
  jdaggett: Those are really bad inconsistencies.

  heycam: From a different direction:
  heycam: Looking at what the limit value is as you reduce the
          number of font faces in the fontFaceSet,
  heycam: If you have a bunch of matching fonts,
  heycam: As you remove fonts, you are more likely to return true
          because more and more likely to have error case,
  heycam: But when you remove the last one, suddenly return false.
  heycam: It adds another ... for what the check method is doing.
  heycam: Are all of the things in this list ready?
  heycam: And do we have no font faces at all?
  heycam: Complicates what we're looking for.
  heycam: Those make me want to return a true value.
  TabAtkins: I'm willing to provisionally change it, until/unless I
             revisit the arguments for changing it.
  heycam: Agree it's kindof a corner case.
  heycam: As an author probably know what fonts you added to set.
  heycam: Why would you do checks and loads not in the set?
  heycam: But would want consistent with load's behavior and [?]
  TabAtkins: Okay, let's do that, that's fine.

  heycam: Another aspect of this, which I think we have different
          opinions on,
  heycam: Looking up the list,
  heycam: system fonts,
  heycam: whether they should influence the return value of check().
  heycam: In my mind, check() is like a very close counterpart to
          load(),
  heycam: Where it's telling you, are things going to load,
  heycam: Same set of font faces as load.
  heycam: It tells me if you call load, that promise is going to be
          resolved straightaway or not.
  heycam: Looking up system fonts, influencing value of check()
          doesn't fit in with that.

  TabAtkins: Can't seem to find thread that convinced me on this....
  jdaggett: I don't really remember seeing a thread on the list
            about this.
  [TabAtkins trying to find emails]
  TabAtkins: Don't want to make a resolution until I find the logic
             that caused this change in the first place.

  ACTION TabAtkins Find out why including system fonts behavior of
         check and trivial case behavior of check.
  <trackbot> Created ACTION-693

  jdaggett: Whether check returns true or false when no fonts are
            found in the font list.
  plinss: Anything else on this topic?

  TabAtkins: Found the thread!
  TabAtkins: Either I wrote the algorithm slightly wrong, or you're
             reading slightly wrong.
  TabAtkins: The idea was for returning false if you have only one
             misspelled font,
  TabAtkins: True should look nice.
  TabAtkins: Added system-wide keywords, because before they could
             write 'Arial' and it would return false, because
             'Arial' is a system font, not an @font-face rule.
  jdaggett: Check should return whether a font should be loaded or
            not.
  jdaggett: If it's a system font, doesn't need to be loaded.
  jdaggett: Don't understand for misspelled font how that helps
            anything...
  jdaggett: If you try to render with it, it won't work .
  TabAtkins: That's why it returns false. Cuz it won't work.
  TabAtkins: Case is, you call check("misspelled") or
             check("systemfont").
  TabAtkins: If you use John's preferred semantic, "whether or not
             need to load something", both will return false,
             because nothing needs to be loaded.
  jdaggett: If you want different sematics, what's the use case?
  jdaggett: Where does this improve your code?
  TabAtkins: The use case is if it returns true, you can just start
             using the stuff.
  TabAtkins: At bare minimum, system font needs to return true,
  TabAtkins: because asking system whether can use '16px Arial', if
             it returns false that's confusing.
  TabAtkins: I have a font-face value if I can start drawing with it
             check() should return true, otherwise false.
  TabAtkins: Check returns true if you can render with the font.
  TabAtkins: That's also what you're saying.
  TabAtkins: Check returns true if all the fonts are loaded.
  jdaggett: check() returns true if it's always available,
  jdaggett: Check on a blank list should always return true.
  <jdaggett> http://dev.w3.org/csswg/css-font-loading/#font-face-set-check
  <jdaggett> yes

  fantasai: Who's arguing what here?
  fantasai: If I check() for 16px Arial, does it return true or
            false?
  TabAtkins: True
  jdaggett: True
  jdaggett: If you say check() Misspelled, should return true
            because you don't need to load anything to get its
            expected behavior
  <jdaggett> check("16px arial") should return true
  <jdaggett> check("16px misspelled fontname") should return true
  <jdaggett> check("16px misspelled fontname,arial") should return
             true

  Florian: So John's semantic is that it returns true because it's
           already in it's final state?
  TabAtkins: Yeah, any load you do won't help.
  TabAtkins: That seems terrible to me [...]
  <TabAtkins> https://www.irccloud.com/pastebin/Z9X5Orqq
  <TabAtkins> That spec seems crazy to me - it means I can't tell
              the difference between a font that is ready to be used
              and what is effectively a gibberish string!  This
              turns typos into terrible hard-to-detect bugs, and
              makes relying on the call for any reason extremely
              dangerous.
  <TabAtkins> Plausible example of the danger:
  <TabAtkins> 1) We start using Roboto on the SRP
  <TabAtkins> 2) In our various page elements for various reasons we
              start calling document.fonts.check('400 12pt Roboto')
              in a bunch of places
  <TabAtkins> 3) We later decide to migrate to using "Roboto Neue"
              instead of Roboto for whatever reason.
  <TabAtkins> 4) We modify our CSS to use this new font, and find
              and update most but not all of the old check calls,
              because we have a lot of code and it's easy to miss
              stuff.
  <TabAtkins> 5) We now have code that calls document.fonts.check
              ('400 12pt Roboto') which erroneously returns true
              even though the font isn't available, causing all
              sorts of havoc.
  <TabAtkins> </blockquote>

  heycam: Comes back to what is check() for,
  heycam: And exactly how would be using return value of that method.
  heycam: Makes me think that the name check() is too confusing.
  heycam: People could get confused as to what check() is meant to
          mean.
  <Florian> so check needs to be renamed into either "needsLoading"
            or "canUse"

  TabAtkins: Given it's a trivial case, it doesn't matter too much.
  TabAtkins: Suggest straw polling.
  fantasai: I think heycam's point is important.
  Andreyr: I agree with TabAtkins.

  heycam: I don't think this is unimportant.
  heycam: I think the way you're expecting this API to be used
          really does influence whether this should return true or
          false.
  heycam: Would like to flesh out use cases of what check() is meant
          to be used for.
  heycam: Still not exactly sure what you meant to use it for.
  heycam: Can we draw with this text?
  heycam: Doesn't seem settled enough.
  TabAtkins: Outside of this trivial case, doesn't matter.
  TabAtkins: Only case where two meanings diverge.
  TabAtkins: However, what if we just throw in that case?
  TabAtkins: You've clearly done something wrong if we go through
             all fonts in your list and we can't find any of them.
  <Florian> +1 to TabAtkins
  heycam: Really depends on what check is doing.
  heycam: Does it mean "Do I need to do any loads now?"
  heycam: vs "Can I render now?"
  heycam: Might not matter if can't find any fonts in the list.

  TabAtkins: There's no reason why font matching should return empty
             set.
  heycam: Disagree.
  heycam: Suppose you have toolkit that downloads a bunch of fonts.
  heycam: Later want to draw a particular string.
  jdaggett: There are a lot of system fonts, on mobile device, they
            don't have any of the fonts on that list.
  jdaggett: Don't think should throw in that situation.
  jdaggett: Could use "Arial" or whatever, not going to get any of
            those fonts.
  jdaggett: Shouldn't be a special error case.
  <Florian> This is a valid use case for having true | false |
            file_not_found
  TabAtkins: If you put a final fallback, then something always
             matches.
  jdaggett: check() is for "do I need to do anything for this", do I
            need to load.
  TabAtkins: I disagree with the characterization.

  TabAtkins: In all other cases, the two interpretations are the
             same answer. Only case where they're different.
  TabAtkins: I have specific feedback from a user that this is
             confusing, want to handle that well.

  plinss: Conversation between 2-3 ppl at this point.
  TabAtkins: Cameron, do you understand the system fonts piece?
  TabAtkins: 2 issues.
  TabAtkins: One about check() method in trivial case.
  TabAtkins: Other one is system fonts flag.
  TabAtkins: Do we need to talk more about system fonts flag?
  heycam: I think the wording of name of flag is different from how
          actually set in checked algorithm.
  jdaggett: System font flag is unnecessary if you simply consider
            system fonts as trivially loaded.
  jdaggett: Don't think it needs to be in the algorithm.

  <TabAtkins> jdaggett: As I explained in the thread, the system
              fonts flag lets me get the right behavior in check(
              "16px Ariel") (true) and the right behavior in load(
              "16px Ariel") (not waiting for any promises).
  <heycam> TabAtkins, I think all jdaggett is saying is that if you
           agree with the check method returning true for system
           fonts (and non-existent fonts), then that obviates the
           need for a flag altogether
  <TabAtkins> heycam: Ah, yeah, if you don't have the flag, so that
              system fonts become "unknown" (returning an empty list
              from the algo), then sure, if system fonts and unknown
              fonts have the same result we can avoid it.
  <TabAtkins> heycam: That means that the question just becomes a
              trivial result of the decision going one way or
              another, not a separate issue to discuss. ^_^
  <heycam> TabAtkins, indeed
  <TabAtkins> heycam: This was very unclear to me.
  <heycam> TabAtkins, I think the best way to advance the discussion
           is to see code fragments for how check() is intended to
           be used... i.e. seeing what people do in response to the
           return value
  <TabAtkins> heycam: Specifically, we need to see what people would
              want to do if they misspelled the font - if they'd
              want to respond to the "there's nothing here"
              specially, or just go through and draw.
  <heycam> TabAtkins, but also how they intend to use the return
           value in other cases, since that might help us decide
           what to do with the misspelled/system font cases
  <TabAtkins> heycam: In all other cases, if check() is true, you
              start drawing. If it's false, I guess you'd either
              avoid drawing, or call load(), depending on what
              you're wanting to do.
  <TabAtkins> The former means a misspelling returning false is fine.
              The latter means returning false is bad; the load()
              wouldn't do anything.
  <TabAtkins> Which is why I suggested throwing, actually.
  <TabAtkins> It gives us a tri-state result - "at least one of the
              fonts you're asking for is ready", "none of the fonts
              are ready", "lol what even is this shit"
  <heycam> TabAtkins, yes, what you want to do in response to
           true/false are exactly the things I'd like to see. I
           think an issue is that there may be valid use cases for
           correctly spelled but missing font where it's not an
           error situation

Carto CSS
---------

  <TabAtkins> https://github.com/mapbox/carto/blob/master/docs/latest.md
  Andreyr: For developers trying to build mapping solutions...
  andreyr: If I do Google maps or bin maps, stuck with that solution.
           Locked in.
  andreyr: Would be nice to have some kind of markup that would
           describe layers of the maps.
  andreyr: e.g. ground layer, road layer, traffic layer, etc.
  andreyr: Can annotate with different semantics,
  andreyr: CSS-like style sheet.
  andreyr: Pretty good usage.
  andreyr: Mapping products could plug data from various places.
  andreyr: From developers' point of view, it's a huge benefit.
  andreyr: Ton of people looking for this to be a standard.
  andreyr: Asking to see if group is somewhat interested in this.
  andreyr: Can give example of some labels.

  glazou: I'm very interested in the fact that someone is reusing
          the general CSS syntax and grammar to do something else.
  glazou: I've done such a thing in the past.
  glazou: Very well reusable for other things than CSS.
  glazou: I don't exclude possibility that we will kill XSLT in
          favor of solution with CSS syntax.
  glazou: We could probably extract a few things about requirements
          for CSS grammar.
  glazou: Things we don't do right now because our only use case is
          CSS.
  glazou: ... looking at existing CSS parsers.
  glazou: Can only do that if general syntax and grammar allow it,
  glazou: So look into that.
  Florian: I think it's not about getting this in CSS, but getting
           the syntax that is used here in CSS.
  glazou: I see that as another client of the syntax and grammar
          modules.
  glazou: You're using rulesets, declarations, properties, values,
  glazou: But have very specific stuff.

  ChrisL: I was at Libre Graphics meeting.
  ChrisL: There was an OSS project called metapolator.
  <liam> [ http://metapolator.com/home/ ]
  ChrisL: Figures out where the centerline is, allows multiple
          weights.
  ChrisL: This is UFO fonts in XML.
  ChrisL: I made up a language called Cascading Property Sheets,
  ChrisL: it had properties, at-rules, etc.,
  ChrisL: CSS syntax for entirely different thing.

  leaverou: There was a project in my research group that used CSS
            syntax to connect DOM trees together.

  leaverou: Also with this kind of thing polyfills for CAS
            (Cascading Attribute Sheets — Tab’s proposal) would be
            much easier to code.

  glazou: What do you want from us?
  andreyr: If becomes a standard, then more people would use it.
  andreyr: If vendors implement that, then,
  andreyr: could mash up bing and google maps.
  andreyr: In Bloomberg we combine maps from different organizations.
  glazou: Are you suggesting that all the properties can be
          retrieved from CSS and SVG properties?
  glazou: Your text name looks like content property.
  glazou: It could probably better align with SVG and SVG
  glazou: You said turn it into a standard.
  glazou: That wouldn't be CSS, right.
  glazou: It's another standard

  Bert: There's a number of things that shared and others not shared.
  Bert: E.g. selectors, if they need new selectors, have a single
        selectors space.
  Bert: Styling lines along edge of road on the map,
  Bert: Those not need to be shared,
  Bert: But then also styling font of labels.
  Bert: Could reduce duplication by referencing CSS.
  Bert: Could look for overlap, but other things, nice property but
        not in our scope.

  glazou: It's a naive question...
  glazou: Is Bloomberg somehow behind this?
  Andreyr: No. Multiple OSS actually doing this. Just happened to
           stumble upon it.
  plinss: We have prior art of adding properties to CSS from SVG.
  plinss: If web-exposed, then might need to add more properties.
  plinss: But could have a task force or whatever.
  glazou: We would need a contributor. we know nothing about this.

  fantasai: Question - is this something that needs to be built into
            the layout engine? Or is this something that would go
            into some kind of SVG-output framework?
  andreyr: Both.
  glazou: So this:
          ::label {
            text-name: [name];
            text-face-name: 'Arial regular';
          }
  glazou: Are they wanting to change this to match CSS syntax?
  glazou: Because this is content and font-family properties.
  fantasai: [...]

  tantek: I like the use cases here,
  tantek: Other cases would find it useful,
  tantek: e.g. want to style name of someone in an image.
  tantek: It's kind of like a map.
  tantek: Happy to see you bring this up.
  tantek: Good for this group to look at.
  tantek: There's expertise to do this is here.
  tantek: In addition, think it would be helpful to find the
          limitations of where things like HTML's imagemaps <area>
          and <map>, don't quite let you do what you want.
  tantek: Think there's potential for reuse.
  tantek: I would like to see problems solved, especially for use
          case of marking up a photo with a note,
  tantek: e.g. something here, put a label there.
  tantek: hyperlink to name of person.

  leaverou: When I've mentioned a few examples, thought that CSS
            grammar and cascading and inheritance are a good
            framework for other languages.
  leaverou: Not for incorporating this into CSS.
  leaverou: I think a lot of languages invented that follow this
            framework,
  leaverou: Offer those as tools for them to use in their languages.
  leaverou: Expose the CSS parser, the mechanism for specificity,
            cascading, inheritance, have events like propertyapplied
            and propertyunapplied.
  leaverou: Then they have tools to implement this to CSS.
  leaverou: I think it's out of scope for us to add every
            CSSlike-framework-syntax-language's properties into CSS.
  plinss: If we have a reason to pull maps in as a native part of
          the web platform, then makes sense to bring things into
          CSS.

  Florian: I'm saying, are we interested in cooperating with these
           people? Yes.
  Florian: But what kind of cooperation?
  Florian: We definitely want to help groups like these make
           CSS-like languages.
  Florian: In addition, for this groups, if this is [...] then we
           might synchronize with that.
  Florian: But we need to discuss whether that's the case.
  plinss: Houdini should discuss use case of building CSS-like
          languages with syntax, cascading, etc.

  fantasai: Not sure what this is about, but there's some cases
            where it might not be appropriate to try to involve in
            the CSSWG, but maybe create own standards group, here at
            W3C, or elsewhere, or ad-hoc.
  fantasai: E.g. there were industries that got together to design
            an XML syntax for interchange of information specific to
            their industry.
  fantasai: They built their own standard for that format. Didn't
            need to get involved in XML Core WG.
  tantek: Consider a community group.

  plinss: Thank you to Andrey and Bloomberg for hosting.
  [Meeting adjourned]

Received on Saturday, 20 June 2015 12:45:16 UTC