瀏覽代碼

add some data_type classes

melon.yin 2 年之前
父節點
當前提交
879a18df10

+ 1 - 0
lib/interfaces/date_types/matrix.dart

@@ -0,0 +1 @@
+class DMatrix {}

+ 83 - 0
lib/interfaces/date_types/point.dart

@@ -0,0 +1,83 @@
+import 'dart:math' show Point;
+
+import 'package:flutter/painting.dart' show Offset;
+
+import 'vector.dart';
+
+class DPoint {
+  static final zero = DPoint(0, 0);
+
+  double _x = 0;
+  double _y = 0;
+
+  // ignore: unnecessary_getters_setters
+  double get x => _x;
+  set x(double value) => _x = value;
+
+  // ignore: unnecessary_getters_setters
+  double get y => _y;
+  set y(double value) => _y = value;
+
+  DPoint(double x, double y) {
+    _x = x;
+    _y = y;
+  }
+
+  Offset toOffset() => Offset(x, y);
+
+  Point toInnerPoint() => Point(x, y);
+
+  @override
+  String toString() => '$x,$y';
+
+  void addOffset(double offsetX, double offsetY) {
+    _x += offsetX;
+    _y += offsetY;
+  }
+
+  DPoint addVector(DVector vector) {
+    _x += vector.x;
+    _y += vector.y;
+    return this;
+  }
+
+  DPoint subtractVector(DVector vector) {
+    _x -= vector.x;
+    _y -= vector.y;
+    return this;
+  }
+
+  static DPoint parse(String source) {
+    var splits = source.split(',');
+    if (splits.length != 2) {
+      throw ArgumentError("Parse $source to DPoint failed");
+    }
+    return DPoint(double.parse(splits[0]), double.parse(splits[1]));
+  }
+
+  static DPoint parsePoint(Point<double> point) {
+    return DPoint(point.x, point.y);
+  }
+
+  static DPoint parseOffset(Offset offset) {
+    return DPoint(offset.dx, offset.dy);
+  }
+
+  @override
+  bool operator ==(Object other) =>
+      other is DPoint && x == other.x && y == other.y;
+
+  bool operator <(DPoint other) =>
+      toInnerPoint().magnitude < other.toInnerPoint().magnitude;
+  bool operator <=(DPoint other) =>
+      toInnerPoint().magnitude <= other.toInnerPoint().magnitude;
+  bool operator >(DPoint other) =>
+      toInnerPoint().magnitude > other.toInnerPoint().magnitude;
+  bool operator >=(DPoint other) =>
+      toInnerPoint().magnitude >= other.toInnerPoint().magnitude;
+
+  DVector operator -(DPoint other) => DVector(x - other.x, y - other.y);
+
+  @override
+  int get hashCode => x.hashCode ^ y.hashCode;
+}

+ 240 - 0
lib/interfaces/date_types/rect.dart

