<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Just to add a bit more about this: <br>
    </p>
    <p>I wouldn't want the condition mechanism for VARC to differ
      substantially from that of Feature Variations. So this raises the
      question of how it will work in the latter context. Is the idea
      that we continue to (rather uselessly) go through the indirection
      of a condition set? Do we rev the FeatureVariationRecord system to
      eliminate the condition set and alter the specification of the
      LookupVariationRecord similarly? Do we just change the
      LookupVariationRecord (which is new, so it's not a rev) on the
      theory that it will almost always be used, and the indirection
      through the ConditionSet for the FeatureVariationRecord doesn't
      matter enough to worry about?</p>
    <p>I suppose if we go this way I would favor changing the
      LookupVariationRecord and leaving the FeatureVariationRecord as is
      (so, supporting the new formats but still going though a condition
      set).<br>
    </p>
    <p>Skef<br>
    </p>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">On 4/11/24 13:40, Skef Iterum via
      mpeg-otspec wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:f1f6b1ae-019e-4e7b-b81e-2bd34e595ff6@skef.org">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <p>This proposal is a particular way of supporting arbitrary
        boolean expressions in OFF. That does have the benefit of "just
        doing it" -- it's certainly preferable to adding significantly
        more complexity while falling short of total generality.</p>
      <p>However, there were presumably reasons this route wasn't taken
        to begin with, probably having to do with complexity, and those
        would have to be discussed. I.e.: Is this too much rope? <br>
      </p>
      <p>This direction would be fine with me if it's fine with the
        group, but I feel that would a discussion for the upcoming, more
        onerous phase of work, not to squeeze in before the up coming
        deadline. <br>
      </p>
      <p>Skef<br>
      </p>
      <div class="moz-cite-prefix">On 4/11/24 08:44, Behdad Esfahbod
        wrote:<br>
      </div>
      <blockquote type="cite"
cite="mid:CAF63+7XmJ4m24+xmxYgdXgZSbU=354BewZJ8BC_vJj5YK2DM_A@mail.gmail.com">
        <meta http-equiv="content-type"
          content="text/html; charset=UTF-8">
        <div dir="ltr">Thanks Skef.
          <div><br>
          </div>
          <div>I think I found the right approach for this (taking ideas
            from COLRv1 paint tree / graph). Ignoring your other
            proposals, we add these:</div>
          <div><br>
          </div>
          <div>We add new Condition's that implement AND of a bunch of
            Conditions (like the current ConditionSet does), another for
            OR, and another for NEGATE:</div>
          <div><br>
          </div>
          <div>struct ConditionAnd</div>
          <div>{</div>
          <div>  uint16 format; // 2</div>
          <div>  uint16 conditionCount; // Number of conditions for this
            conjunction expression.</div>
            Offset32To<Condition>
          conditionOffsets[conditionCount];
          <div>}</div>
          <div><br>
          </div>
          <div>
            <div>struct ConditionOr<br>
            </div>
            <div>{</div>
            <div>  uint16 format; // 3</div>
            <div>  uint16 conditionCount; // Number of conditions for
              this disjunction expression.</div>
              Offset32To<Condition>
            conditionOffsets[conditionCount];
            <div>}</div>
          </div>
          <div>
            <div>
              <div><br>
              </div>
              <div>struct ConditionNegate<br>
              </div>
              <div>{</div>
              <div>  uint16 format; // 4</div>
                Offset32To<Condition> condition;
              <div>}</div>
              <div><br>
              </div>
              <div>WDYT?</div>
            </div>
            <div>
              <div dir="ltr" class="gmail_signature"
                data-smartmail="gmail_signature">behdad<br>
                <a href="http://behdad.org/" target="_blank"
                  moz-do-not-send="true" class="moz-txt-link-freetext">http://behdad.org/</a></div>
            </div>
            <br>
          </div>
        </div>
        <br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Thu, Apr 11, 2024 at
            6:26 AM Skef Iterum <<a href="mailto:skef@skef.org"
              moz-do-not-send="true" class="moz-txt-link-freetext">skef@skef.org</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div>
              <p>I'm still trying to think through all of this stuff,
                but I tentatively think that if we added a hack to
                negate a condition set then we'll have enough. <br>
              </p>
              <p>To see the issues involved it may be easiest to work
                backwards. It's not an accident that most programming
                languages contain the combination of boolean expressions
                (with AND, OR, NOT and some equivalent of parentheses) +
                an if/else if/.../else structure. The former lets you
                express anything you need to, typically quite compactly.
                The latter expresses a set of alternatives such that
                it's guaranteed you'll only get one of them. <br>
              </p>
              <p>With arbitrary boolean expressions it's easy to fake up
                the if/else if/else. If you would have had</p>
              <blockquote>
                <p><font face="monospace">if A<br>
                        R<br>
                    else if B<br>
                        S<br>
                    else if C<br>
                        T<br>
                    else if D<br>
                        U<br>
                    else<br>
                        V</font></p>
              </blockquote>
              <p>you can just do</p>
              <blockquote>
                <p><font face="monospace">if A<br>
                        R<br>
                    if ~A & B<br>
                        S<br>
                    if ~A & ~B & C<br>
                        T<br>
                    if ~A & ~B & ~C & D<br>
                        U<br>
                    if ~A & ~B & ~C & ~D<br>
                        V</font></p>
              </blockquote>
              <p>at the cost of a bit more computation (typically). <br>
              </p>
              <p>This kind of generality was (presumably) thought to be
                <i>over</i>-general for variable fonts, and I don't
                disagree. But it's worth noting what you lose if you
                lack <i>both</i> arbitrary boolean expressions <i>and</i>
                if/else if/.../else. Say we add condition set negation.
                Then if you have a fairly typical case like the
                following (where brackets indicate a set)<br>
              </p>
              <blockquote>
                <p><font face="monospace">if [A & C]<br>
                        R<br>
                    else<br>
                        S</font></p>
              </blockquote>
              <p>You can replace that with</p>
              <blockquote>
                <p><font face="monospace">if [A & C]<br>
                        R<br>
                    if ~[A & C]<br>
                        S</font></p>
              </blockquote>
              <p>However, <i>at a single level</i> that doesn't extend
                further. So if you have</p>
              <blockquote>
                <p><font face="monospace">if [A & C]<br>
                        R<br>
                    else if [D & E]<br>
                        S<br>
                    else<br>
                        T</font></p>
              </blockquote>
              <p>(which is just adding a third case), there's no easy
                way to adapt that into pure "if" conditions using the
                tools available. And that's what I've been worried about
                -- it seems annoying not to be able to have three
                alternatives (with non-trivial conditions) spread out
                over the design space. <br>
              </p>
              <p>However, it seems like you can accomplish the
                equivalent with an extra level. Assume <font
                  face="monospace">R</font>, <font face="monospace">S</font>,
                and <font face="monospace">T</font> are "existing"
                components. Then you can just do</p>
              <blockquote>
                <p><font face="monospace">a:</font><br>
                  <font face="monospace">if [D & E]<br>
                        S<br>
                    if ~[D & E]<br>
                        T</font></p>
                <p><font face="monospace">b:</font><br>
                  <font face="monospace">if [A & C]<br>
                        R<br>
                    if ~[A & C]<br>
                        a</font></p>
              </blockquote>
              <p>Now <font face="monospace">b</font> has the right
                qualities. In effect, <font face="monospace">a</font>
                sometimes has the "wrong" contents when <font
                  face="monospace">[A & C]</font> applies but you
                never <i>see</i> it in that case.<br>
              </p>
              <p>So like I said I want to think about this a bit more
                but I tentatively think the thing to do is add means of
                negating the condition set (and I think the Format 5
                condition hack would be fine for that, actually), and
                remove the "else" from the lookup-based feature
                variations mechanism to simplify it.</p>
              <p>Skef<br>
              </p>
              <div>On 4/11/24 01:20, Behdad Esfahbod wrote:<br>
              </div>
              <blockquote type="cite">
                <div dir="ltr">Hi Skef,
                  <div><br>
                  </div>
                  <div>I'm a bit uncomfortable encoding if/else in VARC.
                    As you said on the call, the current design seems
                    like a practical compromise. As for negation, we
                    *can* add a flag to the component to negate the
                    condition. Maybe that's the right approach. But I
                    feel like the conditionSet itself should contain the
                    negation. That would reduce sharing though.</div>
                  <div><br>
                  </div>
                  <div>A "negate the rest" condition type sounds good to
                    me.<br>
                  </div>
                  <div><br clear="all">
                    <div>
                      <div dir="ltr" class="gmail_signature">behdad<br>
                        <a href="http://behdad.org/" target="_blank"
                          moz-do-not-send="true"
                          class="moz-txt-link-freetext">http://behdad.org/</a></div>
                    </div>
                    <br>
                  </div>
                </div>
                <br>
                <div class="gmail_quote">
                  <div dir="ltr" class="gmail_attr">On Mon, Apr 8, 2024
                    at 1:55 PM Skef Iterum via mpeg-otspec <<a
                      href="mailto:mpeg-otspec@lists.aau.at"
                      target="_blank" moz-do-not-send="true"
                      class="moz-txt-link-freetext">mpeg-otspec@lists.aau.at</a>>
                    wrote:<br>
                  </div>
                  <blockquote class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                    <div>
                      <p>A note on conditions as defined in
                        WG03-varc-and-other-updates-03.pdf (up for
                        review tomorrow morning).</p>
                      <p>When I sketched out the VARC condition idea I
                        had them arranged in if/else if/.../else
                        sequences. From my reading of the document
                        they're currently in "if" form -- a condition
                        set can be attached to a component and if it is
                        it will only be used if the condition set
                        evaluates to true.</p>
                      <p>There's nothing wrong with that semantic; it
                        may be preferable because it's simpler. However,
                        the most common case with this system is that
                        you want one shape to render in some region of
                        design space (defined by the condition set) and
                        another shape to render outside of that. And
                        negating a condition <i>set</i> can be
                        expensive and/or tricky. So I would recommend
                        that one of these two things change:<br>
                      </p>
                      <ul>
                        <li>The if/else if/.../else semantic is restored</li>
                        <li>Some way of negating a condition set is
                          added to the specification<br>
                        </li>
                      </ul>
                      <p>We talked about the possibility of condition
                        set negation in a previous meeting but didn't
                        come to any conclusions. It's tricky because the
                        table has no versioning. If we wanted to hack
                        negations into the current format the way to do
                        that might be to add a new condition format
                        (possibly 5 if newfeatvar_spec.pdf is accepted)
                        that looks something like:<br>
                      </p>
                      <blockquote>
                        <p>ConditionTableFormat5</p>
                      </blockquote>
                      <blockquote>
                        <p><b>Type                   
                            Name                               
                            Description</b></p>
                        <p>uint16                 
                          Format                              Format
                          (set to 5)</p>
                      </blockquote>
                      <blockquote>
                        <p>When present in a condition set this
                          condition indicates the set should apply when<br>
                          at least one of the other conditions is false
                          and not otherwise. That is, it makes the<br>
                          condition set apply when it would normally not
                          and vice-versa. There should be at <br>
                          most one format 5 condition in a condition set
                          and it should be the first.<br>
                        </p>
                      </blockquote>
                      <p>If this is preferred it could be used to
                        replace/simplify the
                        trueLookupIndexListOffset/falseLookupIndexListOffset
                        pair in the LookupCondition record of
                        newfeatvar_spec.pdf to just
                        lookupIndexListOffset (because one could just
                        follow the record<br>
                        with the "positive" condition set with another
                        record with the negated one when needed).</p>
                      <p>Skef<br>
                      </p>
                    </div>
                    _______________________________________________<br>
                    mpeg-otspec mailing list<br>
                    <a href="mailto:mpeg-otspec@lists.aau.at"
                      target="_blank" moz-do-not-send="true"
                      class="moz-txt-link-freetext">mpeg-otspec@lists.aau.at</a><br>
                    <a
href="https://lists.aau.at/mailman/listinfo/mpeg-otspec"
                      rel="noreferrer" target="_blank"
                      moz-do-not-send="true"
                      class="moz-txt-link-freetext">https://lists.aau.at/mailman/listinfo/mpeg-otspec</a><br>
                  </blockquote>
                </div>
              </blockquote>
            </div>
          </blockquote>
        </div>
      </blockquote>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
mpeg-otspec mailing list
<a class="moz-txt-link-abbreviated" href="mailto:mpeg-otspec@lists.aau.at">mpeg-otspec@lists.aau.at</a>
<a class="moz-txt-link-freetext" href="https://lists.aau.at/mailman/listinfo/mpeg-otspec">https://lists.aau.at/mailman/listinfo/mpeg-otspec</a>
</pre>
    </blockquote>
  </body>
</html>