Skip to content

Commit 1f8f259

Browse files
Ink Open Sourcecopybara-github
authored andcommitted
Add BrushBehavior::BinaryOp::kMin and kMax operators
PiperOrigin-RevId: 867598397
1 parent d5d1a2b commit 1f8f259

File tree

8 files changed

+74
-0
lines changed

8 files changed

+74
-0
lines changed

ink/brush/brush_behavior.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ bool IsValidBehaviorBinaryOp(BrushBehavior::BinaryOp operation) {
221221
switch (operation) {
222222
case BrushBehavior::BinaryOp::kProduct:
223223
case BrushBehavior::BinaryOp::kSum:
224+
case BrushBehavior::BinaryOp::kMin:
225+
case BrushBehavior::BinaryOp::kMax:
224226
return true;
225227
}
226228
return false;
@@ -677,6 +679,10 @@ std::string ToFormattedString(BrushBehavior::BinaryOp operation) {
677679
return "kProduct";
678680
case BrushBehavior::BinaryOp::kSum:
679681
return "kSum";
682+
case BrushBehavior::BinaryOp::kMin:
683+
return "kMin";
684+
case BrushBehavior::BinaryOp::kMax:
685+
return "kMax";
680686
}
681687
return absl::StrCat("BinaryOp(", static_cast<int>(operation), ")");
682688
}

