jonjanisch
29 Apr 2009, 11:48 AM
The TextMetrics class will incorrectly compute the width of any text which is bold since the bind method does not copy the font-weight (fontWeight) style property.
I think the reason why the dev who wrote the TextMetrics.bind method ignored the font-weight property is because El.getStyleAttribute("fontWeight") will throw an internal Javascript exception (atleast in IE) if the font-weight was specified in an external CSS file.
In other words, this works fine:
El copy = new El(el);
copy.setStyleAttribute("fontWeight", "bold");
this.el.setStyleAttribute("fontWeight", copy.getStyleAttribute("fontWeight"));
This does not work:
El copy = new El(el);
this.el.setStyleAttribute("fontWeight", copy.getStyleAttribute("fontWeight")); // font-weight specified in external CSS
The reason why it fails is because the DOM's fontWeight property returns a number while the native javascript method XElement.getStyleAttribute method declaration returns a String.
Before I show my solution, I have one question. In XElement.java, the native getStyleAttribute() method calls "this.getStyle()". Where exactly is the getStyle() method defined?
Anyway, since I couldn't "step into" that code, I created my own methods to get the font weight from the DOM.
public final native String getFontWeight(Element el) /*-{
return $doc.defaultView.getComputedStyle(el, "").fontWeight + '';
}-*/;
public final native String getFontWeightIE(Element el) /*-{
return el.currentStyle.fontWeight + '';
}-*/;
If I did not concatenate the empty string, it will throw the same error unless I change the return type to "int". So my proposed solution (that I cannot test) is to change the internal implementation of getStyle so that it always concats an empty string to the DOM style property (to ensure it returns a String).
Secondly, TextMetrics.bind should be updated to include the fontWeight property.
Does this make sense?
Thanks
Jonathan
I think the reason why the dev who wrote the TextMetrics.bind method ignored the font-weight property is because El.getStyleAttribute("fontWeight") will throw an internal Javascript exception (atleast in IE) if the font-weight was specified in an external CSS file.
In other words, this works fine:
El copy = new El(el);
copy.setStyleAttribute("fontWeight", "bold");
this.el.setStyleAttribute("fontWeight", copy.getStyleAttribute("fontWeight"));
This does not work:
El copy = new El(el);
this.el.setStyleAttribute("fontWeight", copy.getStyleAttribute("fontWeight")); // font-weight specified in external CSS
The reason why it fails is because the DOM's fontWeight property returns a number while the native javascript method XElement.getStyleAttribute method declaration returns a String.
Before I show my solution, I have one question. In XElement.java, the native getStyleAttribute() method calls "this.getStyle()". Where exactly is the getStyle() method defined?
Anyway, since I couldn't "step into" that code, I created my own methods to get the font weight from the DOM.
public final native String getFontWeight(Element el) /*-{
return $doc.defaultView.getComputedStyle(el, "").fontWeight + '';
}-*/;
public final native String getFontWeightIE(Element el) /*-{
return el.currentStyle.fontWeight + '';
}-*/;
If I did not concatenate the empty string, it will throw the same error unless I change the return type to "int". So my proposed solution (that I cannot test) is to change the internal implementation of getStyle so that it always concats an empty string to the DOM style property (to ensure it returns a String).
Secondly, TextMetrics.bind should be updated to include the fontWeight property.
Does this make sense?
Thanks
Jonathan