@@ -0,0 +1,240 @@
+import 'dart:math' as math;
+import 'package:fis_common/logger/logger.dart';
+import 'package:fis_measure/vid.dart';
+
+import 'size.dart';
+
+class DRect {
+  static final DRect empty = DRect(
+    double.infinity,
+    double.infinity,
+    double.negativeInfinity,
+    double.negativeInfinity,
+  );
+
+  late double _x;
+  late double _y;
+  late double _width;
+  late double _height;
+
+  bool get isEmpty => _width < 0;
+
+  double get x => _x;
+  set x(double value) {
+    if (isEmpty) {
+      throw UnsupportedError("Rect_CannotModifyEmptyRect");
+    }
+    _x = value;
+  }
+
+  double get y => _y;
+  set y(double value) {
+    if (isEmpty) {
+      throw UnsupportedError("Rect_CannotModifyEmptyRect");
+    }
+    _y = value;
+  }
+
+  double get width => _width;
+  set width(double value) {
+    if (isEmpty) {
+      throw UnsupportedError("Rect_CannotModifyEmptyRect");
+    }
+    if (value < 0.0) {
+      throw ArgumentError("Size_WidthCannotBeNegative");
+    }
+    _width = value;
+  }
+
+  double get height => _height;
+  set height(double value) {
+    if (isEmpty) {
+      throw UnsupportedError("Rect_CannotModifyEmptyRect");
+    }
+    if (value < 0.0) {
+      throw ArgumentError("Size_HeightCannotBeNegative");
+    }
+    _height = value;
+  }
+
+  double get top => _y;
+  double get left => _x;
+
+  double get right {
+    if (isEmpty) {
+      return double.negativeInfinity;
+    }
+    return (_x + _width);
+  }
+
+  double get bottom {
+    if (isEmpty) {
+      return double.negativeInfinity;
+    }
+    return (_y + height);
+  }
+
+  DRect(double x, double y, double width, double height) {
+    if ((width < 0.0) || (height < 0.0)) {
+      logger.e("Size_WidthAndHeightCannotBeNegative($x,$y,$width,$height)");
+      width = height = 0;
+    }
+    _x = x;
+    _y = y;
+    _width = width;
+    _height = height;
+  }
+
+  factory DRect.fromSize(DSize size) {
+    if (size.isEmpty) return empty;
+    return DRect(0, 0, size.width, size.height);
+  }
+
+  factory DRect.fromPositionedSize(DPoint point, DSize size) {
+    return DRect(point.x, 0, point.y, size.height);
+  }
+
+  factory DRect.fromCrossPoints(DPoint p1, DPoint p2) {
+    final x = math.min(p1.x, p2.x);
+    final y = math.min(p1.y, p2.y);
+    final width = math.max((math.max(p1.x, p2.x) - x), 0.0);
+    final height = math.max((math.max(p1.y, p2.y) - y), 0.0);
+    return DRect(x, y, width, height);
+  }
+
+  bool containsOffset(double x, double y) {
+    if (isEmpty) {
+      return false;
+    }
+    return _containsOffsetInner(x, y);
+  }
+
+  bool containsPoint(DPoint point) => containsOffset(point.x, point.y);
+  bool contains(DRect rect) {
+    if (isEmpty || rect.isEmpty) return false;
+    return ((x <= rect.x && y <= rect.y) &&
+            ((x + width) >= (rect._x + rect._width))) &&
+        ((y + height) >= (rect._y + rect._height));
+  }
+
+  bool intersectsWith(DRect rect) {
+    if (isEmpty || rect.isEmpty) {
+      return false;
+    }
+    return ((((rect.left <= right) && (rect.right >= left)) &&
+            (rect.top <= bottom)) &&
+        (rect.bottom >= top));
+  }
+
+  void intersect(DRect rect) {
+    if (!intersectsWith(rect)) {
+      copyFrom(empty);
+    } else {
+      double num = math.max(left, rect.left);
+      double num2 = math.max(top, rect.top);
+      _width = math.max((math.min(right, rect.right) - num), 0.0);
+      _height = math.max((math.min(bottom, rect.bottom) - num2), 0.0);
+      _x = num;
+      _y = num2;
+    }
+  }
+
+  void union(DRect rect) {
+    if (isEmpty) {
+      copyFrom(rect);
+    } else if (!rect.isEmpty) {
+      double num = math.min(left, rect.left);
+      double num2 = math.min(top, rect.top);
+      if ((rect.width == double.infinity) || (width == double.infinity)) {
+        _width = double.infinity;
+      } else {
+        double num3 = math.max(right, rect.right);
+        _width = math.max((num3 - num), 0.0);
+      }
+      if ((rect.height == double.infinity) || (height == double.infinity)) {
+        _height = double.infinity;
+      } else {
+        double num4 = math.max(bottom, rect.bottom);
+        _height = math.max((num4 - num2), 0.0);
+      }
+      _x = num;
+      _y = num2;
+    }
+  }
+
+  void addOffset(double offsetX, double offsetY) {
+    if (isEmpty) {
+      throw UnsupportedError(("Rect_CannotCallMethod"));
+    }
+    _x += offsetX;
+    _y += offsetY;
+  }
+
+  void inflate(double width, double height) {
+    if (isEmpty) {
+      throw UnsupportedError(("Rect_CannotCallMethod"));
+    }
+    _x -= width;
+    _y -= height;
+    _width += width;
+    _width += width;
+    _height += height;
+    _height += height;
+    if ((_width < 0.0) || (_height < 0.0)) {
+      copyFrom(empty);
+    }
+  }
+
+  static DRect parse(String source) {
+    DRect rect;
+    if (source == "Empty") {
+      rect = empty;
+    } else {
+      var items = source.split(',');
+      if (items.length != 4) {
+        throw ArgumentError("$source can not be parsed to DRect");
+      }
+      rect = DRect(
+        double.parse(items[0]),
+        double.parse(items[1]),
+        double.parse(items[2]),
+        double.parse(items[3]),
+      );
+    }
+    return rect;
+  }
+
+  @override
+  String toString() => '$x,$y,$width,$height';
+
+  @override
+  int get hashCode {
+    if (isEmpty) return 0;
+    return x.hashCode ^ y.hashCode ^ width.hashCode ^ height.hashCode;
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is DRect) {
+      if (isEmpty) return other.isEmpty;
+
+      return x == other.x &&
+          y == other.y &&
+          width == other.width &&
+          height == other.height;
+    }
+    return false;
+  }
+
+  bool _containsOffsetInner(double x, double y) {
+    return (x >= this.x && x - width <= this.x) &&
+        (y >= this.y && y - height <= this.y);
+  }
+
+  void copyFrom(DRect other) {
+    _x = other.x;
+    _y = other.y;
+    _width = other.width;
+    _height = other.height;
+  }
+}

