From eaef718c089518f5a3ba874b4770edbcd77cf20e Mon Sep 17 00:00:00 2001 From: qeesung <1245712564@qq.com> Date: Wed, 7 Nov 2018 00:37:28 +0800 Subject: [PATCH] Fixed the high cyclomatic complexity issue --- convert/resize.go | 135 +++++++++++++++++++++++++++-------------- convert/resize_test.go | 2 + 2 files changed, 91 insertions(+), 46 deletions(-) diff --git a/convert/resize.go b/convert/resize.go index 3b8e8cb..30bd303 100644 --- a/convert/resize.go +++ b/convert/resize.go @@ -9,9 +9,76 @@ import ( // NewResizeHandler create a new resize handler func NewResizeHandler() ResizeHandler { - return &ImageResizeHandler{ + handler := &ImageResizeHandler{ terminal: terminal.NewTerminalAccessor(), } + + initResizeResolver(handler) + return handler +} + +// initResizeResolver register the size resolvers +func initResizeResolver(handler *ImageResizeHandler) { + sizeResolvers := make([]imageSizeResolver, 0, 5) + // fixed height or width resolver + sizeResolvers = append(sizeResolvers, imageSizeResolver{ + match: func(options *Options) bool { + return options.FixedWidth != -1 || options.FixedHeight != -1 + }, + compute: func(sz image.Rectangle, options *Options, handler *ImageResizeHandler) (width, height int, err error) { + height = sz.Max.Y + width = sz.Max.X + if options.FixedWidth != -1 { + width = options.FixedWidth + } + + if options.FixedHeight != -1 { + height = options.FixedHeight + } + return + }, + }) + // scaled by ratio + sizeResolvers = append(sizeResolvers, imageSizeResolver{ + match: func(options *Options) bool { + return options.Ratio != 1 + }, + compute: func(sz image.Rectangle, options *Options, handler *ImageResizeHandler) (width, height int, err error) { + ratio := options.Ratio + width = handler.ScaleWidthByRatio(float64(sz.Max.X), ratio) + height = handler.ScaleHeightByRatio(float64(sz.Max.Y), ratio) + return + }, + }) + // scaled by stretched screen + sizeResolvers = append(sizeResolvers, imageSizeResolver{ + match: func(options *Options) bool { + return options.StretchedScreen + }, + compute: func(sz image.Rectangle, options *Options, handler *ImageResizeHandler) (width, height int, err error) { + return handler.terminal.ScreenSize() + }, + }) + // scaled by fit the screen + sizeResolvers = append(sizeResolvers, imageSizeResolver{ + match: func(options *Options) bool { + return options.FitScreen + }, + compute: func(sz image.Rectangle, options *Options, handler *ImageResizeHandler) (width, height int, err error) { + return handler.CalcProportionalFittingScreenSize(sz) + }, + }) + // default size + sizeResolvers = append(sizeResolvers, imageSizeResolver{ + match: func(options *Options) bool { + return true + }, + compute: func(sz image.Rectangle, options *Options, handler *ImageResizeHandler) (width, height int, err error) { + return sz.Max.X, sz.Max.Y, nil + }, + }) + + handler.imageSizeResolvers = sizeResolvers } // ResizeHandler define the operation to resize a image @@ -22,69 +89,45 @@ type ResizeHandler interface { // ImageResizeHandler implement the ResizeHandler interface and // responsible for image resizing type ImageResizeHandler struct { - terminal terminal.Terminal + terminal terminal.Terminal + imageSizeResolvers []imageSizeResolver +} + +// imageSizeResolver to resolve the image size from the options +type imageSizeResolver struct { + match func(options *Options) bool + compute func(sz image.Rectangle, options *Options, handler *ImageResizeHandler) (width, height int, err error) } // ScaleImage resize the convert to expected size base on the convert options func (handler *ImageResizeHandler) ScaleImage(image image.Image, options *Options) (newImage image.Image) { sz := image.Bounds() - ratio := options.Ratio - newHeight := sz.Max.Y - newWidth := sz.Max.X - - if options.FixedWidth != -1 { - newWidth = options.FixedWidth - } - - if options.FixedHeight != -1 { - newHeight = options.FixedHeight - } - - // use the ratio the scale the image - if options.FixedHeight == -1 && options.FixedWidth == -1 && ratio != 1 { - newWidth = handler.ScaleWidthByRatio(float64(sz.Max.X), ratio) - newHeight = handler.ScaleHeightByRatio(float64(sz.Max.Y), ratio) + newWidth, newHeight, err := handler.resolveSize(sz, options) + if err != nil { + log.Fatal(err) } - //Stretch the picture to overspread the terminal - if ratio == 1 && - options.FixedWidth == -1 && - options.FixedHeight == -1 && - options.StretchedScreen { - screenWidth, screenHeight, err := handler.terminal.ScreenSize() - if err != nil { - log.Fatal(err) - } - newWidth = int(screenWidth) - newHeight = int(screenHeight) - } + newImage = resize.Resize(uint(newWidth), uint(newHeight), image, resize.Lanczos3) + return +} - // fit the screen - if ratio == 1 && - options.FixedWidth == -1 && - options.FixedHeight == -1 && - options.FitScreen && - !options.StretchedScreen { - fitWidth, fitHeight, err := handler.CalcProportionalFittingScreenSize(image) - if err != nil { - log.Fatal(err) +// resolveSize resolve the image size +func (handler *ImageResizeHandler) resolveSize(sz image.Rectangle, options *Options) (width, height int, err error) { + for _, resolver := range handler.imageSizeResolvers { + if resolver.match(options) { + return resolver.compute(sz, options, handler) } - newWidth = int(fitWidth) - newHeight = int(fitHeight) } - - newImage = resize.Resize(uint(newWidth), uint(newHeight), image, resize.Lanczos3) - return + return sz.Max.X, sz.Max.Y, nil } // CalcProportionalFittingScreenSize proportional scale the image // so that the terminal can just show the picture. -func (handler *ImageResizeHandler) CalcProportionalFittingScreenSize(image image.Image) (newWidth, newHeight int, err error) { +func (handler *ImageResizeHandler) CalcProportionalFittingScreenSize(sz image.Rectangle) (newWidth, newHeight int, err error) { screenWidth, screenHeight, err := handler.terminal.ScreenSize() if err != nil { log.Fatal(nil) } - sz := image.Bounds() newWidth, newHeight = handler.CalcFitSize( float64(screenWidth), float64(screenHeight), diff --git a/convert/resize_test.go b/convert/resize_test.go index 39055e0..49d2808 100644 --- a/convert/resize_test.go +++ b/convert/resize_test.go @@ -136,6 +136,7 @@ func TestFitTheTerminalScreenSize(t *testing.T) { handler := ImageResizeHandler{ terminal: &terminalMock, } + initResizeResolver(&handler) imageFilePath := "testdata/cat_2000x1500.jpg" img, err := OpenImageFile(imageFilePath) @@ -169,6 +170,7 @@ func TestStretchTheTerminalScreenSize(t *testing.T) { handler := ImageResizeHandler{ terminal: &terminalMock, } + initResizeResolver(&handler) imageFilePath := "testdata/cat_2000x1500.jpg" img, err := OpenImageFile(imageFilePath) -- 2.45.2