move text measuring into separate module

This commit is contained in:
nightwing 2014-02-15 12:30:30 +04:00
commit f352165725
4 changed files with 183 additions and 127 deletions

View file

@ -41,10 +41,6 @@ var Text = function(parentEl) {
this.element = dom.createElement("div");
this.element.className = "ace_layer ace_text-layer";
parentEl.appendChild(this.element);
this.$characterSize = {width: 0, height: 0};
this.checkForSizeChanges();
this.$pollSizeChanges();
};
(function() {
@ -63,132 +59,27 @@ var Text = function(parentEl) {
};
this.getLineHeight = function() {
return this.$characterSize.height || 0;
return this.$fontMetrics.$characterSize.height || 0;
};
this.getCharacterWidth = function() {
return this.$characterSize.width || 0;
return this.$fontMetrics.$characterSize.width || 0;
};
this.$setFontMetrics = function(measure) {
this.$fontMetrics = measure;
this.$fontMetrics.on("changeCharacterSize", function(e) {
this._signal("changeCharacterSize", e);
}.bind(this));
this.$pollSizeChanges();
}
this.checkForSizeChanges = function() {
var size = this.$measureSizes();
if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
this.$measureNode.style.fontWeight = "bold";
var boldSize = this.$measureSizes();
this.$measureNode.style.fontWeight = "";
this.$characterSize = size;
this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;
this._emit("changeCharacterSize", {data: size});
}
this.$fontMetrics.checkForSizeChanges();
};
this.$pollSizeChanges = function() {
var self = this;
this.$pollSizeChangesTimer = setInterval(function() {
self.checkForSizeChanges();
}, 500);
return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges();
};
this.$fontStyles = {
fontFamily : 1,
fontSize : 1,
fontWeight : 1,
fontStyle : 1,
lineHeight : 1
};
this.$measureSizes = useragent.isIE || useragent.isOldGecko ? function() {
var n = 1000;
if (!this.$measureNode) {
var measureNode = this.$measureNode = dom.createElement("div");
var style = measureNode.style;
style.width = style.height = "auto";
style.left = style.top = (-n * 40) + "px";
style.visibility = "hidden";
style.position = "fixed";
style.overflow = "visible";
style.whiteSpace = "nowrap";
// in FF 3.6 monospace fonts can have a fixed sub pixel width.
// that's why we have to measure many characters
// Note: characterWidth can be a float!
measureNode.innerHTML = lang.stringRepeat("Xy", n);
if (this.element.ownerDocument.body) {
this.element.ownerDocument.body.appendChild(measureNode);
} else {
var container = this.element.parentNode;
while (!dom.hasCssClass(container, "ace_editor"))
container = container.parentNode;
container.appendChild(measureNode);
}
}
// Size and width can be null if the editor is not visible or
// detached from the document
if (!this.element.offsetWidth)
return null;
var style = this.$measureNode.style;
var computedStyle = dom.computedStyle(this.element);
for (var prop in this.$fontStyles)
style[prop] = computedStyle[prop];
var size = {
height: this.$measureNode.offsetHeight,
width: this.$measureNode.offsetWidth / (n * 2)
};
// Size and width can be null if the editor is not visible or
// detached from the document
if (size.width == 0 || size.height == 0)
return null;
return size;
}
: function() {
if (!this.$measureNode) {
var measureNode = this.$measureNode = dom.createElement("div");
var style = measureNode.style;
style.width = style.height = "auto";
style.left = style.top = -100 + "px";
style.visibility = "hidden";
style.position = "fixed";
style.overflow = "visible";
style.whiteSpace = "nowrap";
// fixes fractional fixed-width fonts; see http://git.io/CavZNw
measureNode.innerHTML = lang.stringRepeat("X", 100);
var container = this.element.parentNode;
while (container && !dom.hasCssClass(container, "ace_editor"))
container = container.parentNode;
if (!container)
return this.$measureNode = null;
container.appendChild(measureNode);
}
var rect = this.$measureNode.getBoundingClientRect();
var size = {
height: rect.height,
width: rect.width / 100
};
// Size and width can be null if the editor is not visible or
// detached from the document
if (size.width == 0 || size.height == 0)
return null;
return size;
};
this.setSession = function(session) {
this.session = session;
this.$computeTabString();