+ 72 - 0
lib/interfaces/date_types/size.dart

@@ -0,0 +1,72 @@
+import 'package:fis_common/logger/logger.dart';
+
+class DSize {
+  static final DSize empty =
+      DSize(double.negativeInfinity, double.negativeInfinity);
+
+  late double _width;
+  late double _height;
+
+  bool get isEmpty => width < 0.0;
+
+  double get width => _width;
+  set width(double value) {
+    if (isEmpty) {
+      throw UnsupportedError("Size_CannotModifyEmptySize");
+    }
+    if (value < 0.0) {
+      throw ArgumentError("Size_WidthCannotBeNegative");
+    }
+    _width = value;
+  }
+
+  double get height => _height;
+  set height(double value) {
+    if (isEmpty) {
+      throw UnsupportedError("Size_CannotModifyEmptySize");
+    }
+    if (value < 0.0) {
+      throw ArgumentError("Size_HeightCannotBeNegative");
+    }
+    _height = value;
+  }
+
+  DSize(double width, double height) {
+    if (width < 0.0 || height < 0.0) {
+      logger.e("Size_WidthAndHeightCannotBeNegative($width,$height)");
+      width = height = 0;
+    }
+    _width = width;
+    _height = height;
+  }
+
+  static DSize parse(String source) {
+    DSize size;
+    if (source == "Empty") {
+      size = empty;
+    } else {
+      var items = source.split(',');
+      if (items.length != 2) {
+        throw ArgumentError("$source can not be parsed to DSize");
+      }
+      size = DSize(double.parse(items[0]), double.parse(items[1]));
+    }
+    return size;
+  }
+
+  @override
+  String toString() => '$width,$height';
+
+  @override
+  int get hashCode {
+    if (isEmpty) {
+      return 0;
+    }
+    return width.hashCode ^ height.hashCode;
+  }
+
+  @override
+  bool operator ==(Object other) {
+    return other is DSize && width == other.width && height == other.height;
+  }
+}

+ 1 - 0
lib/interfaces/date_types/skew_transform.dart

@@ -0,0 +1 @@
+class DSkewTransform {}

+ 5 - 0
lib/interfaces/date_types/vector.dart

@@ -0,0 +1,5 @@
+class DVector {
+  double x = 0;
+  double y = 0;
+  DVector(double x, double y);
+}

+ 25 - 0
lib/interfaces/enums/display_mode.dart

@@ -0,0 +1,25 @@
+/// C# enum begin at -1,so if u would like to match value, must calcluate -1
+enum DisplayModeEnum {
+  /// Normal B mode
+  normal,
+
+  /// Up/Down, B holds 1/3, Other hodes 2/3
+  upDown13B,
+
+  /// Up/Down, half, half
+  upDownHalfHalf,
+
+  /// Up/Down, B holds2/3, Other hodes1/3
+  upDown23B,
+
+  /// Left/Right, half, half
+  sideBySideHalfHalf,
+
+  /// Left/Right, B holds2/3, Other hodes1/3
+  sideBySide14BOther,
+
+  /// All Image area are Other image instead of B image
+  fullOther,
+
+  fullTissue,
+}

+ 76 - 0
lib/interfaces/process/layout/configuration.dart

