// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package designcompose.definition.element;

import "definition/element/background.proto";
import "definition/element/shader.proto";

option java_package = "com.android.designcompose.definition.element";
option java_multiple_files = true;
option optimize_for = LITE_RUNTIME;

// Path represents a complex shape in a design, defined by a series of commands
// (e.g., move, line, curve) and associated numerical data. It determines the
// outline of graphical elements or UI components.
message Path {
  // WindingRule determines how the interior of a self-intersecting
  // or overlapping path is filled.
  enum WindingRule {
    WINDING_RULE_UNSPECIFIED = 0;
    // NonZero fills regions based on the direction of the path segments as
    // they cross the ray.
    WINDING_RULE_NON_ZERO = 1;
    // EvenOdd fills regions based on whether a ray drawn from a point crosses
    // the path an even or odd number of times.
    WINDING_RULE_EVEN_ODD = 2;
    WINDING_RULE_NONE = 3;
  }

  bytes commands = 1;
  repeated float data = 2;
  WindingRule winding_rule = 3;
}

// Determines the vertical spacing between lines of text.
message LineHeight {
  oneof line_height_type {
    float pixels = 1;
    float percent = 2;
  }
}

// How is a stroke aligned to its containing box?
enum StrokeAlign {
  STROKE_ALIGN_UNSPECIFIED = 0;
  // The stroke is entirely within the containing view. The stroke's outer edge
  // matches the outer edge of the containing view.
  STROKE_ALIGN_INSIDE = 1;
  // The stroke is centered on the edge of the containing view, and extends into
  // the view on the inside, and out of the view on the outside.
  STROKE_ALIGN_CENTER = 2;
  // The stroke is entirely outside of the view. The stroke's inner edge is the
  // outer edge of the containing view.
  STROKE_ALIGN_OUTSIDE = 3;
}

// Stroke weight is either a uniform value for all sides, or individual
// weights for each side.
message StrokeWeight {
  // Individual weights for each side (typically only applied on boxes).
  message Individual {
    float top = 1;
    float right = 2;
    float bottom = 3;
    float left = 4;
  }
  oneof stroke_weight_type {
    // One weight is used for all sides.
    float uniform = 1;
    Individual individual = 2;
  }
}

// A stroke is similar to a border, except that it does not change layout (a
// border insets the children by the border size), it may be inset, centered or
// outset from the view bounds and there can be multiple strokes on a view.
message Stroke {
  StrokeAlign stroke_align = 1;
  StrokeWeight stroke_weight = 2;
  repeated Background strokes = 3;

  // Runtime shader from the shader plugin as stroke.
  // When shader is present, strokes will not be drawn.
  optional element.ShaderData shader_data = 4;
}