ink/brush/brush_behavior.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,8 @@ struct BrushBehavior {
403403
enum class BinaryOp {
404404
kProduct, // A * B, or null if either is null
405405
kSum, // A + B, or null if either is null
406+
kMin, // min(A, B), or null if either is null
407+
kMax, // max(A, B), or null if either is null
406408
};
407409
// LINT.ThenChange(
408410
// fuzz_domains.cc:binary_op,

ink/brush/brush_behavior_test.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ TEST(BrushBehaviorTest, StringifyOptionalInputProperty) {
235235
TEST(BrushBehaviorTest, StringifyBinaryOp) {
236236
EXPECT_EQ(absl::StrCat(BrushBehavior::BinaryOp::kProduct), "kProduct");
237237
EXPECT_EQ(absl::StrCat(BrushBehavior::BinaryOp::kSum), "kSum");
238+
EXPECT_EQ(absl::StrCat(BrushBehavior::BinaryOp::kMin), "kMin");
239+
EXPECT_EQ(absl::StrCat(BrushBehavior::BinaryOp::kMax), "kMax");
238240
EXPECT_EQ(absl::StrCat(static_cast<BrushBehavior::BinaryOp>(147)),
239241
"BinaryOp(147)");
240242
}

ink/brush/fuzz_domains.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ Domain<BrushBehavior::BinaryOp> ArbitraryBrushBehaviorBinaryOp() {
128128
return ElementOf({
129129
BrushBehavior::BinaryOp::kProduct,
130130
BrushBehavior::BinaryOp::kSum,
131+
BrushBehavior::BinaryOp::kMin,
132+
BrushBehavior::BinaryOp::kMax,
131133
});
132134
}
133135
// LINT.ThenChange(brush_behavior.h:binary_op)

ink/storage/brush.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ proto::BrushBehavior::BinaryOp EncodeBrushBehaviorBinaryOp(
5656
return proto::BrushBehavior::BINARY_OP_PRODUCT;
5757
case BrushBehavior::BinaryOp::kSum:
5858
return proto::BrushBehavior::BINARY_OP_SUM;
59+
case BrushBehavior::BinaryOp::kMin:
60+
return proto::BrushBehavior::BINARY_OP_MIN;
61+
case BrushBehavior::BinaryOp::kMax:
62+
return proto::BrushBehavior::BINARY_OP_MAX;
5963
}
6064
return proto::BrushBehavior::BINARY_OP_UNSPECIFIED;
6165
}
@@ -67,6 +71,10 @@ absl::StatusOr<BrushBehavior::BinaryOp> DecodeBrushBehaviorBinaryOp(
6771
return BrushBehavior::BinaryOp::kProduct;
6872
case proto::BrushBehavior::BINARY_OP_SUM:
6973
return BrushBehavior::BinaryOp::kSum;
74+
case proto::BrushBehavior::BINARY_OP_MIN:
75+
return BrushBehavior::BinaryOp::kMin;
76+
case proto::BrushBehavior::BINARY_OP_MAX:
77+
return BrushBehavior::BinaryOp::kMax;
7078
default:
7179
return absl::InvalidArgumentError(absl::StrCat(
7280
"invalid ink.proto.BrushBehavior.BinaryOp value: ", binary_op_proto));

ink/storage/proto/brush_family.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,12 @@ message BrushBehavior {
948948

949949
// A + B, or null if either is null
950950
BINARY_OP_SUM = 2;
951+
952+
// min(A, B), or null if either is null
953+
BINARY_OP_MIN = 3;
954+
955+
// max(A, B), or null if either is null
956+
BINARY_OP_MAX = 4;
951957
}
952958
// LINT.ThenChange(../../brush/brush_behavior.h:binary_op)
953959

ink/strokes/internal/brush_tip_modeler_helpers.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,18 @@ void ProcessBehaviorNodeImpl(const BrushBehavior::BinaryOpNode& node,
497497
// the result will be null (NaN).
498498
*result = first_input + second_input;
499499
break;
500+
case BrushBehavior::BinaryOp::kMin:
501+
*result = IsNullBehaviorNodeValue(first_input) ||
502+
IsNullBehaviorNodeValue(second_input)
503+
? kNullBehaviorNodeValue
504+
: std::min(first_input, second_input);
505+
break;
506+
case BrushBehavior::BinaryOp::kMax:
507+
*result = IsNullBehaviorNodeValue(first_input) ||
508+
IsNullBehaviorNodeValue(second_input)
509+
? kNullBehaviorNodeValue
510+
: std::max(first_input, second_input);
511+
break;
500512
}
501513
// If any of the above operations resulted in a non-finite value
502514
// (e.g. overflow to infinity), treat the result as null.

ink/strokes/internal/brush_tip_modeler_helpers_test.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,42 @@ TEST_F(ProcessBehaviorNodeTest, BinaryOpNodeProduct) {
13421342
EXPECT_THAT(stack_, ElementsAre(NullNodeValueMatcher()));
13431343
}
13441344

1345+
TEST_F(ProcessBehaviorNodeTest, BinaryOpNodeMin) {
1346+
BrushBehavior::BinaryOpNode binary_op_node = {
1347+
.operation = BrushBehavior::BinaryOp::kMin};
1348+
1349+
stack_.push_back(2.0f);
1350+
stack_.push_back(3.0f);
1351+
ProcessBehaviorNode(binary_op_node, context_);
1352+
EXPECT_THAT(stack_, ElementsAre(2.0f));
1353+
1354+
// `kMin` returns null when either of the two inputs is null.
1355+
stack_.push_back(kNullBehaviorNodeValue);
1356+
ProcessBehaviorNode(binary_op_node, context_);
1357+
EXPECT_THAT(stack_, ElementsAre(NullNodeValueMatcher()));
1358+
stack_.push_back(1.0f);
1359+
ProcessBehaviorNode(binary_op_node, context_);
1360+
EXPECT_THAT(stack_, ElementsAre(NullNodeValueMatcher()));
1361+
}
1362+
1363+
TEST_F(ProcessBehaviorNodeTest, BinaryOpNodeMax) {
1364+
BrushBehavior::BinaryOpNode binary_op_node = {
1365+
.operation = BrushBehavior::BinaryOp::kMax};
1366+
1367+
stack_.push_back(2.0f);
1368+
stack_.push_back(3.0f);
1369+
ProcessBehaviorNode(binary_op_node, context_);
1370+
EXPECT_THAT(stack_, ElementsAre(3.0f));
1371+
1372+
// `kMax` returns null when either of the two inputs is null.
1373+
stack_.push_back(kNullBehaviorNodeValue);
1374+
ProcessBehaviorNode(binary_op_node, context_);
1375+
EXPECT_THAT(stack_, ElementsAre(NullNodeValueMatcher()));
1376+
stack_.push_back(1.0f);
1377+
ProcessBehaviorNode(binary_op_node, context_);
1378+
EXPECT_THAT(stack_, ElementsAre(NullNodeValueMatcher()));
1379+
}
1380+
13451381
TEST_F(ProcessBehaviorNodeTest, InterpolationNodeLerp) {
13461382
BrushBehavior::InterpolationNode interpolation_node = {
13471383
.interpolation = BrushBehavior::Interpolation::kLerp,

0 commit comments

Comments
 (0)