hunk.code_window:                                                        @"iPhone11,4", // iPhoneXsMax
                                                          @"iPhone11,8", // iPhoneXr
  
hunk.labels: add keep
hunk.after_edit:                                                        @"iPhone11,6", // iPhoneXsMax
  
hunk.file_path: ios/Exponent/Versioned/Core/Api/EXScreenOrientation.m
hunk.type: add
file: /*
   * Copyright (c) 2015-present, Horcrux.
   * All rights reserved.
   *
   * This source code is licensed under the MIT-style license found in the
   * LICENSE file in the root directory of this source tree.
   */
  
  
  package abi36_0_0.host.exp.exponent.modules.api.components.svg;
  
  import android.graphics.Matrix;
  import android.graphics.Path;
  import android.graphics.PathMeasure;
  import android.graphics.RectF;
  import android.graphics.Region;
  
  import abi36_0_0.com.facebook.react.bridge.Arguments;
  import abi36_0_0.com.facebook.react.bridge.ReactApplicationContext;
  import abi36_0_0.com.facebook.react.bridge.ReactContextBaseJavaModule;
  import abi36_0_0.com.facebook.react.bridge.ReactMethod;
  import abi36_0_0.com.facebook.react.bridge.ReadableMap;
  import abi36_0_0.com.facebook.react.bridge.WritableMap;
  
  import javax.annotation.Nonnull;
  
  class RNSVGRenderableManager extends ReactContextBaseJavaModule {
      RNSVGRenderableManager(ReactApplicationContext reactContext) {
          super(reactContext);
      }
  
      @Nonnull
      @Override
      public String getName() {
          return "RNSVGRenderableManager";
      }
  
      @SuppressWarnings("unused")
      @ReactMethod(isBlockingSynchronousMethod = true)
      public boolean isPointInFill(int tag, ReadableMap options) {
          RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
          if (svg == null) {
              return false;
          }
  
          float scale = svg.mScale;
          float x = (float) options.getDouble("x") * scale;
          float y = (float) options.getDouble("y") * scale;
  
          int i = svg.hitTest(new float[]{x, y});
          return i != -1;
      }
  
      @SuppressWarnings("unused")
      @ReactMethod(isBlockingSynchronousMethod = true)
      public boolean isPointInStroke(int tag, ReadableMap options) {
          RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
          if (svg == null) {
              return false;
          }
  
          svg.getPath(null, null);
          svg.initBounds();
  
          float scale = svg.mScale;
          int x = (int) (options.getDouble("x") * scale);
          int y = (int) (options.getDouble("y") * scale);
  
          Region strokeRegion = svg.mStrokeRegion;
          return strokeRegion != null && strokeRegion.contains(x, y);
      }
  
      @SuppressWarnings("unused")
      @ReactMethod(isBlockingSynchronousMethod = true)
      public float getTotalLength(int tag) {
          RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
          if (svg == null) {
              return 0;
          }
  
          Path path = svg.getPath(null, null);
          PathMeasure pm = new PathMeasure(path, false);
          return pm.getLength() / svg.mScale;
      }
  
      @SuppressWarnings("unused")
      @ReactMethod(isBlockingSynchronousMethod = true)
      public WritableMap getPointAtLength(int tag, ReadableMap options) {
          RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
          if (svg == null) {
              return null;
          }
  
          Path path = svg.getPath(null, null);
          PathMeasure pm = new PathMeasure(path, false);
          float length = (float) options.getDouble("length");
          float scale = svg.mScale;
  
          float[] pos = new float[2];
          float[] tan = new float[2];
          float distance = Math.max(0, Math.min(length, pm.getLength()));
          pm.getPosTan(distance, pos, tan);
  
          double angle = Math.atan2(tan[1], tan[0]);
          WritableMap result = Arguments.createMap();
          result.putDouble("x", pos[0] / scale);
          result.putDouble("y", pos[1] / scale);
          result.putDouble("angle", angle);
          return result;
      }
  
      @SuppressWarnings("unused")
      @ReactMethod(isBlockingSynchronousMethod = true)
      public WritableMap getBBox(int tag, ReadableMap options) {
          RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
          if (svg == null) {
              return null;
          }
  
          boolean fill = options.getBoolean("fill");
          boolean stroke = options.getBoolean("stroke");
          boolean markers = options.getBoolean("markers");
          boolean clipped = options.getBoolean("clipped");
  
          Path path = svg.getPath(null, null);
          float scale = svg.mScale;
          svg.initBounds();
  
          RectF bounds = new RectF();
          if (fill) {
              bounds.union(svg.mFillBounds);
          }
          if (stroke) {
              bounds.union(svg.mStrokeBounds);
          }
          if (markers) {
              bounds.union(svg.mMarkerBounds);
          }
          if (clipped) {
              RectF clipBounds = svg.mClipBounds;
              if (clipBounds != null) {
                  bounds.intersect(svg.mClipBounds);
              }
          }
  
          WritableMap result = Arguments.createMap();
          result.putDouble("x", bounds.left / scale);
          result.putDouble("y", bounds.top / scale);
          result.putDouble("width", bounds.width() / scale);
          result.putDouble("height", bounds.height() / scale);
          return result;
      }
  
      @SuppressWarnings("unused")
      @ReactMethod(isBlockingSynchronousMethod = true)
      public WritableMap getCTM(int tag) {
          RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
          if (svg == null) {
              return null;
          }
  
          float scale = svg.mScale;
          Matrix ctm = new Matrix(svg.mCTM);
          Matrix invViewBoxMatrix = svg.getSvgView().mInvViewBoxMatrix;
          ctm.preConcat(invViewBoxMatrix);
  
          float[] values = new float[9];
          ctm.getValues(values);
  
          WritableMap result = Arguments.createMap();
          result.putDouble("a", values[Matrix.MSCALE_X]);
          result.putDouble("b", values[Matrix.MSKEW_Y]);
          result.putDouble("c", values[Matrix.MSKEW_X]);
          result.putDouble("d", values[Matrix.MSCALE_Y]);
          result.putDouble("e", values[Matrix.MTRANS_X] / scale);
          result.putDouble("f", values[Matrix.MTRANS_Y] / scale);
          return result;
      }
  
      @SuppressWarnings("unused")
      @ReactMethod(isBlockingSynchronousMethod = true)
      public WritableMap getScreenCTM(int tag) {
          RenderableView svg = RenderableViewManager.getRenderableViewByTag(tag);
          if (svg == null) {
              return null;
          }
  
          float[] values = new float[9];
          svg.mCTM.getValues(values);
          float scale = svg.mScale;
  
          WritableMap result = Arguments.createMap();
          result.putDouble("a", values[Matrix.MSCALE_X]);
          result.putDouble("b", values[Matrix.MSKEW_Y]);
          result.putDouble("c", values[Matrix.MSKEW_X]);
          result.putDouble("d", values[Matrix.MSCALE_Y]);
          result.putDouble("e", values[Matrix.MTRANS_X] / scale);
          result.putDouble("f", values[Matrix.MTRANS_Y] / scale);
          return result;
      }
  }
  