openfl
Version:
A fast, productive library for 2D cross-platform development.
1,101 lines (1,085 loc) • 36.2 kB
JavaScript
// Class: openfl.text._internal.TextEngine
var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this
$global.Object.defineProperty(exports, "__esModule", {value: true});
var __map_reserved = {};
// Imports
var $hxClasses = require("./../../../hxClasses_stub").default;
var $hxEnums = require("./../../../hxEnums_stub").default;
var $import = require("./../../../import_stub").default;
function EReg() {return require("./../../../EReg");}
function openfl__$Vector_Vector_$Impl_$() {return require("./../../../openfl/_Vector/Vector_Impl_");}
function openfl__$Vector_VectorIterator() {return require("./../../../openfl/_Vector/VectorIterator");}
function Std() {return require("./../../../Std");}
function openfl_text_TextField() {return require("./../../../openfl/text/TextField");}
function HxOverrides() {return require("./../../../HxOverrides");}
function openfl_text__$internal_TextLayoutGroup() {return require("./../../../openfl/text/_internal/TextLayoutGroup");}
function lime_utils_Log() {return require("./../../../lime/utils/Log");}
function openfl_text_Font() {return require("./../../../openfl/text/Font");}
function StringTools() {return require("./../../../StringTools");}
function haxe_ds_StringMap() {return require("./../../../haxe/ds/StringMap");}
function openfl_text__$internal_ShapeCache() {return require("./../../../openfl/text/_internal/ShapeCache");}
function openfl_geom_Rectangle() {return require("./../../../openfl/geom/Rectangle");}
// Constructor
var TextEngine = function(textField) {
this.__shapeCache = new (openfl_text__$internal_ShapeCache().default)();
this.textField = textField;
this.width = 100;
this.height = 100;
this.set_text("");
this.bounds = new (openfl_geom_Rectangle().default)(0,0,0,0);
this.textBounds = new (openfl_geom_Rectangle().default)(0,0,0,0);
this.type = "dynamic";
this.autoSize = "none";
this.embedFonts = false;
this.selectable = true;
this.borderColor = 0;
this.border = false;
this.backgroundColor = 16777215;
this.background = false;
this.gridFitType = "pixel";
this.maxChars = 0;
this.multiline = false;
this.numLines = 1;
this.sharpness = 0;
this.scrollH = 0;
this.set_scrollV(1);
this.wordWrap = false;
this.lineAscents = (openfl__$Vector_Vector_$Impl_$().default)._new();
this.lineBreaks = (openfl__$Vector_Vector_$Impl_$().default)._new();
this.lineDescents = (openfl__$Vector_Vector_$Impl_$().default)._new();
this.lineLeadings = (openfl__$Vector_Vector_$Impl_$().default)._new();
this.lineHeights = (openfl__$Vector_Vector_$Impl_$().default)._new();
this.lineWidths = (openfl__$Vector_Vector_$Impl_$().default)._new();
this.layoutGroups = (openfl__$Vector_Vector_$Impl_$().default)._new();
this.textFormatRanges = (openfl__$Vector_Vector_$Impl_$().default)._new();
if(TextEngine.__context == null) {
TextEngine.__context = window.document.createElement("canvas").getContext("2d");
}
}
// Meta
TextEngine.__name__ = "openfl.text._internal.TextEngine";
TextEngine.__isInterface__ = false;
TextEngine.prototype = {
createRestrictRegexp: function(restrict) {
var declinedRange = new (EReg().default)("\\^([^\\^]+)","gu");
var declined = "";
var accepting = false;
var accepted = declinedRange.map(restrict,function(ereg) {
if(accepting) {
accepting = !accepting;
return ereg.matched(1);
}
declined += ereg.matched(1);
accepting = !accepting;
return "";
});
var testRegexpParts = [];
if(accepted.length > 0) {
testRegexpParts.push("[^" + accepted + "]");
}
if(declined.length > 0) {
testRegexpParts.push("[" + declined + "]");
}
return new (EReg().default)("(" + testRegexpParts.join("|") + ")","g");
},
getBounds: function() {
var padding = this.border ? 1 : 0;
this.bounds.width = this.width + padding;
this.bounds.height = this.height + padding;
var x = this.width;
var y = this.height;
var lastIndex = this.layoutGroups.get_length() - 1;
var _g = 0;
var _g1 = this.layoutGroups.get_length();
while(_g < _g1) {
var i = _g++;
var group = this.layoutGroups[i];
if(i == lastIndex && group.startIndex == group.endIndex && this.type != "input") {
continue;
}
if(group.offsetX < x) {
x = group.offsetX;
}
if(group.offsetY < y) {
y = group.offsetY;
}
}
if(x >= this.width) {
x = 2;
}
if(y >= this.height) {
y = 2;
}
var textHeight = this.textHeight * 1.185;
this.textBounds.setTo(Math.max(x - 2,0),Math.max(y - 2,0),Math.min(this.textWidth + 4,this.bounds.width),Math.min(textHeight + 4,this.bounds.height));
},
getLine: function(index) {
if(index < 0 || index > this.lineBreaks.get_length() + 1) {
return null;
}
if(this.lineBreaks.get_length() == 0) {
return this.text;
} else {
return this.text.substring(index > 0 ? this.lineBreaks[index - 1] : 0,this.lineBreaks[index]);
}
},
getLineBreaks: function() {
this.lineBreaks.set_length(0);
var index = -1;
var cr = -1;
var lf = -1;
while(index < this.text.length) {
lf = this.text.indexOf("\n",index + 1);
cr = this.text.indexOf("\r",index + 1);
index = cr == -1 ? lf : lf == -1 ? cr : cr < lf ? cr : lf;
if(index > -1) {
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineBreaks,index);
} else {
break;
}
}
},
getLineBreakIndex: function(startIndex) {
if(startIndex == null) {
startIndex = 0;
}
var lineBreak = new (openfl__$Vector_VectorIterator().default)(this.lineBreaks);
while(lineBreak.hasNext()) {
var lineBreak1 = lineBreak.next();
if(lineBreak1 >= startIndex) {
return lineBreak1;
}
}
return -1;
},
getLineMeasurements: function() {
this.lineAscents.set_length(0);
this.lineDescents.set_length(0);
this.lineLeadings.set_length(0);
this.lineHeights.set_length(0);
this.lineWidths.set_length(0);
var currentLineAscent = 0.0;
var currentLineDescent = 0.0;
var currentLineLeading = null;
var currentLineHeight = 0.0;
var currentLineWidth = 0.0;
var currentTextHeight = 0.0;
this.textWidth = 0;
this.textHeight = 0;
this.numLines = 1;
this.maxScrollH = 0;
var lastIndex = this.layoutGroups.get_length() - 1;
var _g = 0;
var _g1 = this.layoutGroups.get_length();
while(_g < _g1) {
var i = _g++;
var group = this.layoutGroups[i];
if(i == lastIndex && group.startIndex == group.endIndex && this.type != "input") {
continue;
}
while(group.lineIndex > this.numLines - 1) {
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineAscents,currentLineAscent);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineDescents,currentLineDescent);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineLeadings,currentLineLeading != null ? currentLineLeading : 0);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineHeights,currentLineHeight);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineWidths,currentLineWidth);
currentLineAscent = 0;
currentLineDescent = 0;
currentLineLeading = null;
currentLineHeight = 0;
currentLineWidth = 0;
this.numLines++;
}
currentLineAscent = Math.max(currentLineAscent,group.ascent);
currentLineDescent = Math.max(currentLineDescent,group.descent);
if(currentLineLeading == null) {
currentLineLeading = group.leading;
} else {
currentLineLeading = (Std().default).int(Math.max(currentLineLeading,group.leading));
}
currentLineHeight = Math.max(currentLineHeight,group.height);
currentLineWidth = group.offsetX - 2 + group.width;
if(currentLineWidth > this.textWidth) {
this.textWidth = currentLineWidth;
}
currentTextHeight = Math.ceil(group.offsetY - 2 + group.ascent + group.descent);
if(currentTextHeight > this.textHeight) {
this.textHeight = currentTextHeight;
}
}
if(this.textHeight == 0 && this.textField != null && this.type == "input") {
var currentFormat = this.textField.__textFormat;
var ascent;
var descent;
var font = TextEngine.getFontInstance(currentFormat);
if(currentFormat.__ascent != null) {
ascent = currentFormat.size * currentFormat.__ascent;
descent = currentFormat.size * currentFormat.__descent;
} else if(font != null && font.unitsPerEM != 0) {
ascent = font.ascender / font.unitsPerEM * currentFormat.size;
descent = Math.abs(font.descender / font.unitsPerEM * currentFormat.size);
} else {
ascent = currentFormat.size;
descent = currentFormat.size * 0.185;
}
var leading = currentFormat.leading;
var heightValue = Math.ceil(ascent + descent + leading);
currentLineAscent = ascent;
currentLineDescent = descent;
currentLineLeading = leading;
currentTextHeight = Math.ceil(ascent + descent);
this.textHeight = currentTextHeight;
}
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineAscents,currentLineAscent);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineDescents,currentLineDescent);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineLeadings,currentLineLeading != null ? currentLineLeading : 0);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineHeights,currentLineHeight);
(openfl__$Vector_Vector_$Impl_$().default).push(this.lineWidths,currentLineWidth);
if(this.numLines == 1) {
if(currentLineLeading > 0) {
this.textHeight += currentLineLeading;
}
}
if(this.autoSize != "none") {
switch(this.autoSize) {
case "center":case "left":case "right":
if(!this.wordWrap) {
this.width = this.textWidth + 4;
}
this.height = this.textHeight + 4;
this.bottomScrollV = this.numLines;
break;
default:
}
}
if(this.textWidth > this.width - 4) {
this.maxScrollH = (Std().default).int(this.textWidth - this.width + 4);
} else {
this.maxScrollH = 0;
}
if(this.scrollH > this.maxScrollH) {
this.scrollH = this.maxScrollH;
}
},
getLayoutGroups: function() {
var _gthis = this;
this.layoutGroups.set_length(0);
if(this.text == null || this.text == "") {
return;
}
var rangeIndex = -1;
var formatRange = null;
var font = null;
var currentFormat = (openfl_text_TextField().default).__defaultTextFormat.clone();
var leading = 0;
var ascent = 0.0;
var maxAscent = 0.0;
var descent = 0.0;
var align = "left";
var blockIndent = 0;
var bullet = false;
var indent = 0;
var leftMargin = 0;
var rightMargin = 0;
var firstLineOfParagraph = true;
var layoutGroup = null;
var positions = null;
var widthValue = 0.0;
var heightValue = 0;
var maxHeightValue = 0;
var previousSpaceIndex = -2;
var previousBreakIndex = -1;
var spaceIndex = this.text.indexOf(" ");
var breakCount = 0;
var breakIndex = breakCount < this.lineBreaks.get_length() ? this.lineBreaks[breakCount] : -1;
var offsetX = 0.0;
var offsetY = 0.0;
var textIndex = 0;
var lineIndex = 0;
var getPositions = function(text,startIndex,endIndex) {
var letterSpacing = 0.0;
if(formatRange.format.letterSpacing != null) {
letterSpacing = formatRange.format.letterSpacing;
}
var html5Positions = function() {
var positions1 = [];
if(_gthis.__useIntAdvances == null) {
var html5Positions1 = new (EReg().default)("Trident/7.0","");
_gthis.__useIntAdvances = html5Positions1.match(window.navigator.userAgent);
}
if(_gthis.__useIntAdvances) {
var previousWidth = 0.0;
var width;
var _g = startIndex;
var _g1 = endIndex;
while(_g < _g1) {
var i = _g++;
width = _gthis.measureText(text.substring(startIndex,i + 1));
positions1.push(width - previousWidth);
previousWidth = width;
}
} else {
var _g2 = startIndex;
var _g11 = endIndex;
while(_g2 < _g11) {
var i1 = _g2++;
var advance;
if(i1 < text.length - 1) {
var nextWidth = _gthis.measureText(text.charAt(i1 + 1));
var twoWidths = _gthis.measureText((HxOverrides().default).substr(text,i1,2));
advance = twoWidths - nextWidth;
} else {
advance = TextEngine.__context.measureText(text.charAt(i1)).width;
}
positions1.push(advance);
}
}
return positions1;
};
if(currentFormat.align == "justify") {
return html5Positions();
}
return _gthis.__shapeCache.cache(formatRange,html5Positions,text.substring(startIndex,endIndex));
};
var getPositionsWidth = function(positions2) {
var width1 = 0.0;
var _g3 = 0;
while(_g3 < positions2.length) {
var position = positions2[_g3];
++_g3;
width1 += position;
}
return width1;
};
var getTextWidth = function(text1) {
return _gthis.measureText(text1);
};
var getBaseX = function() {
return 2 + leftMargin + blockIndent + (firstLineOfParagraph ? indent : 0);
};
var getWrapWidth = function() {
return _gthis.width - 2 - rightMargin - getBaseX();
};
var nextLayoutGroup = function(startIndex1,endIndex1) {
if(layoutGroup == null || layoutGroup.startIndex != layoutGroup.endIndex) {
layoutGroup = new (openfl_text__$internal_TextLayoutGroup().default)(formatRange.format,startIndex1,endIndex1);
(openfl__$Vector_Vector_$Impl_$().default).push(_gthis.layoutGroups,layoutGroup);
} else {
layoutGroup.format = formatRange.format;
layoutGroup.startIndex = startIndex1;
layoutGroup.endIndex = endIndex1;
}
};
var setLineMetrics = function() {
if(currentFormat.__ascent != null) {
ascent = currentFormat.size * currentFormat.__ascent;
descent = currentFormat.size * currentFormat.__descent;
} else if(font != null && font.unitsPerEM != 0) {
ascent = font.ascender / font.unitsPerEM * currentFormat.size;
descent = Math.abs(font.descender / font.unitsPerEM * currentFormat.size);
} else {
ascent = currentFormat.size;
descent = currentFormat.size * 0.185;
}
leading = currentFormat.leading;
heightValue = Math.ceil(ascent + descent + leading);
if(heightValue > maxHeightValue) {
maxHeightValue = heightValue;
}
if(ascent > maxAscent) {
maxAscent = ascent;
}
};
var setParagraphMetrics = function() {
firstLineOfParagraph = true;
align = currentFormat.align != null ? currentFormat.align : "left";
blockIndent = currentFormat.blockIndent != null ? currentFormat.blockIndent : 0;
indent = currentFormat.indent != null ? currentFormat.indent : 0;
leftMargin = currentFormat.leftMargin != null ? currentFormat.leftMargin : 0;
rightMargin = currentFormat.rightMargin != null ? currentFormat.rightMargin : 0;
var setParagraphMetrics1 = currentFormat.bullet != null;
var setParagraphMetrics2 = currentFormat.tabStops != null;
};
var nextFormatRange = function() {
var nextFormatRange1 = _gthis.textFormatRanges.get_length() - 1;
if(rangeIndex < nextFormatRange1) {
rangeIndex += 1;
formatRange = _gthis.textFormatRanges[rangeIndex];
currentFormat.__merge(formatRange.format);
var fontString = TextEngine.getFont(currentFormat);
TextEngine.__context.font = fontString;
font = TextEngine.getFontInstance(currentFormat);
return true;
}
return false;
};
var setFormattedPositions = function(startIndex2,endIndex2) {
if(startIndex2 >= endIndex2) {
positions = [];
widthValue = 0;
} else if(endIndex2 <= formatRange.end) {
positions = getPositions(_gthis.text,startIndex2,endIndex2);
widthValue = getPositionsWidth(positions);
} else {
var tempIndex = startIndex2;
var tempRangeEnd = formatRange.end;
var countRanges = 0;
positions = [];
widthValue = 0;
while(true) {
if(tempIndex != tempRangeEnd) {
var tempPositions = getPositions(_gthis.text,tempIndex,tempRangeEnd);
positions = positions.concat(tempPositions);
}
if(tempRangeEnd != endIndex2) {
if(!nextFormatRange()) {
(lime_utils_Log().default).warn("You found a bug in OpenFL's text code! Please save a copy of your project and create an issue on GitHub so we can fix this.",{ fileName : "../node_modules/openfl-haxelib/src/openfl/text/_internal/TextEngine.hx", lineNumber : 1121, className : "openfl.text._internal.TextEngine", methodName : "getLayoutGroups"});
break;
}
tempIndex = tempRangeEnd;
tempRangeEnd = endIndex2 < formatRange.end ? endIndex2 : formatRange.end;
++countRanges;
} else {
widthValue = getPositionsWidth(positions);
break;
}
}
rangeIndex -= countRanges + 1;
nextFormatRange();
}
};
var placeFormattedText = function(endIndex3) {
if(endIndex3 <= formatRange.end) {
positions = getPositions(_gthis.text,textIndex,endIndex3);
widthValue = getPositionsWidth(positions);
nextLayoutGroup(textIndex,endIndex3);
layoutGroup.positions = positions;
var placeFormattedText1 = getBaseX();
layoutGroup.offsetX = offsetX + placeFormattedText1;
layoutGroup.ascent = ascent;
layoutGroup.descent = descent;
layoutGroup.leading = leading;
layoutGroup.lineIndex = lineIndex;
layoutGroup.offsetY = offsetY + 2;
layoutGroup.width = widthValue;
layoutGroup.height = heightValue;
offsetX += widthValue;
if(endIndex3 == formatRange.end) {
layoutGroup = null;
nextFormatRange();
setLineMetrics();
}
} else {
while(true) {
var tempRangeEnd1 = endIndex3 < formatRange.end ? endIndex3 : formatRange.end;
if(textIndex != tempRangeEnd1) {
positions = getPositions(_gthis.text,textIndex,tempRangeEnd1);
widthValue = getPositionsWidth(positions);
nextLayoutGroup(textIndex,tempRangeEnd1);
layoutGroup.positions = positions;
var placeFormattedText2 = getBaseX();
layoutGroup.offsetX = offsetX + placeFormattedText2;
layoutGroup.ascent = ascent;
layoutGroup.descent = descent;
layoutGroup.leading = leading;
layoutGroup.lineIndex = lineIndex;
layoutGroup.offsetY = offsetY + 2;
layoutGroup.width = widthValue;
layoutGroup.height = heightValue;
offsetX += widthValue;
textIndex = tempRangeEnd1;
}
if(tempRangeEnd1 == formatRange.end) {
layoutGroup = null;
}
if(tempRangeEnd1 == endIndex3) {
break;
}
if(!nextFormatRange()) {
(lime_utils_Log().default).warn("You found a bug in OpenFL's text code! Please save a copy of your project and create an issue on GitHub so we can fix this.",{ fileName : "../node_modules/openfl-haxelib/src/openfl/text/_internal/TextEngine.hx", lineNumber : 1209, className : "openfl.text._internal.TextEngine", methodName : "getLayoutGroups"});
break;
}
setLineMetrics();
}
}
textIndex = endIndex3;
};
var alignBaseline = function() {
setLineMetrics();
var i2 = _gthis.layoutGroups.get_length();
while(--i2 > -1) {
var lg = _gthis.layoutGroups[i2];
if(lg.lineIndex < lineIndex) {
break;
}
if(lg.lineIndex > lineIndex) {
continue;
}
lg.ascent = maxAscent;
lg.height = maxHeightValue;
}
offsetY += maxHeightValue;
maxAscent = 0.0;
maxHeightValue = 0;
lineIndex += 1;
offsetX = 0;
firstLineOfParagraph = false;
};
var breakLongWords = function(endIndex4) {
var remainingPositions = positions;
var bufferCount;
var placeIndex;
var positionWidth;
var currentPosition;
var tempWidth = getPositionsWidth(remainingPositions);
var i3 = remainingPositions.length - 1;
while(i3 >= 0) {
var currentCharCode = (HxOverrides().default).cca(_gthis.text,textIndex + i3);
if(currentCharCode != 32 && currentCharCode != 9) {
break;
}
var position1 = remainingPositions[i3];
tempWidth -= position1;
--i3;
}
while(remainingPositions.length > 0 && offsetX + tempWidth > getWrapWidth()) {
bufferCount = 0;
i3 = bufferCount;
positionWidth = 0.0;
while(offsetX + positionWidth < getWrapWidth()) {
currentPosition = remainingPositions[i3];
if(currentPosition == 0.0) {
++i3;
++bufferCount;
} else {
positionWidth += currentPosition;
++i3;
}
}
if(i3 == bufferCount) {
i3 = bufferCount + 1;
} else {
while(i3 > 1 && offsetX + positionWidth > getWrapWidth()) {
--i3;
if(i3 - bufferCount > 0) {
setFormattedPositions(textIndex,textIndex + i3 - bufferCount);
positionWidth = widthValue;
} else {
i3 = 1;
bufferCount = 0;
setFormattedPositions(textIndex,textIndex + 1);
positionWidth = 0;
}
}
}
placeIndex = textIndex + i3 - bufferCount;
placeFormattedText(placeIndex);
alignBaseline();
setFormattedPositions(placeIndex,endIndex4);
remainingPositions = positions;
tempWidth = widthValue;
}
};
var placeText = function(endIndex5) {
if(_gthis.width >= 4 && _gthis.wordWrap) {
breakLongWords(endIndex5);
}
placeFormattedText(endIndex5);
};
nextFormatRange();
setParagraphMetrics();
setLineMetrics();
var wrap;
var maxLoops = this.text.length + 1;
while(textIndex < maxLoops) if(breakIndex > -1 && (spaceIndex == -1 || breakIndex < spaceIndex)) {
if(textIndex <= breakIndex) {
setFormattedPositions(textIndex,breakIndex);
placeText(breakIndex);
layoutGroup = null;
} else if(layoutGroup != null && layoutGroup.startIndex != layoutGroup.endIndex) {
if(layoutGroup.endIndex == spaceIndex) {
layoutGroup.width -= layoutGroup.getAdvance(layoutGroup.positions.length - 1);
}
layoutGroup = null;
}
alignBaseline();
if(formatRange.end == breakIndex) {
nextFormatRange();
setLineMetrics();
}
textIndex = breakIndex + 1;
previousBreakIndex = breakIndex;
++breakCount;
breakIndex = breakCount < this.lineBreaks.get_length() ? this.lineBreaks[breakCount] : -1;
setParagraphMetrics();
} else if(spaceIndex > -1) {
if(layoutGroup != null && layoutGroup.startIndex != layoutGroup.endIndex) {
layoutGroup = null;
}
wrap = false;
while(textIndex < this.text.length) {
var endIndex6 = -1;
if(spaceIndex == -1) {
endIndex6 = breakIndex;
} else {
endIndex6 = spaceIndex + 1;
if(breakIndex > -1 && breakIndex < endIndex6) {
endIndex6 = breakIndex;
}
}
if(endIndex6 == -1) {
endIndex6 = this.text.length;
}
setFormattedPositions(textIndex,endIndex6);
if(align == "justify") {
if(positions.length > 0 && textIndex == previousSpaceIndex) {
textIndex += 1;
var spaceWidth = positions.shift();
widthValue -= spaceWidth;
offsetX += spaceWidth;
}
if(positions.length > 0 && endIndex6 == spaceIndex + 1) {
--endIndex6;
var spaceWidth1 = positions.pop();
widthValue -= spaceWidth1;
}
}
if(this.wordWrap) {
if(offsetX + widthValue > getWrapWidth()) {
wrap = true;
if(positions.length > 0 && endIndex6 == spaceIndex + 1) {
var lastPosition = positions[positions.length - 1];
var spaceWidth2 = lastPosition;
if(offsetX + widthValue - spaceWidth2 <= getWrapWidth()) {
wrap = false;
}
}
}
}
if(wrap) {
if(align != "justify" && (layoutGroup != null || this.layoutGroups.get_length() > 0)) {
var previous = layoutGroup;
if(previous == null) {
previous = this.layoutGroups[this.layoutGroups.get_length() - 1];
}
previous.width -= previous.getAdvance(previous.positions.length - 1);
previous.endIndex--;
}
var i4 = this.layoutGroups.get_length() - 1;
var offsetCount = 0;
while(i4 >= 0) {
layoutGroup = this.layoutGroups[i4];
if(i4 > 0 && layoutGroup.startIndex > previousSpaceIndex) {
++offsetCount;
} else {
break;
}
--i4;
}
if(textIndex == previousSpaceIndex + 1) {
alignBaseline();
}
offsetX = 0;
if(offsetCount > 0) {
var bumpX = this.layoutGroups[this.layoutGroups.get_length() - offsetCount].offsetX;
var _g4 = this.layoutGroups.get_length() - offsetCount;
var _g12 = this.layoutGroups.get_length();
while(_g4 < _g12) {
var i5 = _g4++;
layoutGroup = this.layoutGroups[i5];
layoutGroup.offsetX -= bumpX;
layoutGroup.offsetY = offsetY + 2;
layoutGroup.lineIndex = lineIndex;
offsetX += layoutGroup.width;
}
}
placeText(endIndex6);
wrap = false;
} else if(layoutGroup != null && textIndex == spaceIndex && previousSpaceIndex != spaceIndex - 1) {
if(align != "justify") {
layoutGroup.endIndex = spaceIndex;
layoutGroup.positions = layoutGroup.positions.concat(positions);
layoutGroup.width += widthValue;
}
offsetX += widthValue;
textIndex = endIndex6;
} else if(layoutGroup == null || align == "justify") {
placeText(endIndex6);
if(endIndex6 == this.text.length) {
alignBaseline();
}
} else {
var tempRangeEnd2 = endIndex6 < formatRange.end ? endIndex6 : formatRange.end;
if(tempRangeEnd2 < endIndex6) {
positions = getPositions(this.text,textIndex,tempRangeEnd2);
widthValue = getPositionsWidth(positions);
}
layoutGroup.endIndex = tempRangeEnd2;
layoutGroup.positions = layoutGroup.positions.concat(positions);
layoutGroup.width += widthValue;
offsetX += widthValue;
if(tempRangeEnd2 == formatRange.end) {
layoutGroup = null;
nextFormatRange();
setLineMetrics();
textIndex = tempRangeEnd2;
if(tempRangeEnd2 != endIndex6) {
placeFormattedText(endIndex6);
}
}
if(breakIndex == endIndex6) {
++endIndex6;
}
textIndex = endIndex6;
if(endIndex6 == this.text.length) {
alignBaseline();
if(breakIndex != -1) {
previousBreakIndex = breakIndex;
++breakCount;
breakIndex = breakCount < this.lineBreaks.get_length() ? this.lineBreaks[breakCount] : -1;
}
}
}
var nextSpaceIndex = this.text.indexOf(" ",textIndex);
if(breakIndex == previousSpaceIndex) {
layoutGroup.endIndex = breakIndex;
if(breakIndex - layoutGroup.startIndex - layoutGroup.positions.length < 0) {
layoutGroup.positions.push(0.0);
}
textIndex = breakIndex + 1;
}
previousSpaceIndex = spaceIndex;
spaceIndex = nextSpaceIndex;
if(breakIndex > -1 && breakIndex <= textIndex && (spaceIndex > breakIndex || spaceIndex == -1) || textIndex > this.text.length) {
break;
}
}
} else {
if(textIndex < this.text.length) {
setFormattedPositions(textIndex,this.text.length);
placeText(this.text.length);
alignBaseline();
}
textIndex += 1;
}
if(previousBreakIndex == textIndex - 2 && previousBreakIndex > -1) {
nextLayoutGroup(textIndex - 1,textIndex - 1);
layoutGroup.positions = [];
layoutGroup.ascent = ascent;
layoutGroup.descent = descent;
layoutGroup.leading = leading;
layoutGroup.lineIndex = lineIndex;
layoutGroup.offsetX = getBaseX();
layoutGroup.offsetY = offsetY + 2;
layoutGroup.width = 0;
layoutGroup.height = heightValue;
}
},
measureText: function(text) {
return TextEngine.__context.measureText(text).width;
},
restrictText: function(value) {
if(value == null) {
return value;
}
if(this.__restrictRegexp != null) {
value = this.__restrictRegexp.split(value).join("");
}
return value;
},
setTextAlignment: function() {
var lineIndex = -1;
var offsetX = 0.0;
var totalWidth = this.width - 4;
var group;
var lineLength;
var lineMeasurementsDirty = false;
var _g = 0;
var _g1 = this.layoutGroups.get_length();
while(_g < _g1) {
var i = _g++;
group = this.layoutGroups[i];
if(group.lineIndex != lineIndex) {
lineIndex = group.lineIndex;
totalWidth = this.width - 4 - group.format.rightMargin;
switch(group.format.align) {
case "center":
if(this.lineWidths[lineIndex] < totalWidth) {
offsetX = Math.round((totalWidth - this.lineWidths[lineIndex]) / 2);
} else {
offsetX = 0;
}
break;
case "justify":
if(this.lineWidths[lineIndex] < totalWidth) {
lineLength = 1;
var _g2 = i + 1;
var _g11 = this.layoutGroups.get_length();
while(_g2 < _g11) {
var j = _g2++;
if(this.layoutGroups[j].lineIndex == lineIndex) {
if(j == 0 || (HxOverrides().default).cca(this.text,this.layoutGroups[j].startIndex - 1) == 32) {
++lineLength;
}
} else {
break;
}
}
if(lineLength > 1) {
group = this.layoutGroups[i + lineLength - 1];
var endChar = (HxOverrides().default).cca(this.text,group.endIndex);
if(group.endIndex < this.text.length && endChar != 10 && endChar != 13) {
offsetX = (totalWidth - this.lineWidths[lineIndex]) / (lineLength - 1);
lineMeasurementsDirty = true;
var j1 = 1;
while(true) {
this.layoutGroups[i + j1].offsetX += offsetX * j1;
if(!(++j1 < lineLength)) {
break;
}
}
}
}
}
offsetX = 0;
break;
case "right":
if(this.lineWidths[lineIndex] < totalWidth) {
offsetX = Math.round(totalWidth - this.lineWidths[lineIndex]);
} else {
offsetX = 0;
}
break;
default:
offsetX = 0;
}
}
if(offsetX > 0) {
group.offsetX += offsetX;
}
}
if(lineMeasurementsDirty) {
this.getLineMeasurements();
}
},
trimText: function(value) {
if(value == null) {
return value;
}
if(this.maxChars > 0 && value.length > this.maxChars) {
value = (HxOverrides().default).substr(value,0,this.maxChars);
}
return value;
},
update: function() {
if(this.text == null || this.textFormatRanges.get_length() == 0) {
this.lineAscents.set_length(0);
this.lineBreaks.set_length(0);
this.lineDescents.set_length(0);
this.lineLeadings.set_length(0);
this.lineHeights.set_length(0);
this.lineWidths.set_length(0);
this.layoutGroups.set_length(0);
this.textWidth = 0;
this.textHeight = 0;
this.numLines = 1;
this.maxScrollH = 0;
this.maxScrollV = 1;
this.bottomScrollV = 1;
} else {
this.getLineBreaks();
this.getLayoutGroups();
this.getLineMeasurements();
this.setTextAlignment();
}
this.getBounds();
},
get_bottomScrollV: function() {
if(this.numLines == 1 || this.lineHeights == null) {
return 1;
} else {
var ret = this.lineHeights.get_length();
var tempHeight = this.lineLeadings.get_length() == ret ? -this.lineLeadings[ret - 1] : 0.0;
var _g = (this.get_scrollV() > 0 ? this.get_scrollV() : 1) - 1;
var _g1 = this.lineHeights.get_length();
while(_g < _g1) {
var i = _g++;
var lineHeight = this.lineHeights[i];
tempHeight += lineHeight;
if(tempHeight > this.height - 4) {
ret = i + (tempHeight - this.height >= 0 ? 0 : 1);
break;
}
}
if(ret < this.get_scrollV()) {
return this.get_scrollV();
}
return ret;
}
},
get_maxScrollV: function() {
if(this.numLines == 1 || this.lineHeights == null) {
return 1;
} else {
var i = this.numLines - 1;
var tempHeight = 0.0;
var j = i;
while(i >= 0) {
tempHeight += this.lineHeights[i];
if(tempHeight > this.height - 4) {
i += tempHeight - this.height < 0 ? 1 : 2;
break;
}
--i;
}
if(i < 1) {
return 1;
}
return i;
}
},
set_restrict: function(value) {
if(this.restrict == value) {
return this.restrict;
}
this.restrict = value;
if(this.restrict == null || this.restrict.length == 0) {
this.__restrictRegexp = null;
} else {
this.__restrictRegexp = this.createRestrictRegexp(value);
}
return this.restrict;
},
get_scrollV: function() {
if(this.numLines == 1 || this.lineHeights == null) {
return 1;
}
var max = this.get_maxScrollV();
if(this.scrollV > max) {
return max;
}
return this.scrollV;
},
set_scrollV: function(value) {
if(value < 1) {
value = 1;
} else if(value > this.get_maxScrollV()) {
value = this.get_maxScrollV();
}
return this.scrollV = value;
},
set_text: function(value) {
return this.text = value;
}
};
TextEngine.prototype.__class__ = TextEngine.prototype.constructor = $hxClasses["openfl.text._internal.TextEngine"] = TextEngine;
// Init
// Statics
TextEngine.findFont = function(name) {
return (openfl_text_Font().default).__fontByName.get(name);
}
TextEngine.findFontVariant = function(format) {
var fontName = format.font;
var bold = format.bold;
var italic = format.italic;
if(fontName == null) {
fontName = "_serif";
}
var fontNamePrefix = (StringTools().default).replace((StringTools().default).replace(fontName," Normal","")," Regular","");
if(bold && italic && (openfl_text_Font().default).__fontByName.exists(fontNamePrefix + " Bold Italic")) {
return TextEngine.findFont(fontNamePrefix + " Bold Italic");
} else if(bold && (openfl_text_Font().default).__fontByName.exists(fontNamePrefix + " Bold")) {
return TextEngine.findFont(fontNamePrefix + " Bold");
} else if(italic && (openfl_text_Font().default).__fontByName.exists(fontNamePrefix + " Italic")) {
return TextEngine.findFont(fontNamePrefix + " Italic");
}
return TextEngine.findFont(fontName);
}
TextEngine.getDefaultFont = function(name,bold,italic) {
if(TextEngine.__defaultFonts == null) {
TextEngine.__defaultFonts = new (haxe_ds_StringMap().default)();
}
var fontSet = TextEngine.__defaultFonts.get(name);
if(fontSet == null) {
return null;
}
return fontSet.getFont(bold,italic);
}
TextEngine.getFormatHeight = function(format) {
var ascent;
var descent;
var font = TextEngine.getFont(format);
TextEngine.__context.font = font;
var font1 = TextEngine.getFontInstance(format);
if(format.__ascent != null) {
ascent = format.size * format.__ascent;
descent = format.size * format.__descent;
} else if(font1 != null && font1.unitsPerEM != 0) {
ascent = font1.ascender / font1.unitsPerEM * format.size;
descent = Math.abs(font1.descender / font1.unitsPerEM * format.size);
} else {
ascent = format.size;
descent = format.size * 0.185;
}
var leading = format.leading;
return ascent + descent + leading;
}
TextEngine.getFont = function(format) {
var fontName = format.font;
var bold = format.bold;
var italic = format.italic;
if(fontName == null) {
fontName = "_serif";
}
var fontNamePrefix = (StringTools().default).replace((StringTools().default).replace(fontName," Normal","")," Regular","");
if(bold && italic && (openfl_text_Font().default).__fontByName.exists(fontNamePrefix + " Bold Italic")) {
fontName = fontNamePrefix + " Bold Italic";
bold = false;
italic = false;
} else if(bold && (openfl_text_Font().default).__fontByName.exists(fontNamePrefix + " Bold")) {
fontName = fontNamePrefix + " Bold";
bold = false;
} else if(italic && (openfl_text_Font().default).__fontByName.exists(fontNamePrefix + " Italic")) {
fontName = fontNamePrefix + " Italic";
italic = false;
} else {
if(bold && (fontName.indexOf(" Bold ") > -1 || (StringTools().default).endsWith(fontName," Bold"))) {
bold = false;
}
if(italic && (fontName.indexOf(" Italic ") > -1 || (StringTools().default).endsWith(fontName," Italic"))) {
italic = false;
}
}
var font = italic ? "italic " : "normal ";
font += "normal ";
font += bold ? "bold " : "normal ";
font += format.size + "px";
font += "/" + (format.size + 3) + "px ";
var font1;
switch(fontName) {
case "_sans":
font1 = "sans-serif";
break;
case "_serif":
font1 = "serif";
break;
case "_typewriter":
font1 = "monospace";
break;
default:
font1 = "'" + new (EReg().default)("^[\\s'\"]+(.*)[\\s'\"]+$","").replace(fontName,"$1") + "'";
}
font += "" + font1;
return font;
}
TextEngine.getFontInstance = function(format) {
return TextEngine.findFontVariant(format);
}
TextEngine.__meta__ = { obj : { SuppressWarnings : ["checkstyle:FieldDocComment"]}, fields : { __cairoFont : { SuppressWarnings : ["checkstyle:Dynamic"]}}}
TextEngine.GUTTER = 2
TextEngine.UTF8_TAB = 9
TextEngine.UTF8_ENDLINE = 10
TextEngine.UTF8_SPACE = 32
TextEngine.UTF8_HYPHEN = 45
// Export
exports.default = TextEngine;