1// Copyright (C) 2019 The Android Open Source Project
2//
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
15export function cropText(str: string, charWidth: number, rectWidth: number) {
16  let displayText = '';
17  const maxLength = Math.floor(rectWidth / charWidth) - 1;
18  if (str.length <= maxLength) {
19    displayText = str;
20  } else {
21    let limit = maxLength;
22    let maybeTripleDot = '';
23    if (maxLength > 1) {
24      limit = maxLength - 1;
25      maybeTripleDot = '\u2026';
26    }
27    // Javascript strings are UTF-16. |limit| could point in the middle of a
28    // 32-bit double-wchar codepoint (e.g., an emoji). Here we detect if the
29    // |limit|-th wchar is a leading surrogate and attach the trailing one.
30    const lastCharCode = str.charCodeAt(limit - 1);
31    limit += (lastCharCode >= 0xD800 && lastCharCode < 0xDC00) ? 1 : 0;
32    displayText = str.substring(0, limit) + maybeTripleDot;
33  }
34  return displayText;
35}
36
37export function drawDoubleHeadedArrow(
38    ctx: CanvasRenderingContext2D,
39    x: number,
40    y: number,
41    length: number,
42    showArrowHeads: boolean,
43    width = 2,
44    color = 'black') {
45  ctx.beginPath();
46  ctx.lineWidth = width;
47  ctx.lineCap = 'round';
48  ctx.strokeStyle = color;
49  ctx.moveTo(x, y);
50  ctx.lineTo(x + length, y);
51  ctx.stroke();
52  ctx.closePath();
53  // Arrowheads on the each end of the line.
54  if (showArrowHeads) {
55    ctx.beginPath();
56    ctx.moveTo(x + length - 8, y - 4);
57    ctx.lineTo(x + length, y);
58    ctx.lineTo(x + length - 8, y + 4);
59    ctx.stroke();
60    ctx.closePath();
61    ctx.beginPath();
62    ctx.moveTo(x + 8, y - 4);
63    ctx.lineTo(x, y);
64    ctx.lineTo(x + 8, y + 4);
65    ctx.stroke();
66    ctx.closePath();
67  }
68}
69
70export function drawIncompleteSlice(
71    ctx: CanvasRenderingContext2D,
72    x: number,
73    y: number,
74    length: number,
75    width: number,
76    color: string) {
77  ctx.beginPath();
78  ctx.fillStyle = color;
79  const triangleSize = width / 4;
80  ctx.moveTo(x, y);
81  ctx.lineTo(x + length, y);
82  ctx.lineTo(x + length - 3, y + triangleSize * 0.5);
83  ctx.lineTo(x + length, y + triangleSize);
84  ctx.lineTo(x + length - 3, y + (triangleSize * 1.5));
85  ctx.lineTo(x + length, y + 2 * triangleSize);
86  ctx.lineTo(x + length - 3, y + (triangleSize * 2.5));
87  ctx.lineTo(x + length, y + 3 * triangleSize);
88  ctx.lineTo(x + length - 3, y + (triangleSize * 3.5));
89  ctx.lineTo(x + length, y + 4 * triangleSize);
90  ctx.lineTo(x, y + width);
91  ctx.fill();
92}