Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ink/brush/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ cc_test(
":type_matchers",
"//ink/color",
"//ink/geometry:angle",
"@com_google_absl//absl/hash:hash_testing",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:status_matchers",
Expand Down Expand Up @@ -106,6 +107,7 @@ cc_test(
":fuzz_domains",
"//ink/geometry:mesh_format",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/hash:hash_testing",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:status_matchers",
"@com_google_absl//absl/strings",
Expand Down Expand Up @@ -158,6 +160,8 @@ cc_test(
"//ink/geometry:angle",
"//ink/geometry:point",
"//ink/types:duration",
"@com_google_absl//absl/hash",
"@com_google_absl//absl/hash:hash_testing",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:status_matchers",
"@com_google_absl//absl/status:statusor",
Expand Down
8 changes: 8 additions & 0 deletions ink/brush/brush.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ class Brush {
sink.Append(brush.ToFormattedString());
}

bool operator==(const Brush& other) const = default;

template <typename H>
friend H AbslHashValue(H h, const Brush& brush) {
return H::combine(std::move(h), brush.family_, brush.color_, brush.size_,
brush.epsilon_);
}

private:
Brush(const BrushFamily& family, const Color& color, float size,
float epsilon);
Expand Down
71 changes: 71 additions & 0 deletions ink/brush/brush_behavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define INK_STROKES_BRUSH_BRUSH_BEHAVIOR_H_

#include <array>
#include <cstdint>
#include <string>
#include <variant>
#include <vector>
Expand Down Expand Up @@ -378,6 +379,12 @@ struct BrushBehavior {

friend bool operator==(const EnabledToolTypes&,
const EnabledToolTypes&) = default;

template <typename H>
friend H AbslHashValue(H h, const EnabledToolTypes& ett) {
return H::combine(std::move(h), ett.unknown, ett.mouse, ett.touch,
ett.stylus);
}
};

static constexpr EnabledToolTypes kAllToolTypes = {
Expand Down Expand Up @@ -461,6 +468,12 @@ struct BrushBehavior {
std::array<float, 2> source_value_range;

friend bool operator==(const SourceNode&, const SourceNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const SourceNode& sn) {
return H::combine(std::move(h), sn.source,
sn.source_out_of_range_behavior, sn.source_value_range);
}
};

// Value node for producing a constant value.
Expand All @@ -471,6 +484,11 @@ struct BrushBehavior {
float value;

friend bool operator==(const ConstantNode&, const ConstantNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const ConstantNode& cn) {
return H::combine(std::move(h), cn.value);
}
};

// Value node for producing a continuous random noise function with values
Expand All @@ -492,6 +510,11 @@ struct BrushBehavior {
float base_period;

friend bool operator==(const NoiseNode&, const NoiseNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const NoiseNode& nn) {
return H::combine(std::move(h), nn.seed, nn.vary_over, nn.base_period);
}
};

//////////////////////////
Expand All @@ -509,6 +532,11 @@ struct BrushBehavior {

friend bool operator==(const ToolTypeFilterNode&,
const ToolTypeFilterNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const ToolTypeFilterNode& ttfn) {
return H::combine(std::move(h), ttfn.enabled_tool_types);
}
};

////////////////////////////
Expand All @@ -534,6 +562,11 @@ struct BrushBehavior {
float damping_gap;

friend bool operator==(const DampingNode&, const DampingNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const DampingNode& dn) {
return H::combine(std::move(h), dn.damping_source, dn.damping_gap);
}
};

// Value node for mapping a value through a response curve.
Expand All @@ -546,6 +579,11 @@ struct BrushBehavior {
EasingFunction response_curve;

friend bool operator==(const ResponseNode&, const ResponseNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const ResponseNode& rn) {
return H::combine(std::move(h), rn.response_curve);
}
};

// Value node for integrating an input value over time or distance.
Expand All @@ -571,6 +609,13 @@ struct BrushBehavior {
std::array<float, 2> integral_value_range;

friend bool operator==(const IntegralNode&, const IntegralNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const IntegralNode& in) {
return H::combine(std::move(h), in.integrate_over,
in.integral_out_of_range_behavior,
in.integral_value_range);
}
};

// Value node for combining two other values with a binary operation.
Expand All @@ -583,6 +628,11 @@ struct BrushBehavior {
BinaryOp operation;

friend bool operator==(const BinaryOpNode&, const BinaryOpNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const BinaryOpNode& bon) {
return H::combine(std::move(h), bon.operation);
}
};

// Value node for interpolating to/from a range of two values.
Expand All @@ -596,6 +646,11 @@ struct BrushBehavior {

friend bool operator==(const InterpolationNode&,
const InterpolationNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const InterpolationNode& in) {
return H::combine(std::move(h), in.interpolation);
}
};

//////////////////////
Expand All @@ -617,6 +672,11 @@ struct BrushBehavior {
std::array<float, 2> target_modifier_range;

friend bool operator==(const TargetNode&, const TargetNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const TargetNode& tn) {
return H::combine(std::move(h), tn.target, tn.target_modifier_range);
}
};

// Terminal node that consumes two input values (angle and magnitude), forming
Expand All @@ -638,6 +698,12 @@ struct BrushBehavior {

friend bool operator==(const PolarTargetNode&,
const PolarTargetNode&) = default;

template <typename H>
friend H AbslHashValue(H h, const PolarTargetNode& ptn) {
return H::combine(std::move(h), ptn.target, ptn.angle_range,
ptn.magnitude_range);
}
};

// A single node in a behavior's graph. Each node type is either a "value
Expand All @@ -659,6 +725,11 @@ struct BrushBehavior {
std::string developer_comment;

friend bool operator==(const BrushBehavior&, const BrushBehavior&) = default;

template <typename H>
friend H AbslHashValue(H h, const BrushBehavior& behavior) {
return H::combine(std::move(h), behavior.nodes, behavior.developer_comment);
}
};

namespace brush_internal {
Expand Down
7 changes: 7 additions & 0 deletions ink/brush/brush_coat.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ namespace ink {
struct BrushCoat {
BrushTip tip;
absl::InlinedVector<BrushPaint, 1> paint_preferences = {BrushPaint{}};

bool operator==(const BrushCoat&) const = default;

template <typename H>
friend H AbslHashValue(H h, const BrushCoat& coat) {
return H::combine(std::move(h), coat.tip, coat.paint_preferences);
}
};

namespace brush_internal {
Expand Down
38 changes: 38 additions & 0 deletions ink/brush/brush_coat_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "gtest/gtest.h"
#include "fuzztest/fuzztest.h"
#include "absl/container/flat_hash_set.h"
#include "absl/hash/hash_testing.h"
#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/str_cat.h"
Expand All @@ -42,6 +43,43 @@ using ::testing::UnorderedElementsAre;

constexpr absl::string_view kTestTextureId = "test-paint";

TEST(BrushCoatTest, Equality) {
BrushCoat coat1, coat2;
EXPECT_EQ(coat1, coat2);

coat1.tip.pinch = 0.5;
EXPECT_NE(coat1, coat2);
coat2.tip.pinch = 0.5;
EXPECT_EQ(coat1, coat2);

coat1.paint_preferences.push_back(BrushPaint{});
EXPECT_NE(coat1, coat2);
coat2.paint_preferences.push_back(BrushPaint{});
EXPECT_EQ(coat1, coat2);

coat1.paint_preferences[0] =
BrushPaint{.self_overlap = BrushPaint::SelfOverlap::kDiscard};
EXPECT_NE(coat1, coat2);
coat2.paint_preferences[0] =
BrushPaint{.self_overlap = BrushPaint::SelfOverlap::kDiscard};
EXPECT_EQ(coat1, coat2);
}

TEST(BrushCoatTest, AbslHash) {
BrushPaint paint_a = {.self_overlap = BrushPaint::SelfOverlap::kDiscard};
BrushPaint paint_b = {};
BrushTip tip_a = {.pinch = 0.1f};
BrushTip tip_b = {.pinch = 0.2f};

EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
{BrushCoat{}, BrushCoat{.tip = tip_a}, BrushCoat{.tip = tip_b},
BrushCoat{.paint_preferences = {paint_a}},
BrushCoat{.paint_preferences = {paint_b}},
BrushCoat{.paint_preferences = {paint_a, paint_b}},
BrushCoat{.tip = tip_a, .paint_preferences = {paint_a}},
BrushCoat{.tip = tip_b, .paint_preferences = {paint_b}}}));
}

TEST(BrushCoatTest, Stringify) {
EXPECT_EQ(absl::StrCat(BrushCoat{.tip = BrushTip{}}),
"BrushCoat{tip=BrushTip{scale=<1, 1>, corner_rounding=1}, "
Expand Down
31 changes: 30 additions & 1 deletion ink/brush/brush_family.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ class BrushFamily {
// the modeled inputs. This can be useful as a point of comparison for other
// input models, or for callers who wish to do their own input modeling prior
// to passing inputs into Ink.
struct PassthroughModel {};
struct PassthroughModel {
bool operator==(const PassthroughModel&) const = default;
template <typename H>
friend H AbslHashValue(H h, const PassthroughModel&) {
return h;
}
};

// Averages nearby inputs together within a sliding time window. To be valid,
// the window size must be finite and strictly positive, and the upsampling
Expand All @@ -57,6 +63,14 @@ class BrushFamily {
// inserted between them. Set this to `Duration32::Infinite()` to disable
// upsampling.
Duration32 upsampling_period = Duration32::Seconds(1.0 / 180.0);

bool operator==(const SlidingWindowModel&) const = default;

template <typename H>
friend H AbslHashValue(H h, const SlidingWindowModel& model) {
return H::combine(std::move(h), model.window_size,
model.upsampling_period);
}
};

// Specifies a model for turning a sequence of raw hardware inputs (e.g. from
Expand Down Expand Up @@ -86,6 +100,12 @@ class BrushFamily {
std::string developer_comment;

bool operator==(const Metadata&) const = default;

template <typename H>
friend H AbslHashValue(H h, const Metadata& metadata) {
return H::combine(std::move(h), metadata.client_brush_family_id,
metadata.developer_comment);
}
};

// Returns the default `InputModel` that will be used by
Expand Down Expand Up @@ -160,6 +180,15 @@ class BrushFamily {
sink.Append(family.ToFormattedString());
}

bool operator==(const BrushFamily& other) const = default;

template <typename H>
friend H AbslHashValue(H h, const BrushFamily& family) {
return H::combine(std::move(h), family.coats_, family.input_model_,
family.metadata_,
family.opaque_decoded_proto_bytes_with_fallbacks_);
}

friend class BrushFamilyInternalAccessor;

private:
Expand Down
Loading
Loading