1<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7<link rel="import" href="/tracing/base/base.html">
8<script>
9'use strict';
10
11/**
12 * @fileoverview Provides a caching layer for elided text values.
13 */
14tr.exportTo('tr.ui.b', function() {
15  /**
16   * Cache for elided strings.
17   * Moved from the ElidedTitleCache protoype to a "global" for speed
18   * (variable reference is 100x faster).
19   *   key: String we wish to elide.
20   *   value: Another dict whose key is width
21   *     and value is an ElidedStringWidthPair.
22   */
23  var elidedTitleCacheDict = {};
24  var elidedTitleCache = new ElidedTitleCache();
25
26  /**
27   * A cache for elided strings.
28   * @constructor
29   */
30  function ElidedTitleCache() {
31    // TODO(jrg): possibly obsoleted with the elided string cache.
32    // Consider removing.
33    this.textWidthMap = {};
34  }
35
36  ElidedTitleCache.prototype = {
37    /**
38     * Return elided text.
39     *
40     * @param {ctx} Context The graphics context.
41     * @param {pixWidth} Pixel width.
42     * @param {title} Original title text.
43     * @param {width} Drawn width in world coords.
44     * @param {sliceDuration} Where the title must fit (in world coords).
45     * @return {ElidedStringWidthPair} Elided string and width.
46     */
47    get: function(ctx, pixWidth, title, width, sliceDuration) {
48      var elidedDict = elidedTitleCacheDict[title];
49      if (!elidedDict) {
50        elidedDict = {};
51        elidedTitleCacheDict[title] = elidedDict;
52      }
53
54      var elidedDictForPixWidth = elidedDict[pixWidth];
55      if (!elidedDictForPixWidth) {
56        elidedDict[pixWidth] = {};
57        elidedDictForPixWidth = elidedDict[pixWidth];
58      }
59
60      var stringWidthPair = elidedDictForPixWidth[sliceDuration];
61      if (stringWidthPair === undefined) {
62        var newtitle = title;
63        var elided = false;
64        while (this.labelWidthWorld(ctx, newtitle, pixWidth) > sliceDuration) {
65          if (newtitle.length * 0.75 < 1)
66            break;
67          newtitle = newtitle.substring(0, newtitle.length * 0.75);
68          elided = true;
69        }
70
71        if (elided && newtitle.length > 3)
72          newtitle = newtitle.substring(0, newtitle.length - 3) + '...';
73
74        stringWidthPair = new ElidedStringWidthPair(
75            newtitle, this.labelWidth(ctx, newtitle));
76        elidedDictForPixWidth[sliceDuration] = stringWidthPair;
77      }
78      return stringWidthPair;
79    },
80
81    quickMeasureText_: function(ctx, text) {
82      var w = this.textWidthMap[text];
83      if (!w) {
84        w = ctx.measureText(text).width;
85        this.textWidthMap[text] = w;
86      }
87      return w;
88    },
89
90    labelWidth: function(ctx, title) {
91      return this.quickMeasureText_(ctx, title) + 2;
92    },
93
94    labelWidthWorld: function(ctx, title, pixWidth) {
95      return this.labelWidth(ctx, title) * pixWidth;
96    }
97  };
98
99  /**
100   * A pair representing an elided string and world-coordinate width
101   * to draw it.
102   * @constructor
103   */
104  function ElidedStringWidthPair(string, width) {
105    this.string = string;
106    this.width = width;
107  }
108
109  return {
110    ElidedTitleCache: ElidedTitleCache
111  };
112});
113</script>
114