@@ -0,0 +1,76 @@
+import 'package:fis_common/logger/logger.dart';
+import 'package:fis_measure/interfaces/enums/display_mode.dart';
+
+import 'section.dart';
+import 'view_port.dart';
+
+class LayoutConfiguration {
+  static LayoutConfiguration? _instance;
+
+  static LayoutConfiguration get ins {
+    _instance ??= LayoutConfiguration();
+    return _instance!;
+  }
+
+  bool _loaded = false;
+  List<LayoutSection> _layoutSections = [];
+
+  bool get loaded => _loaded;
+
+  LayoutConfiguration();
+
+  void loadData(List<dynamic> data) {
+    for (final item in data) {
+      final Map<String, dynamic> map = item;
+      _layoutSections.add(LayoutSection.fromJson(map));
+    }
+    if (_layoutSections.isEmpty) {
+      throw ArgumentError(
+          "Layout configuration error: LayoutSection not found.");
+    }
+    _loaded = true;
+  }
+
+  LayoutViewPort _matchViewPort(
+    String name,
+    String layoutKey,
+    DisplayModeEnum displayFormat,
+  ) {
+    bool found = false;
+    LayoutViewPort viewPort = LayoutViewPort();
+    List<LayoutSection> sections = [];
+
+    var sectionIdx = _layoutSections.indexWhere((x) => x.key == name);
+    if (sectionIdx > -1) {
+      sections.add(_layoutSections[sectionIdx]);
+    }
+    sections.add(_layoutSections[0]);
+
+    for (final candidate in sections) {
+      final layoutIdx = candidate.layouts.indexWhere((x) => x.key == layoutKey);
+      if (layoutIdx > -1) {
+        final layout = candidate.layouts[layoutIdx];
+        int i = -1;
+        while (++i < layout.viewPorts.length) {
+          if (layout.viewPorts[i].displayFormat == displayFormat) {
+            break;
+          }
+        }
+
+        if (i == layout.viewPorts.length) {
+          i = 0;
+        }
+        viewPort = layout.viewPorts[i];
+        found = true;
+        break;
+      }
+    }
+
+    if (!found) {
+      logger.w(
+          "MatchViewPort failed, ViewPort:$viewPort is used. layout section:$name, layout key:$layoutKey, display format:${displayFormat.name}.");
+    }
+
+    return viewPort;
+  }
+}

+ 34 - 0
lib/interfaces/process/layout/section.dart

@@ -0,0 +1,34 @@
+import 'unit.dart';
+
+class LayoutSection {
+  String _key = '';
+  List<LayoutUnit>? _layouts;
+
+  String get key => _key;
+  List<LayoutUnit> get layouts => _layouts ?? const [];
+
+  LayoutSection();
+
+  factory LayoutSection.fromJson(Map<String, dynamic> map) {
+    final instance = LayoutSection();
+    instance._key = map['n'] ?? '';
+    instance._loadLayoutUnits(map['Layouts']);
+    return instance;
+  }
+
+  void _loadLayoutUnits(dynamic data) {
+    final List<LayoutUnit> arr = [];
+
+    if (data != null && data is List) {
+      final List<dynamic> jArr = data;
+      for (final item in jArr) {
+        arr.add(LayoutUnit.fromJson(item));
+      }
+    }
+    if (arr.isEmpty) {
+      throw ArgumentError(
+          "Layout configuration error: Layout element not found.");
+    }
+    _layouts = arr;
+  }
+}

+ 30 - 0
lib/interfaces/process/layout/unit.dart

@@ -0,0 +1,30 @@
+import 'view_port.dart';
+
+class LayoutUnit {
+  String _key = '';
+  List<LayoutViewPort>? _viewPorts;
+
+  String get key => _key;
+  List<LayoutViewPort> get viewPorts => _viewPorts ?? const [];
+
+  LayoutUnit();
+
+  factory LayoutUnit.fromJson(Map<String, dynamic> map) {
+    final instance = LayoutUnit();
+    instance._key = map['k'] ?? '';
+    instance._loadViewPorts(map['ViewPorts']);
+    return instance;
+  }
+
+  void _loadViewPorts(dynamic data) {
+    final List<LayoutViewPort> arr = [];
+
+    if (data != null && data is List) {
+      final List<dynamic> jArr = data;
+      for (final item in jArr) {
+        arr.add(LayoutViewPort.fromJson(item));
+      }
+    }
+    _viewPorts = arr;
+  }
+}

+ 22 - 0
lib/interfaces/process/layout/view_port.dart

@@ -0,0 +1,22 @@
+import 'package:fis_measure/interfaces/enums/display_mode.dart';
+
+class LayoutViewPort {
+  double left = 0;
+  double right = 0;
+  double top = 0;
+  double bottom = 0;
+  DisplayModeEnum displayFormat = DisplayModeEnum.normal;
+
+  LayoutViewPort();
+
+  factory LayoutViewPort.fromJson(Map<String, dynamic> map) {
+    final instance = LayoutViewPort();
+    instance.bottom = map['b'] ?? double.nan;
+    instance.top = map['t'] ?? 0;
+    instance.left = map['l'] ?? 0;
+    instance.right = map['r'] ?? 0;
+    instance.displayFormat = DisplayModeEnum.values[map['format'] ?? 0];
+
+    return instance;
+  }
+}