1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.gallery3d.filtershow.crop;
18 
19 import android.graphics.Canvas;
20 import android.graphics.Color;
21 import android.graphics.Matrix;
22 import android.graphics.Paint;
23 import android.graphics.Path;
24 import android.graphics.RectF;
25 import android.graphics.Region;
26 import android.graphics.drawable.Drawable;
27 
28 public abstract class CropDrawingUtils {
29 
drawRuleOfThird(Canvas canvas, RectF bounds)30     public static void drawRuleOfThird(Canvas canvas, RectF bounds) {
31         Paint p = new Paint();
32         p.setStyle(Paint.Style.STROKE);
33         p.setColor(Color.argb(128, 255, 255, 255));
34         p.setStrokeWidth(2);
35         float stepX = bounds.width() / 3.0f;
36         float stepY = bounds.height() / 3.0f;
37         float x = bounds.left + stepX;
38         float y = bounds.top + stepY;
39         for (int i = 0; i < 2; i++) {
40             canvas.drawLine(x, bounds.top, x, bounds.bottom, p);
41             x += stepX;
42         }
43         for (int j = 0; j < 2; j++) {
44             canvas.drawLine(bounds.left, y, bounds.right, y, p);
45             y += stepY;
46         }
47     }
48 
drawCropRect(Canvas canvas, RectF bounds)49     public static void drawCropRect(Canvas canvas, RectF bounds) {
50         Paint p = new Paint();
51         p.setStyle(Paint.Style.STROKE);
52         p.setColor(Color.WHITE);
53         p.setStrokeWidth(3);
54         canvas.drawRect(bounds, p);
55     }
56 
drawShade(Canvas canvas, RectF bounds)57     public static void drawShade(Canvas canvas, RectF bounds) {
58         int w = canvas.getWidth();
59         int h = canvas.getHeight();
60         Paint p = new Paint();
61         p.setStyle(Paint.Style.FILL);
62         p.setColor(Color.BLACK & 0x88000000);
63 
64         RectF r = new RectF();
65         r.set(0,0,w,bounds.top);
66         canvas.drawRect(r, p);
67         r.set(0,bounds.top,bounds.left,h);
68         canvas.drawRect(r, p);
69         r.set(bounds.left,bounds.bottom,w,h);
70         canvas.drawRect(r, p);
71         r.set(bounds.right,bounds.top,w,bounds.bottom);
72         canvas.drawRect(r, p);
73     }
74 
drawIndicator(Canvas canvas, Drawable indicator, int indicatorSize, float centerX, float centerY)75     public static void drawIndicator(Canvas canvas, Drawable indicator, int indicatorSize,
76             float centerX, float centerY) {
77         int left = (int) centerX - indicatorSize / 2;
78         int top = (int) centerY - indicatorSize / 2;
79         indicator.setBounds(left, top, left + indicatorSize, top + indicatorSize);
80         indicator.draw(canvas);
81     }
82 
drawIndicators(Canvas canvas, Drawable cropIndicator, int indicatorSize, RectF bounds, boolean fixedAspect, int selection)83     public static void drawIndicators(Canvas canvas, Drawable cropIndicator, int indicatorSize,
84             RectF bounds, boolean fixedAspect, int selection) {
85         boolean notMoving = (selection == CropObject.MOVE_NONE);
86         if (fixedAspect) {
87             if ((selection == CropObject.TOP_LEFT) || notMoving) {
88                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.left, bounds.top);
89             }
90             if ((selection == CropObject.TOP_RIGHT) || notMoving) {
91                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.right, bounds.top);
92             }
93             if ((selection == CropObject.BOTTOM_LEFT) || notMoving) {
94                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.left, bounds.bottom);
95             }
96             if ((selection == CropObject.BOTTOM_RIGHT) || notMoving) {
97                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.right, bounds.bottom);
98             }
99         } else {
100             if (((selection & CropObject.MOVE_TOP) != 0) || notMoving) {
101                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.centerX(), bounds.top);
102             }
103             if (((selection & CropObject.MOVE_BOTTOM) != 0) || notMoving) {
104                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.centerX(), bounds.bottom);
105             }
106             if (((selection & CropObject.MOVE_LEFT) != 0) || notMoving) {
107                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.left, bounds.centerY());
108             }
109             if (((selection & CropObject.MOVE_RIGHT) != 0) || notMoving) {
110                 drawIndicator(canvas, cropIndicator, indicatorSize, bounds.right, bounds.centerY());
111             }
112         }
113     }
114 
drawWallpaperSelectionFrame(Canvas canvas, RectF cropBounds, float spotX, float spotY, Paint p, Paint shadowPaint)115     public static void drawWallpaperSelectionFrame(Canvas canvas, RectF cropBounds, float spotX,
116             float spotY, Paint p, Paint shadowPaint) {
117         float sx = cropBounds.width() * spotX;
118         float sy = cropBounds.height() * spotY;
119         float cx = cropBounds.centerX();
120         float cy = cropBounds.centerY();
121         RectF r1 = new RectF(cx - sx / 2, cy - sy / 2, cx + sx / 2, cy + sy / 2);
122         float temp = sx;
123         sx = sy;
124         sy = temp;
125         RectF r2 = new RectF(cx - sx / 2, cy - sy / 2, cx + sx / 2, cy + sy / 2);
126         canvas.save();
127         canvas.clipRect(cropBounds);
128         canvas.clipRect(r1, Region.Op.DIFFERENCE);
129         canvas.clipRect(r2, Region.Op.DIFFERENCE);
130         canvas.drawPaint(shadowPaint);
131         canvas.restore();
132         Path path = new Path();
133         path.moveTo(r1.left, r1.top);
134         path.lineTo(r1.right, r1.top);
135         path.moveTo(r1.left, r1.top);
136         path.lineTo(r1.left, r1.bottom);
137         path.moveTo(r1.left, r1.bottom);
138         path.lineTo(r1.right, r1.bottom);
139         path.moveTo(r1.right, r1.top);
140         path.lineTo(r1.right, r1.bottom);
141         path.moveTo(r2.left, r2.top);
142         path.lineTo(r2.right, r2.top);
143         path.moveTo(r2.right, r2.top);
144         path.lineTo(r2.right, r2.bottom);
145         path.moveTo(r2.left, r2.bottom);
146         path.lineTo(r2.right, r2.bottom);
147         path.moveTo(r2.left, r2.top);
148         path.lineTo(r2.left, r2.bottom);
149         canvas.drawPath(path, p);
150     }
151 
drawShadows(Canvas canvas, Paint p, RectF innerBounds, RectF outerBounds)152     public static void drawShadows(Canvas canvas, Paint p, RectF innerBounds, RectF outerBounds) {
153         canvas.drawRect(outerBounds.left, outerBounds.top, innerBounds.right, innerBounds.top, p);
154         canvas.drawRect(innerBounds.right, outerBounds.top, outerBounds.right, innerBounds.bottom,
155                 p);
156         canvas.drawRect(innerBounds.left, innerBounds.bottom, outerBounds.right,
157                 outerBounds.bottom, p);
158         canvas.drawRect(outerBounds.left, innerBounds.top, innerBounds.left, outerBounds.bottom, p);
159     }
160 
getBitmapToDisplayMatrix(RectF imageBounds, RectF displayBounds)161     public static Matrix getBitmapToDisplayMatrix(RectF imageBounds, RectF displayBounds) {
162         Matrix m = new Matrix();
163         CropDrawingUtils.setBitmapToDisplayMatrix(m, imageBounds, displayBounds);
164         return m;
165     }
166 
setBitmapToDisplayMatrix(Matrix m, RectF imageBounds, RectF displayBounds)167     public static boolean setBitmapToDisplayMatrix(Matrix m, RectF imageBounds,
168             RectF displayBounds) {
169         m.reset();
170         return m.setRectToRect(imageBounds, displayBounds, Matrix.ScaleToFit.CENTER);
171     }
172 
setImageToScreenMatrix(Matrix dst, RectF image, RectF screen, int rotation)173     public static boolean setImageToScreenMatrix(Matrix dst, RectF image,
174             RectF screen, int rotation) {
175         RectF rotatedImage = new RectF();
176         dst.setRotate(rotation, image.centerX(), image.centerY());
177         if (!dst.mapRect(rotatedImage, image)) {
178             return false; // fails for rotations that are not multiples of 90
179                           // degrees
180         }
181         boolean rToR = dst.setRectToRect(rotatedImage, screen, Matrix.ScaleToFit.CENTER);
182         boolean rot = dst.preRotate(rotation, image.centerX(), image.centerY());
183         return rToR && rot;
184     }
185 
186 }
187