1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { RectF } from '../base/Rect';
17import { MathUtils } from './MathUtils';
18
19export abstract class DrawingUtils {
20  private static readonly DEFAULT_LINE_WIDTH: number = 0.5;
21  private static readonly DEFAULT_BUTTON_WIDTH: number = 3;
22  private static readonly DEFAULT_BUTTON_PADDING: number = 1;
23  private static readonly DEFAULT_BUTTON_LENGTH: number = 20;
24  private static readonly DEFAULT_LINE_COLOR: string = '#80FFFFFF';
25  private static readonly DEFAULT_BUTTON_COLOR: string = 'white';
26  private static readonly DEFAULT_MASK_STYLE: string = 'rgba(0, 0, 0, 0.3)';
27
28  static drawMask(ctx: CanvasRenderingContext2D, outer: RectF, inner: RectF) {
29    ctx.fillStyle = DrawingUtils.DEFAULT_MASK_STYLE;
30    ctx.fillRect(outer.left, outer.top, outer.getWidth(), inner.top - outer.top);
31    ctx.fillRect(outer.left, inner.top, inner.left - outer.left, inner.getHeight());
32    ctx.fillRect(inner.right, inner.top, outer.right - inner.right, inner.getHeight());
33    ctx.fillRect(outer.left, inner.bottom, outer.getWidth(), outer.bottom - inner.bottom);
34  }
35
36  static drawCropButton(ctx: CanvasRenderingContext2D, crop: RectF) {
37    let vp3 = DrawingUtils.DEFAULT_BUTTON_WIDTH;
38    let padding = DrawingUtils.DEFAULT_BUTTON_PADDING;
39    ctx.lineWidth = vp3;
40    ctx.strokeStyle = DrawingUtils.DEFAULT_BUTTON_COLOR;
41    let cornerLength = DrawingUtils.DEFAULT_BUTTON_LENGTH;
42    DrawingUtils.drawCornerButton(ctx, crop, vp3, padding, cornerLength);
43    DrawingUtils.drawLineButton(ctx, crop, vp3, padding, cornerLength);
44  }
45
46  static drawRect(ctx: CanvasRenderingContext2D, crop: RectF) {
47    ctx.lineWidth = DrawingUtils.DEFAULT_LINE_WIDTH;
48    ctx.strokeStyle = DrawingUtils.DEFAULT_LINE_COLOR;
49    let points = MathUtils.rectToPoints(crop);
50    for (let i = 0; i < points.length; i++) {
51      let j = (i + 1) % points.length;
52      DrawingUtils.drawLine(ctx, points[i].x, points[i].y, points[j].x, points[j].y);
53    }
54  }
55
56  static drawSplitLine(ctx: CanvasRenderingContext2D, crop: RectF, split) {
57    ctx.lineWidth = DrawingUtils.DEFAULT_LINE_WIDTH;
58    ctx.strokeStyle = DrawingUtils.DEFAULT_LINE_COLOR;
59    let w = Math.ceil(crop.getWidth() / split);
60    let h = Math.ceil(crop.getHeight() / split);
61    for (let i = 1; i < split; i++) {
62      let x = crop.left + w * i;
63      let y = crop.top + h * i;
64      DrawingUtils.drawLine(ctx, x, crop.top, x, crop.bottom);
65      DrawingUtils.drawLine(ctx, crop.left, y, crop.right, y);
66    }
67  }
68
69  static drawLine(ctx: CanvasRenderingContext2D, srcX: number, srcY: number, dstX: number, dstY: number) {
70    ctx.beginPath();
71    ctx.moveTo(srcX, srcY);
72    ctx.lineTo(dstX, dstY);
73    ctx.stroke();
74  }
75
76  private static drawCornerButton(ctx: CanvasRenderingContext2D, crop: RectF,
77                                  vp3: number, padding: number, cornerLength: number) {
78    // left top conner button
79    let startX = crop.left - vp3 - padding;
80    let startY = crop.top - vp3;
81    let stopX = startX + cornerLength;
82    let stopY = startY;
83    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
84    startX = crop.left - vp3;
85    startY = crop.top - vp3 - padding;
86    stopX = startX;
87    stopY = startY + cornerLength;
88    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
89
90    // right top conner button
91    startX = crop.right + vp3 + padding;
92    startY = crop.top - vp3;
93    stopX = startX - cornerLength;
94    stopY = startY;
95    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
96    startX = crop.right + vp3;
97    startY = crop.top - vp3 - padding;
98    stopX = startX;
99    stopY = startY + cornerLength;
100    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
101
102    // left bottom conner button
103    startX = crop.left - vp3;
104    startY = crop.bottom + vp3 + padding;
105    stopX = startX;
106    stopY = startY - cornerLength;
107    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
108    startX = crop.left - vp3 - padding;
109    startY = crop.bottom + vp3;
110    stopX = startX + cornerLength;
111    stopY = startY;
112    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
113
114    // right bottom conner button
115    startX = crop.right + vp3 + padding;
116    startY = crop.bottom + vp3;
117    stopX = startX - cornerLength;
118    stopY = startY;
119    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
120    startX = crop.right + vp3;
121    startY = crop.bottom + vp3 + padding;
122    stopX = startX;
123    stopY = startY - cornerLength;
124    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
125  }
126
127  private static drawLineButton(ctx: CanvasRenderingContext2D, crop: RectF,
128                                vp3: number, padding: number, cornerLength: number) {
129    // top button
130    let startX = crop.getCenterX() - cornerLength / 2;
131    let startY = crop.top - vp3;
132    let stopX = startX + cornerLength;
133    let stopY = startY;
134    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
135
136    // bottom button
137    startX = crop.getCenterX() - cornerLength / 2;
138    startY = crop.bottom + vp3;
139    stopX = startX + cornerLength;
140    stopY = startY;
141    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
142
143    // left button
144    startX = crop.left - vp3;
145    startY = crop.getCenterY() - cornerLength / 2;
146    stopX = startX;
147    stopY = startY + cornerLength;
148    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
149
150    // right button
151    startX = crop.right + vp3;
152    startY = crop.getCenterY() - cornerLength / 2;
153    stopX = startX;
154    stopY = startY + cornerLength;
155    DrawingUtils.drawLine(ctx, startX, startY, stopX, stopY);
156  }
157}