Start process of better client-side file locations.
[openemr.git] / public / assets / literallycanvas-0-4-13 / js / core / TextRenderer.js
blobdc5af3bdb6b72f2feca0e419bde4a6f2eb9819a4
1 var TextRenderer, getLinesToRender, getNextLine, parseFontString;
3 require('./fontmetrics.js');
5 parseFontString = function(font) {
6   var fontFamily, fontItems, fontSize, item, j, len, maybeSize, remainingFontString;
7   fontItems = font.split(' ');
8   fontSize = 0;
9   for (j = 0, len = fontItems.length; j < len; j++) {
10     item = fontItems[j];
11     maybeSize = parseInt(item.replace("px", ""), 10);
12     if (!isNaN(maybeSize)) {
13       fontSize = maybeSize;
14     }
15   }
16   if (!fontSize) {
17     throw "Font size not found";
18   }
19   remainingFontString = font.substring(fontItems[0].length + 1).replace('bold ', '').replace('italic ', '').replace('underline ', '');
20   fontFamily = remainingFontString;
21   return {
22     fontSize: fontSize,
23     fontFamily: fontFamily
24   };
27 getNextLine = function(ctx, text, forcedWidth) {
28   var doesSubstringFit, endIndex, isEndOfString, isNonWord, isWhitespace, lastGoodIndex, lastOkayIndex, nextWordStartIndex, textToHere, wasInWord;
29   if (!text.length) {
30     return ['', ''];
31   }
32   endIndex = 0;
33   lastGoodIndex = 0;
34   lastOkayIndex = 0;
35   wasInWord = false;
36   while (true) {
37     endIndex += 1;
38     isEndOfString = endIndex >= text.length;
39     isWhitespace = (!isEndOfString) && text[endIndex].match(/\s/);
40     isNonWord = isWhitespace || isEndOfString;
41     textToHere = text.substring(0, endIndex);
42     doesSubstringFit = forcedWidth ? ctx.measureTextWidth(textToHere).width <= forcedWidth : true;
43     if (doesSubstringFit) {
44       lastOkayIndex = endIndex;
45     }
46     if (isNonWord && wasInWord) {
47       wasInWord = false;
48       if (doesSubstringFit) {
49         lastGoodIndex = endIndex;
50       }
51     }
52     wasInWord = !isWhitespace;
53     if (isEndOfString || !doesSubstringFit) {
54       if (doesSubstringFit) {
55         return [text, ''];
56       } else if (lastGoodIndex > 0) {
57         nextWordStartIndex = lastGoodIndex + 1;
58         while (nextWordStartIndex < text.length && text[nextWordStartIndex].match('/\s/')) {
59           nextWordStartIndex += 1;
60         }
61         return [text.substring(0, lastGoodIndex), text.substring(nextWordStartIndex)];
62       } else {
63         return [text.substring(0, lastOkayIndex), text.substring(lastOkayIndex)];
64       }
65     }
66   }
69 getLinesToRender = function(ctx, text, forcedWidth) {
70   var j, len, lines, nextLine, ref, ref1, remainingText, textLine, textSplitOnLines;
71   textSplitOnLines = text.split(/\r\n|\r|\n/g);
72   lines = [];
73   for (j = 0, len = textSplitOnLines.length; j < len; j++) {
74     textLine = textSplitOnLines[j];
75     ref = getNextLine(ctx, textLine, forcedWidth), nextLine = ref[0], remainingText = ref[1];
76     if (nextLine) {
77       while (nextLine) {
78         lines.push(nextLine);
79         ref1 = getNextLine(ctx, remainingText, forcedWidth), nextLine = ref1[0], remainingText = ref1[1];
80       }
81     } else {
82       lines.push(textLine);
83     }
84   }
85   return lines;
88 TextRenderer = (function() {
89   function TextRenderer(ctx, text1, font1, forcedWidth1, forcedHeight) {
90     var fontFamily, fontSize, ref;
91     this.text = text1;
92     this.font = font1;
93     this.forcedWidth = forcedWidth1;
94     this.forcedHeight = forcedHeight;
95     ref = parseFontString(this.font), fontFamily = ref.fontFamily, fontSize = ref.fontSize;
96     ctx.font = this.font;
97     ctx.textBaseline = 'baseline';
98     this.emDashWidth = ctx.measureTextWidth('—', fontSize, fontFamily).width;
99     this.caratWidth = ctx.measureTextWidth('|', fontSize, fontFamily).width;
100     this.lines = getLinesToRender(ctx, this.text, this.forcedWidth);
101     this.metricses = this.lines.map((function(_this) {
102       return function(line) {
103         return ctx.measureText2(line || 'X', fontSize, _this.font);
104       };
105     })(this));
106     this.metrics = {
107       ascent: Math.max.apply(Math, this.metricses.map(function(arg) {
108         var ascent;
109         ascent = arg.ascent;
110         return ascent;
111       })),
112       descent: Math.max.apply(Math, this.metricses.map(function(arg) {
113         var descent;
114         descent = arg.descent;
115         return descent;
116       })),
117       fontsize: Math.max.apply(Math, this.metricses.map(function(arg) {
118         var fontsize;
119         fontsize = arg.fontsize;
120         return fontsize;
121       })),
122       leading: Math.max.apply(Math, this.metricses.map(function(arg) {
123         var leading;
124         leading = arg.leading;
125         return leading;
126       })),
127       width: Math.max.apply(Math, this.metricses.map(function(arg) {
128         var width;
129         width = arg.width;
130         return width;
131       })),
132       height: Math.max.apply(Math, this.metricses.map(function(arg) {
133         var height;
134         height = arg.height;
135         return height;
136       })),
137       bounds: {
138         minx: Math.min.apply(Math, this.metricses.map(function(arg) {
139           var bounds;
140           bounds = arg.bounds;
141           return bounds.minx;
142         })),
143         miny: Math.min.apply(Math, this.metricses.map(function(arg) {
144           var bounds;
145           bounds = arg.bounds;
146           return bounds.miny;
147         })),
148         maxx: Math.max.apply(Math, this.metricses.map(function(arg) {
149           var bounds;
150           bounds = arg.bounds;
151           return bounds.maxx;
152         })),
153         maxy: Math.max.apply(Math, this.metricses.map(function(arg) {
154           var bounds;
155           bounds = arg.bounds;
156           return bounds.maxy;
157         }))
158       }
159     };
160     this.boundingBoxWidth = Math.ceil(this.metrics.width);
161   }
163   TextRenderer.prototype.draw = function(ctx, x, y) {
164     var i, j, len, line, ref, results;
165     ctx.textBaseline = 'top';
166     ctx.font = this.font;
167     i = 0;
168     ref = this.lines;
169     results = [];
170     for (j = 0, len = ref.length; j < len; j++) {
171       line = ref[j];
172       ctx.fillText(line, x, y + i * this.metrics.leading);
173       results.push(i += 1);
174     }
175     return results;
176   };
178   TextRenderer.prototype.getWidth = function(isEditing) {
179     if (isEditing == null) {
180       isEditing = false;
181     }
182     if (this.forcedWidth) {
183       return this.forcedWidth;
184     } else {
185       if (isEditing) {
186         return this.metrics.bounds.maxx + this.caratWidth;
187       } else {
188         return this.metrics.bounds.maxx;
189       }
190     }
191   };
193   TextRenderer.prototype.getHeight = function() {
194     return this.forcedHeight || (this.metrics.leading * this.lines.length);
195   };
197   return TextRenderer;
199 })();
201 module.exports = TextRenderer;