<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<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>
</body>
</html>