// Copyright 2019 The MediaPipe Authors.
//
// 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 = "proto2";

package mediapipe;

import "mediapipe/util/color.proto";

// A RenderData is a collection of multiple RenderAnnotations. For example, a
// face can be rendered using a group of annotations: a bounding box around the
// face (rectangle) and annotations for various face parts such as eyes, nose
// etc (2D points).
message RenderData {
  repeated RenderAnnotation render_annotations = 1;

  // An optional string that uniquely identifies this class of annotations.
  optional string scene_class = 2;

  // An optional viewport to which this set of annotations are intended to be
  // rendered. If left unset, the annotations are meant to render overtop of the
  // existing camera feed in the "main" viewport. If set, the annotations are to
  // be rendered in a separate viewport.
  optional RenderViewport scene_viewport = 3;
}

message RenderAnnotation {
  message Rectangle {
    // Left and top refer to the x and y coordinates of the top-left corner
    // of rectangle, whereas right and bottom refer to the x and y coordinates
    // of the bottom-right corner of rectangle.
    optional double left = 1;
    optional double top = 2;
    optional double right = 3;
    optional double bottom = 4;
    optional bool normalized = 5 [default = false];
    optional double rotation = 6;  // Rotation in radians.
    // Radius of top left corner circle.
    optional double top_left_thickness = 7;
  }

  message FilledRectangle {
    optional Rectangle rectangle = 1;

    // Color to fill in the rectangle.
    optional Color fill_color = 2;
  }

  message RoundedRectangle {
    // A rounded rectangle is specified by a rectangle and a corner radius to
    // round each corner by. A corner radius of 0 implies a standard non-rounded
    // rectangle (i.e. sharp edges) but as the radius increases proportionally
    // to the width and height of the overall rectangle size, the corners
    // increasingly round.
    optional Rectangle rectangle = 1;

    // The radius of the round corners.
    optional int32 corner_radius = 2 [default = 0];

    // Use one of the following:
    // -1: a filled line (FILLED)
    //  4: a 4-connected line (LINE_4)
    //  8: a 8-connected line (LINE_8)
    // 16: an antialiased line (LINE_AA).
    optional int32 line_type = 3 [default = 4];
  }

  message FilledRoundedRectangle {
    optional RoundedRectangle rounded_rectangle = 1;

    // Color to fill in the rounded rectangle.
    optional Color fill_color = 2;
  }

  message Oval {
    // An oval is specified by the rectangle that encloses the oval. For
    // example, a circle with center at (x,y) and radius r can be specified as a
    // Rectangle with left = x - r, right = y - r, and width = height = 2 * r.
    optional Rectangle rectangle = 1;
  }

  message FilledOval {
    optional Oval oval = 1;

    // Color to fill in the oval.
    optional Color fill_color = 2;
  }

  message Point {
    optional double x = 1;
    optional double y = 2;
    optional bool normalized = 3 [default = false];
  }

  message Line {
    optional double x_start = 1;
    optional double y_start = 2;
    optional double x_end = 3;
    optional double y_end = 4;
    optional bool normalized = 5 [default = false];
    enum LineType {
      UNKNOWN = 0;
      SOLID = 1;
      DASHED = 2;
    }
    optional LineType line_type = 6 [default = SOLID];
  }

  message GradientLine {
    optional double x_start = 1;
    optional double y_start = 2;
    optional double x_end = 3;
    optional double y_end = 4;
    optional bool normalized = 5 [default = false];
    // Linearly interpolate between color1 and color2 along the line.
    optional Color color1 = 6;
    optional Color color2 = 7;
  }

  message Arrow {
    // The arrow head will be drawn at (x_end, y_end).
    optional double x_start = 1;
    optional double y_start = 2;
    optional double x_end = 3;
    optional double y_end = 4;
    optional bool normalized = 5 [default = false];
  }

  message Text {
    optional string display_text = 1;

    // The location to render the text. Left and baseline refer to the x and y
    // coordinates of the start location of text respectively.
    optional double left = 2;
    optional double baseline = 3;

    // The height of the text from top to baseline. When normalized=true, font
    // height is specified wrt the image height.
    optional double font_height = 4 [default = 8];

    optional bool normalized = 5 [default = false];

    // Specifies the font for the text. Font must be one of the following from
    // OpenCV:
    // cv::FONT_HERSHEY_SIMPLEX (0)
    // cv::FONT_HERSHEY_PLAIN (1)
    // cv::FONT_HERSHEY_DUPLEX (2)
    // cv::FONT_HERSHEY_COMPLEX (3)
    // cv::FONT_HERSHEY_TRIPLEX (4)
    // cv::FONT_HERSHEY_COMPLEX_SMALL (5)
    // cv::FONT_HERSHEY_SCRIPT_SIMPLEX (6)
    // cv::FONT_HERSHEY_SCRIPT_COMPLEX (7)
    optional int32 font_face = 6 [default = 0];

    // Options to center text around the anchor point (left, baseline) by
    // taking into account font shape, size and text length (e.g.,
    // [left, baseline] represent  [center_x, center_y].
    optional bool center_horizontally = 7 [default = false];
    optional bool center_vertically = 8 [default = false];

    // Thickness of the text outline.
    optional double outline_thickness = 11 [default = 0.0];

    // Color of the text outline.
    optional Color outline_color = 12;
  }

  // The RenderAnnotation can be one of the below formats.
  oneof data {
    Rectangle rectangle = 1;
    FilledRectangle filled_rectangle = 2;
    Oval oval = 3;
    FilledOval filled_oval = 4;
    Point point = 5;
    Line line = 6;
    Arrow arrow = 7;
    Text text = 8;
    RoundedRectangle rounded_rectangle = 9;
    FilledRoundedRectangle filled_rounded_rectangle = 10;
    GradientLine gradient_line = 14;
  }

  // Thickness for drawing the annotation.
  optional double thickness = 11 [default = 1.0];

  // Color for drawing the annotation. For FilledRectangle and FilledOval, this
  // color is used only for drawing the boundary.
  optional Color color = 12;

  // A hint regarding what this annotation is for. Should be unique across all
  // annotation types.
  optional string scene_tag = 13;
}

// Represents a destination viewport to render annotations into, when specified
// in RenderData.
message RenderViewport {
  // A unique identifier for this viewport.
  optional string id = 1;

  // The width and height of this viewport in absolute pixels.
  // Normalized coordinates on annotations destined for this viewport as
  // normalized relative to these absolute pixel dimensions.
  // Camera feeds destined for this viewport will be rescaled to match these
  // dimensions.
  // Note: It is not expected that mid-stream resizing should be possible --
  // the visualizer is epxected to use the first dimensions it sees for a given
  // viewport and ignore any ignore subsequent changes.
  optional int32 width_px = 2;
  optional int32 height_px = 3;

  // Set to true if this viewport should render its annotations overtop of a
  // (rescaled to width/height) copy of the camera feed.
  optional bool compose_on_video = 4;
}
