[MPEG-OTSPEC] Note on VARC conditions and condition set negation
Skef Iterum
skef at skef.org
Thu Apr 11 22:40:35 CEST 2024
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.
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?
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.
Skef
On 4/11/24 08:44, Behdad Esfahbod wrote:
> Thanks Skef.
>
> I think I found the right approach for this (taking ideas from COLRv1
> paint tree / graph). Ignoring your other proposals, we add these:
>
> 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:
>
> struct ConditionAnd
> {
> uint16 format; // 2
> uint16 conditionCount; // Number of conditions for this conjunction
> expression.
> Offset32To<Condition> conditionOffsets[conditionCount];
> }
>
> struct ConditionOr
> {
> uint16 format; // 3
> uint16 conditionCount; // Number of conditions for this disjunction
> expression.
> Offset32To<Condition> conditionOffsets[conditionCount];
> }
>
> struct ConditionNegate
> {
> uint16 format; // 4
> Offset32To<Condition> condition;
> }
>
> WDYT?
> behdad
> http://behdad.org/
>
>
> On Thu, Apr 11, 2024 at 6:26 AM Skef Iterum <skef at skef.org> wrote:
>
> 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.
>
> 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.
>
> With arbitrary boolean expressions it's easy to fake up the
> if/else if/else. If you would have had
>
> if A
> R
> else if B
> S
> else if C
> T
> else if D
> U
> else
> V
>
> you can just do
>
> if A
> R
> if ~A & B
> S
> if ~A & ~B & C
> T
> if ~A & ~B & ~C & D
> U
> if ~A & ~B & ~C & ~D
> V
>
> at the cost of a bit more computation (typically).
>
> This kind of generality was (presumably) thought to be
> /over/-general for variable fonts, and I don't disagree. But it's
> worth noting what you lose if you lack /both/ arbitrary boolean
> expressions /and/ 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)
>
> if [A & C]
> R
> else
> S
>
> You can replace that with
>
> if [A & C]
> R
> if ~[A & C]
> S
>
> However, /at a single level/ that doesn't extend further. So if
> you have
>
> if [A & C]
> R
> else if [D & E]
> S
> else
> T
>
> (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.
>
> However, it seems like you can accomplish the equivalent with an
> extra level. Assume R, S, and T are "existing" components. Then
> you can just do
>
> a:
> if [D & E]
> S
> if ~[D & E]
> T
>
> b:
> if [A & C]
> R
> if ~[A & C]
> a
>
> Now b has the right qualities. In effect, a sometimes has the
> "wrong" contents when [A & C] applies but you never /see/ it in
> that case.
>
> 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.
>
> Skef
>
> On 4/11/24 01:20, Behdad Esfahbod wrote:
>> Hi Skef,
>>
>> 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.
>>
>> A "negate the rest" condition type sounds good to me.
>>
>> behdad
>> http://behdad.org/
>>
>>
>> On Mon, Apr 8, 2024 at 1:55 PM Skef Iterum via mpeg-otspec
>> <mpeg-otspec at lists.aau.at> wrote:
>>
>> A note on conditions as defined in
>> WG03-varc-and-other-updates-03.pdf (up for review tomorrow
>> morning).
>>
>> 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.
>>
>> 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 /set/ can be expensive and/or tricky. So I would
>> recommend that one of these two things change:
>>
>> * The if/else if/.../else semantic is restored
>> * Some way of negating a condition set is added to the
>> specification
>>
>> 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:
>>
>> ConditionTableFormat5
>>
>> *Type Name Description*
>>
>> uint16 Format Format (set to 5)
>>
>> When present in a condition set this condition indicates
>> the set should apply when
>> at least one of the other conditions is false and not
>> otherwise. That is, it makes the
>> condition set apply when it would normally not and
>> vice-versa. There should be at
>> most one format 5 condition in a condition set and it
>> should be the first.
>>
>> 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
>> with the "positive" condition set with another record with
>> the negated one when needed).
>>
>> Skef
>>
>> _______________________________________________
>> mpeg-otspec mailing list
>> mpeg-otspec at lists.aau.at
>> https://lists.aau.at/mailman/listinfo/mpeg-otspec
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.aau.at/pipermail/mpeg-otspec/attachments/20240411/d4038ce4/attachment-0001.htm>
More information about the mpeg-otspec
mailing list