public static float ScaleFactorCalc(float referenceScreenWidth, float referenceScreenHeight,
                                        float currentWidth, float currentHeight,
                                        SVGScalerMatchMode matchMode, float match, float offsetScale)
    {
        SVGScaler scaler = new SVGScaler(referenceScreenWidth, referenceScreenHeight, matchMode, match, offsetScale);

        return(scaler.ScaleFactorCalc(currentWidth, currentHeight));
    }
    private bool DrawInspector(SVGAtlas atlas)
    {
        Rect  scollRect;
        float match   = atlas.Match;
        bool  isDirty = false;
        // get current event
        Event currentEvent = Event.current;
        // show current options
        int refWidth                 = EditorGUILayout.IntField(new GUIContent("Reference width", "The resolution the SVG files content is designed for. If the screen resolution is larger, SVG contents will be scaled up, and if it’s smaller, it will be scaled down."), atlas.ReferenceWidth);
        int refHeight                = EditorGUILayout.IntField(new GUIContent("Reference height", "The resolution the SVG files content is designed for. If the screen resolution is larger, SVG contents will be scaled up, and if it’s smaller, it will be scaled down."), atlas.ReferenceHeight);
        int deviceTestWidth          = EditorGUILayout.IntField("Device test width", atlas.DeviceTestWidth);
        int deviceTestHeight         = EditorGUILayout.IntField("Device test height", atlas.DeviceTestHeight);
        SVGScalerMatchMode scaleType = (SVGScalerMatchMode)EditorGUILayout.EnumPopup(new GUIContent("Screen match mode", "A mode used to scale (i.e. generate) SVG sprites if the aspect ratio of the current resolution doesn’t fit the reference resolution."), atlas.ScaleType);

        if (scaleType == SVGScalerMatchMode.MatchWidthOrHeight)
        {
            Rect r = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + 12);
            match = this.MatchSlider(r, atlas.Match);
        }
        float offsetScale          = EditorGUILayout.FloatField(this.m_OffsetScaleContent, atlas.OffsetScale);
        bool  pow2Textures         = EditorGUILayout.Toggle(this.m_Pow2TexturesContent, atlas.Pow2Textures);
        int   maxTexturesDimension = EditorGUILayout.IntField(this.m_MaxTexturesDimensionContent, atlas.MaxTexturesDimension);
        int   border             = EditorGUILayout.IntField(this.m_SpritesPaddingContent, atlas.SpritesBorder);
        Color clearColor         = EditorGUILayout.ColorField(this.m_ClearColorContent, atlas.ClearColor);
        bool  fastUpload         = EditorGUILayout.Toggle(this.m_FastUploadContent, atlas.FastUpload);
        float spritesPreviewSize = (float)EditorGUILayout.IntField(this.m_SpritesPreviewSizeContent, (int)atlas.SpritesPreviewSize);

        // output folder
        this.OutputFolderDraw(atlas);

        // draw the list of input SVG files / assets
        isDirty |= this.SvgInputAssetsDraw(atlas, currentEvent, out scollRect);

        // update button
        if (this.UpdateButtonDraw(atlas))
        {
            // regenerate/update sprites
            atlas.UpdateEditorSprites(true);
            isDirty = true;
        }
        GUILayout.Space(10);

        if (atlas.SvgAssetsCount() > 0)
        {
            // list of sprites, grouped by SVG document
            Vector2 spritesScrollPos = EditorGUILayout.BeginScrollView(this.m_SvgSpritesScrollPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            bool separatorNeeded = false;
            for (int i = 0; i < atlas.SvgAssetsCount(); ++i)
            {
                SVGAssetInput             svgAsset      = atlas.SvgAsset(i);
                List <SVGSpriteAssetFile> spritesAssets = atlas.GetGeneratedSpritesByDocument(svgAsset.TxtAsset);
                if (spritesAssets != null && spritesAssets.Count > 0)
                {
                    // line separator
                    if (separatorNeeded)
                    {
                        EditorGUILayout.Separator();
                        GUILayout.Box(GUIContent.none, this.m_GreyLine, GUILayout.ExpandWidth(true), GUILayout.Height(1));
                        EditorGUILayout.Separator();
                    }
                    // display sprites list
                    foreach (SVGSpriteAssetFile spriteAsset in spritesAssets)
                    {
                        this.SpritePreview(atlas, spriteAsset);
                    }
                    // we have displayed some sprites, next time a line separator is needed
                    separatorNeeded = true;
                }
            }
            EditorGUILayout.EndScrollView();

            if (this.m_SvgSpritesScrollPos != spritesScrollPos)
            {
                this.m_SvgSpritesScrollPos = spritesScrollPos;
            }
        }

        // events handler
        isDirty |= this.HandleDragEvents(atlas, currentEvent, scollRect);

        // negative values are not allowed for reference resolution
        refWidth         = (refWidth <= 0) ? Screen.currentResolution.width : refWidth;
        refHeight        = (refHeight <= 0) ? Screen.currentResolution.height : refHeight;
        deviceTestWidth  = (deviceTestWidth <= 0) ? refWidth : deviceTestWidth;
        deviceTestHeight = (deviceTestHeight <= 0) ? refHeight : deviceTestHeight;
        // a negative value is not allowed for texture max dimension
        maxTexturesDimension = (maxTexturesDimension < 0) ? 1024 : maxTexturesDimension;
        // a negative value is not allowed for border
        border = (border < 0) ? 0 : border;

        // if reference resolution has been changed, update it
        if (atlas.ReferenceWidth != refWidth)
        {
            atlas.ReferenceWidth = refWidth;
            isDirty = true;
        }
        if (atlas.ReferenceHeight != refHeight)
        {
            atlas.ReferenceHeight = refHeight;
            isDirty = true;
        }
        // if device (test) resolution has been changed, update it
        if (atlas.DeviceTestWidth != deviceTestWidth)
        {
            atlas.DeviceTestWidth = deviceTestWidth;
            isDirty = true;
        }
        if (atlas.DeviceTestHeight != deviceTestHeight)
        {
            atlas.DeviceTestHeight = deviceTestHeight;
            isDirty = true;
        }
        // if scale adaption method has been changed, update it
        if (atlas.ScaleType != scaleType)
        {
            atlas.ScaleType = scaleType;
            isDirty         = true;
        }
        if (atlas.Match != match)
        {
            atlas.Match = match;
            isDirty     = true;
        }
        // if offset additional scale has been changed, update it
        if (atlas.OffsetScale != offsetScale)
        {
            atlas.OffsetScale = Math.Abs(offsetScale);
            isDirty           = true;
        }
        // if power-of-two forcing flag has been changed, update it
        if (atlas.Pow2Textures != pow2Textures)
        {
            atlas.Pow2Textures = pow2Textures;
            isDirty            = true;
        }
        // if desired maximum texture dimension has been changed, update it
        if (atlas.MaxTexturesDimension != maxTexturesDimension)
        {
            atlas.MaxTexturesDimension = maxTexturesDimension;
            isDirty = true;
        }
        // if border between each packed SVG has been changed, update it
        if (atlas.SpritesBorder != border)
        {
            atlas.SpritesBorder = border;
            isDirty             = true;
        }
        // if surface clear color has been changed, update it
        if (atlas.ClearColor != clearColor)
        {
            atlas.ClearColor = clearColor;
            isDirty          = true;
        }
        // if "fast upload" flag has been changed, update it
        if (atlas.FastUpload != fastUpload)
        {
            atlas.FastUpload = fastUpload;
            isDirty          = true;
        }
        // if sprites preview size has been changed, update it
        if (atlas.SpritesPreviewSize != spritesPreviewSize)
        {
            atlas.SpritesPreviewSize = spritesPreviewSize;
            isDirty = true;
        }

        return(isDirty);
    }