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}