From eb40ca44baca051db8c937b03d5f8a208ff938b4 Mon Sep 17 00:00:00 2001
From: Sam El-Husseini
Date: Thu, 20 Feb 2020 17:16:01 -0800
Subject: [PATCH] Dynamic fonts (#3698)
* Piping themes into the renderer and ensuring fields update their size information when constants change.
---
core/field.js | 91 ++++++++----
core/field_checkbox.js | 36 ++---
core/field_dropdown.js | 38 ++---
core/field_image.js | 7 +
core/field_multilineinput.js | 51 +++----
core/flyout_base.js | 2 +
core/flyout_button.js | 27 +++-
core/renderers/common/block_rendering.js | 5 +-
core/renderers/common/constants.js | 153 +++++++++++++++-----
core/renderers/common/debugger.js | 28 +++-
core/renderers/common/renderer.js | 20 ++-
core/renderers/geras/highlight_constants.js | 8 +
core/renderers/geras/renderer.js | 13 +-
core/renderers/zelos/constants.js | 81 ++++-------
core/theme.js | 42 ++++--
core/theme/highcontrast.js | 6 +
core/theme_manager.js | 4 +
core/utils/dom.js | 58 +++++++-
core/workspace_svg.js | 20 ++-
tests/mocha/field_checkbox_test.js | 4 +
tests/playground.html | 25 ++++
21 files changed, 495 insertions(+), 224 deletions(-)
diff --git a/core/field.js b/core/field.js
index 32c239275..c51ec65e8 100644
--- a/core/field.js
+++ b/core/field.js
@@ -310,10 +310,6 @@ Blockly.Field.prototype.initModel = function() {
* @protected
*/
Blockly.Field.prototype.createBorderRect_ = function() {
- this.size_.height =
- Math.max(this.size_.height, this.constants_.FIELD_BORDER_RECT_HEIGHT);
- this.size_.width =
- Math.max(this.size_.width, this.constants_.FIELD_BORDER_RECT_X_PADDING * 2);
this.borderRect_ = /** @type {!SVGRectElement} **/
(Blockly.utils.dom.createSvgElement('rect',
{
@@ -334,24 +330,12 @@ Blockly.Field.prototype.createBorderRect_ = function() {
* @protected
*/
Blockly.Field.prototype.createTextElement_ = function() {
- var xOffset = this.borderRect_ ?
- this.constants_.FIELD_BORDER_RECT_X_PADDING : 0;
- var baselineCenter = this.constants_.FIELD_TEXT_BASELINE_CENTER;
- var baselineY = this.constants_.FIELD_TEXT_BASELINE_Y;
- this.size_.height = Math.max(this.size_.height, baselineCenter ?
- this.constants_.FIELD_TEXT_HEIGHT : baselineY);
- if (this.size_.height > this.constants_.FIELD_TEXT_HEIGHT) {
- baselineY += (this.size_.height - baselineY) / 2;
- }
this.textElement_ = /** @type {!SVGTextElement} **/
(Blockly.utils.dom.createSvgElement('text',
{
'class': 'blocklyText',
- 'y': baselineCenter ? this.size_.height / 2 : baselineY,
- 'dy': this.constants_.FIELD_TEXT_Y_OFFSET,
- 'x': xOffset
}, this.fieldGroup_));
- if (baselineCenter) {
+ if (this.constants_.FIELD_TEXT_BASELINE_CENTER) {
this.textElement_.setAttribute('dominant-baseline', 'central');
}
this.textContent_ = document.createTextNode('');
@@ -587,8 +571,8 @@ Blockly.Field.prototype.applyColour = function() {
Blockly.Field.prototype.render_ = function() {
if (this.textContent_) {
this.textContent_.nodeValue = this.getDisplayText_();
- this.updateSize_();
}
+ this.updateSize_();
};
/**
@@ -619,22 +603,73 @@ Blockly.Field.prototype.updateWidth = function() {
/**
* Updates the size of the field based on the text.
+ * @param {number=} opt_margin margin to use when positioning the text element.
* @protected
*/
-Blockly.Field.prototype.updateSize_ = function() {
- var textWidth = Blockly.utils.dom.getFastTextWidth(
- /** @type {!SVGTextElement} */ (this.textElement_),
- this.constants_.FIELD_TEXT_FONTSIZE,
- this.constants_.FIELD_TEXT_FONTWEIGHT,
- this.constants_.FIELD_TEXT_FONTFAMILY);
- var totalWidth = textWidth;
- if (this.borderRect_) {
- totalWidth += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
- this.borderRect_.setAttribute('width', totalWidth);
+Blockly.Field.prototype.updateSize_ = function(opt_margin) {
+ var constants = this.constants_;
+ var xOffset = opt_margin != undefined ? opt_margin :
+ (this.borderRect_ ? this.constants_.FIELD_BORDER_RECT_X_PADDING : 0);
+ var totalWidth = xOffset * 2;
+ var totalHeight = constants.FIELD_TEXT_HEIGHT;
+
+ var contentWidth = 0;
+ if (this.textElement_) {
+ contentWidth = Blockly.utils.dom.getFastTextWidth(this.textElement_,
+ constants.FIELD_TEXT_FONTSIZE,
+ constants.FIELD_TEXT_FONTWEIGHT,
+ constants.FIELD_TEXT_FONTFAMILY);
+ totalWidth += contentWidth;
}
+ if (this.borderRect_) {
+ totalHeight = Math.max(totalHeight, constants.FIELD_BORDER_RECT_HEIGHT);
+ }
+
+ this.size_.height = totalHeight;
this.size_.width = totalWidth;
+
+ this.positionTextElement_(xOffset, contentWidth);
+ this.positionBorderRect_();
};
+/**
+ * Position a field's text element after a size change. This handles both LTR
+ * and RTL positioning.
+ * @param {number} xOffset x offset to use when positioning the text element.
+ * @param {number} contentWidth The content width.
+ * @protected
+ */
+Blockly.Field.prototype.positionTextElement_ = function(xOffset, contentWidth) {
+ if (!this.textElement_) {
+ return;
+ }
+ var constants = this.constants_;
+ var halfHeight = this.size_.height / 2;
+
+ this.textElement_.setAttribute('x', this.sourceBlock_.RTL ?
+ this.size_.width - contentWidth - xOffset : xOffset);
+ this.textElement_.setAttribute('y', constants.FIELD_TEXT_BASELINE_CENTER ?
+ halfHeight : halfHeight - constants.FIELD_TEXT_HEIGHT / 2 +
+ constants.FIELD_TEXT_BASELINE);
+};
+
+/**
+ * Position a field's border rect after a size change.
+ * @protected
+ */
+Blockly.Field.prototype.positionBorderRect_ = function() {
+ if (!this.borderRect_) {
+ return;
+ }
+ this.borderRect_.setAttribute('width', this.size_.width);
+ this.borderRect_.setAttribute('height', this.size_.height);
+ this.borderRect_.setAttribute('rx',
+ this.constants_.FIELD_BORDER_RECT_RADIUS);
+ this.borderRect_.setAttribute('ry',
+ this.constants_.FIELD_BORDER_RECT_RADIUS);
+};
+
+
/**
* Returns the height and width of the field.
*
diff --git a/core/field_checkbox.js b/core/field_checkbox.js
index c770c0e47..be599c7d8 100644
--- a/core/field_checkbox.js
+++ b/core/field_checkbox.js
@@ -82,15 +82,6 @@ Blockly.FieldCheckbox.prototype.SERIALIZABLE = true;
*/
Blockly.FieldCheckbox.prototype.CURSOR = 'default';
-/**
- * Used to tell if the field needs to be rendered the next time the block is
- * rendered. Checkbox fields are statically sized, and only need to be
- * rendered at initialization.
- * @type {boolean}
- * @protected
- */
-Blockly.FieldCheckbox.prototype.isDirty_ = false;
-
/**
* Configure the field based on the given map of options.
* @param {!Object} config A map of options to configure the field based on.
@@ -108,19 +99,30 @@ Blockly.FieldCheckbox.prototype.configure_ = function(config) {
* @package
*/
Blockly.FieldCheckbox.prototype.initView = function() {
- this.size_.width = this.constants_.FIELD_CHECKBOX_DEFAULT_WIDTH;
Blockly.FieldCheckbox.superClass_.initView.call(this);
- this.textElement_.setAttribute('x', this.constants_.FIELD_CHECKBOX_X_OFFSET);
- this.textElement_.setAttribute('y', this.constants_.FIELD_CHECKBOX_Y_OFFSET);
- this.textElement_.removeAttribute('dominant-baseline');
- Blockly.utils.dom.addClass(this.textElement_, 'blocklyCheckbox');
-
- this.textContent_.nodeValue =
- this.checkChar_ || Blockly.FieldCheckbox.CHECK_CHAR;
+ Blockly.utils.dom.addClass(
+ /** @type {!SVGTextElement} **/ (this.textElement_), 'blocklyCheckbox');
this.textElement_.style.display = this.value_ ? 'block' : 'none';
};
+/**
+ * @override
+ */
+Blockly.FieldCheckbox.prototype.render_ = function() {
+ if (this.textContent_) {
+ this.textContent_.nodeValue = this.getDisplayText_();
+ }
+ this.updateSize_(this.constants_.FIELD_CHECKBOX_X_OFFSET);
+};
+
+/**
+ * @override
+ */
+Blockly.FieldCheckbox.prototype.getDisplayText_ = function() {
+ return this.checkChar_ || Blockly.FieldCheckbox.CHECK_CHAR;
+};
+
/**
* Set the character used for the check mark.
* @param {?string} character The character to use for the check mark, or
diff --git a/core/field_dropdown.js b/core/field_dropdown.js
index 00b8a06a4..b50340d60 100644
--- a/core/field_dropdown.js
+++ b/core/field_dropdown.js
@@ -564,10 +564,8 @@ Blockly.FieldDropdown.prototype.render_ = function() {
} else {
this.renderSelectedText_();
}
- if (this.borderRect_) {
- this.borderRect_.setAttribute('height', this.size_.height);
- this.borderRect_.setAttribute('width', this.size_.width);
- }
+
+ this.positionBorderRect_();
};
/**
@@ -588,14 +586,13 @@ Blockly.FieldDropdown.prototype.renderSelectedImage_ = function(imageJson) {
// Height and width include the border rect.
var hasBorder = !!this.borderRect_;
- this.size_.height = Math.max(
+ var height = Math.max(
hasBorder ? this.constants_.FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
imageHeight + Blockly.FieldDropdown.IMAGE_Y_PADDING);
- var halfHeight = this.size_.height / 2;
var xPadding = hasBorder ? this.constants_.FIELD_BORDER_RECT_X_PADDING : 0;
var arrowWidth = 0;
if (this.svgArrow_) {
- arrowWidth = this.positionSVGArrow_(imageWidth + xPadding, halfHeight -
+ arrowWidth = this.positionSVGArrow_(imageWidth + xPadding, height / 2 -
this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2);
} else {
arrowWidth = Blockly.utils.dom.getFastTextWidth(
@@ -605,19 +602,20 @@ Blockly.FieldDropdown.prototype.renderSelectedImage_ = function(imageJson) {
this.constants_.FIELD_TEXT_FONTFAMILY);
}
this.size_.width = imageWidth + arrowWidth + xPadding * 2;
+ this.size_.height = height;
+ var arrowX = 0;
if (this.sourceBlock_.RTL) {
var imageX = xPadding + arrowWidth;
- var arrowX = xPadding - 1;
this.imageElement_.setAttribute('x', imageX);
- this.textElement_.setAttribute('x', arrowX);
} else {
- var arrowX = imageWidth + arrowWidth + xPadding + 1;
+ arrowX = imageWidth + arrowWidth;
this.textElement_.setAttribute('text-anchor', 'end');
- this.textElement_.setAttribute('x', arrowX);
this.imageElement_.setAttribute('x', xPadding);
}
- this.imageElement_.setAttribute('y', halfHeight - imageHeight / 2);
+ this.imageElement_.setAttribute('y', height / 2 - imageHeight / 2);
+
+ this.positionTextElement_(arrowX + xPadding, imageWidth + arrowWidth);
};
/**
@@ -633,10 +631,9 @@ Blockly.FieldDropdown.prototype.renderSelectedText_ = function() {
// Height and width include the border rect.
var hasBorder = !!this.borderRect_;
- this.size_.height = Math.max(
+ var height = Math.max(
hasBorder ? this.constants_.FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
this.constants_.FIELD_TEXT_HEIGHT);
- var halfHeight = this.size_.height / 2;
var textWidth = Blockly.utils.dom.getFastTextWidth(this.textElement_,
this.constants_.FIELD_TEXT_FONTSIZE,
this.constants_.FIELD_TEXT_FONTWEIGHT,
@@ -644,20 +641,13 @@ Blockly.FieldDropdown.prototype.renderSelectedText_ = function() {
var xPadding = hasBorder ? this.constants_.FIELD_BORDER_RECT_X_PADDING : 0;
var arrowWidth = 0;
if (this.svgArrow_) {
- arrowWidth = this.positionSVGArrow_(textWidth + xPadding, halfHeight -
+ arrowWidth = this.positionSVGArrow_(textWidth + xPadding, height / 2 -
this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2);
}
this.size_.width = textWidth + arrowWidth + xPadding * 2;
+ this.size_.height = height;
- this.textElement_.setAttribute('x', this.sourceBlock_.RTL ?
- this.size_.width - textWidth - xPadding : xPadding);
- this.textElement_.setAttribute('y', halfHeight);
- if (!this.constants_.FIELD_TEXT_BASELINE_CENTER) {
- this.textElement_.setAttribute('dy',
- this.constants_.FIELD_TEXT_BASELINE_Y -
- this.constants_.FIELD_TEXT_HEIGHT / 2 +
- this.constants_.FIELD_TEXT_Y_OFFSET);
- }
+ this.positionTextElement_(xPadding, textWidth);
};
/**
diff --git a/core/field_image.js b/core/field_image.js
index 7b8215103..32af8adca 100644
--- a/core/field_image.js
+++ b/core/field_image.js
@@ -186,6 +186,13 @@ Blockly.FieldImage.prototype.initView = function() {
}
};
+/**
+ * @override
+ */
+Blockly.FieldImage.prototype.updateSize_ = function() {
+ // NOP
+};
+
/**
* Ensure that the input value (the source URL) is a string.
* @param {*=} opt_newValue The input value.
diff --git a/core/field_multilineinput.js b/core/field_multilineinput.js
index 0b641e6ea..5cb9b8e2b 100644
--- a/core/field_multilineinput.js
+++ b/core/field_multilineinput.js
@@ -60,13 +60,6 @@ Blockly.utils.object.inherits(Blockly.FieldMultilineInput,
Blockly.FieldTextInput);
-/**
- * The default height of a single line of text.
- * @type {number}
- * @const
- */
-Blockly.FieldMultilineInput.LINE_HEIGHT = 20;
-
/**
* Construct a FieldMultilineInput from a JSON arg object,
* dereferencing any string table references.
@@ -143,14 +136,16 @@ Blockly.FieldMultilineInput.prototype.render_ = function() {
var lines = this.getDisplayText_().split('\n');
var y = 0;
for (var i = 0; i < lines.length; i++) {
+ var lineHeight = this.constants_.FIELD_TEXT_HEIGHT +
+ this.constants_.FIELD_BORDER_RECT_Y_PADDING;
var span = Blockly.utils.dom.createSvgElement('text', {
'class': 'blocklyText blocklyMultilineText',
x: this.constants_.FIELD_BORDER_RECT_X_PADDING,
y: y + this.constants_.FIELD_BORDER_RECT_Y_PADDING,
- dy: Blockly.FieldMultilineInput.LINE_HEIGHT / 2
+ dy: this.constants_.FIELD_TEXT_BASELINE
}, this.textGroup_);
span.appendChild(document.createTextNode(lines[i]));
- y += Blockly.FieldMultilineInput.LINE_HEIGHT;
+ y += lineHeight;
}
this.updateSize_();
@@ -191,34 +186,19 @@ Blockly.FieldMultilineInput.prototype.updateSize_ = function() {
if (textWidth > totalWidth) {
totalWidth = textWidth;
}
- totalHeight += Blockly.FieldMultilineInput.LINE_HEIGHT;
+ totalHeight += this.constants_.FIELD_TEXT_HEIGHT +
+ (i > 0 ? this.constants_.FIELD_BORDER_RECT_Y_PADDING : 0);
}
if (this.borderRect_) {
+ totalHeight += this.constants_.FIELD_BORDER_RECT_Y_PADDING * 2;
totalWidth += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
this.borderRect_.setAttribute('width', totalWidth);
this.borderRect_.setAttribute('height', totalHeight);
}
this.size_.width = totalWidth;
this.size_.height = totalHeight;
-};
-/**
- * Resize the editor to fit the text.
- * @protected
- */
-Blockly.FieldMultilineInput.prototype.resizeEditor_ = function() {
- var div = Blockly.WidgetDiv.DIV;
- var bBox = this.getScaledBBox();
- div.style.width = bBox.right - bBox.left + 'px';
- div.style.height = bBox.bottom - bBox.top + 'px';
-
- // In RTL mode block fields and LTR input fields the left edge moves,
- // whereas the right edge is fixed. Reposition the editor.
- var x = this.sourceBlock_.RTL ? bBox.right - div.offsetWidth : bBox.left;
- var xy = new Blockly.utils.Coordinate(x, bBox.top);
-
- div.style.left = xy.x + 'px';
- div.style.top = xy.y + 'px';
+ this.positionBorderRect_();
};
/**
@@ -230,7 +210,8 @@ Blockly.FieldMultilineInput.prototype.widgetCreate_ = function() {
var div = Blockly.WidgetDiv.DIV;
var scale = this.workspace_.scale;
- var htmlInput = /** @type {HTMLTextAreaElement} */ (document.createElement('textarea'));
+ var htmlInput =
+ /** @type {HTMLTextAreaElement} */ (document.createElement('textarea'));
htmlInput.className = 'blocklyHtmlInput blocklyHtmlTextAreaInput';
htmlInput.setAttribute('spellcheck', this.spellcheck_);
var fontSize = (this.constants_.FIELD_TEXT_FONTSIZE * scale) + 'pt';
@@ -238,11 +219,13 @@ Blockly.FieldMultilineInput.prototype.widgetCreate_ = function() {
htmlInput.style.fontSize = fontSize;
var borderRadius = (Blockly.FieldTextInput.BORDERRADIUS * scale) + 'px';
htmlInput.style.borderRadius = borderRadius;
- var padding = this.constants_.FIELD_BORDER_RECT_X_PADDING * scale;
- htmlInput.style.paddingLeft = padding + 'px';
- htmlInput.style.width = 'calc(100% - ' + padding + 'px)';
- htmlInput.style.lineHeight =
- (Blockly.FieldMultilineInput.LINE_HEIGHT * scale) + 'px';
+ var paddingX = this.constants_.FIELD_BORDER_RECT_X_PADDING * scale;
+ var paddingY = this.constants_.FIELD_BORDER_RECT_Y_PADDING * scale / 2;
+ htmlInput.style.padding = paddingY + 'px ' + paddingX + 'px ' + paddingY +
+ 'px ' + paddingX + 'px';
+ var lineHeight = this.constants_.FIELD_TEXT_HEIGHT +
+ this.constants_.FIELD_BORDER_RECT_Y_PADDING;
+ htmlInput.style.lineHeight = (lineHeight * scale) + 'px';
div.appendChild(htmlInput);
diff --git a/core/flyout_base.js b/core/flyout_base.js
index 2fa4207fe..afd197fc8 100644
--- a/core/flyout_base.js
+++ b/core/flyout_base.js
@@ -46,6 +46,8 @@ Blockly.Flyout = function(workspaceOptions) {
*/
this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions);
this.workspace_.isFlyout = true;
+ // Keep the workspace visibility consistent with the flyout's visibility.
+ this.workspace_.setVisible(this.isVisible_);
/**
* Is RTL vs LTR.
diff --git a/core/flyout_button.js b/core/flyout_button.js
index b5a2a5452..51173c917 100644
--- a/core/flyout_button.js
+++ b/core/flyout_button.js
@@ -86,9 +86,14 @@ Blockly.FlyoutButton = function(workspace, targetWorkspace, xml, isLabel) {
};
/**
- * The margin around the text in the button.
+ * The horizontal margin around the text in the button.
*/
-Blockly.FlyoutButton.MARGIN = 5;
+Blockly.FlyoutButton.MARGIN_X = 5;
+
+/**
+ * The vertical margin around the text in the button.
+ */
+Blockly.FlyoutButton.MARGIN_Y = 2;
/**
* The width of the button's rect.
@@ -153,11 +158,18 @@ Blockly.FlyoutButton.prototype.createDom = function() {
'flyoutForegroundColour', 'fill');
}
- this.width = Blockly.utils.dom.getTextWidth(svgText);
- this.height = 20; // Can't compute it :(
-
+ var fontSize = Blockly.utils.style.getComputedStyle(svgText, 'fontSize');
+ var fontWeight = Blockly.utils.style.getComputedStyle(svgText, 'fontWeight');
+ var fontFamily = Blockly.utils.style.getComputedStyle(svgText, 'fontFamily');
+ this.width = Blockly.utils.dom.getFastTextWidthWithSizeString(svgText,
+ fontSize, fontWeight, fontFamily);
+ var fontMetrics = Blockly.utils.dom.measureFontMetrics(text, fontSize,
+ fontWeight, fontFamily);
+ this.height = fontMetrics.height;
+
if (!this.isLabel_) {
- this.width += 2 * Blockly.FlyoutButton.MARGIN;
+ this.width += 2 * Blockly.FlyoutButton.MARGIN_X;
+ this.height += 2 * Blockly.FlyoutButton.MARGIN_Y;
shadow.setAttribute('width', this.width);
shadow.setAttribute('height', this.height);
}
@@ -165,7 +177,8 @@ Blockly.FlyoutButton.prototype.createDom = function() {
rect.setAttribute('height', this.height);
svgText.setAttribute('x', this.width / 2);
- svgText.setAttribute('y', this.height - Blockly.FlyoutButton.MARGIN);
+ svgText.setAttribute('y', this.height / 2 - fontMetrics.height / 2 +
+ fontMetrics.baseline);
this.updateTransform_();
diff --git a/core/renderers/common/block_rendering.js b/core/renderers/common/block_rendering.js
index d92218196..5c2a091f0 100644
--- a/core/renderers/common/block_rendering.js
+++ b/core/renderers/common/block_rendering.js
@@ -79,16 +79,17 @@ Blockly.blockRendering.stopDebugger = function() {
/**
* Initialize anything needed for rendering (constants, etc).
* @param {!string} name Name of the renderer to initialize.
+ * @param {!Blockly.Theme} theme The workspace theme object.
* @return {!Blockly.blockRendering.Renderer} The new instance of a renderer.
* Already initialized.
* @package
*/
-Blockly.blockRendering.init = function(name) {
+Blockly.blockRendering.init = function(name, theme) {
if (!Blockly.blockRendering.rendererMap_[name]) {
throw Error('Renderer not registered: ', name);
}
var renderer = (/** @type {!Blockly.blockRendering.Renderer} */ (
new Blockly.blockRendering.rendererMap_[name](name)));
- renderer.init();
+ renderer.init(theme);
return renderer;
};
diff --git a/core/renderers/common/constants.js b/core/renderers/common/constants.js
index 46e4c66a4..727b601fd 100644
--- a/core/renderers/common/constants.js
+++ b/core/renderers/common/constants.js
@@ -26,6 +26,20 @@ goog.require('Blockly.utils.userAgent');
*/
Blockly.blockRendering.ConstantProvider = function() {
+ /**
+ * A placeholder value for number constants that are dynamically set.
+ * @type {number}
+ * @protected
+ */
+ this.DYNAMICALLY_SET_ = -1;
+
+ /**
+ * A placeholder value for string constants that are dynamically set.
+ * @type {string}
+ * @protected
+ */
+ this.DYNAMICALLY_SET_STRING_ = '';
+
/**
* The size of an empty spacer.
* @type {number}
@@ -231,28 +245,39 @@ Blockly.blockRendering.ConstantProvider = function() {
this.JAGGED_TEETH_WIDTH = 6;
/**
- * Point size of text.
+ * Point size of text. This constant is dynamically set in
+ * ``setFontConstants_`` to the size of the font used by the renderer/theme.
* @type {number}
*/
- this.FIELD_TEXT_FONTSIZE = 11;
+ this.FIELD_TEXT_FONTSIZE = this.DYNAMICALLY_SET_;
/**
- * Height of text.
+ * Height of text. This constant is dynamically set in ``setFontConstants_``
+ * to be the height of the text based on the font used.
* @type {number}
*/
- this.FIELD_TEXT_HEIGHT = 16;
+ this.FIELD_TEXT_HEIGHT = this.DYNAMICALLY_SET_;
/**
- * Text font weight.
- * @type {string}
+ * Text baseline. This constant is dynamically set in ``setFontConstants_``
+ * to be the baseline of the text based on the font used.
+ * @type {number}
*/
- this.FIELD_TEXT_FONTWEIGHT = 'normal';
+ this.FIELD_TEXT_BASELINE = this.DYNAMICALLY_SET_;
/**
- * Text font family.
+ * Text font weight. This constant is dynamically set in
+ * ``setFontConstants_`` to the weight of the font used by the renderer/theme.
* @type {string}
*/
- this.FIELD_TEXT_FONTFAMILY = 'sans-serif';
+ this.FIELD_TEXT_FONTWEIGHT = this.DYNAMICALLY_SET_STRING_;
+
+ /**
+ * Text font family. This constant is dynamically set in
+ * ``setFontConstants_`` to the family of the font used by the renderer/theme.
+ * @type {string}
+ */
+ this.FIELD_TEXT_FONTFAMILY = this.DYNAMICALLY_SET_STRING_;
/**
* A field's border rect corner radius.
@@ -285,19 +310,6 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.FIELD_BORDER_RECT_COLOUR = '#fff';
- /**
- * Field text baseline.
- * This is only used if `FIELD_TEXT_BASELINE_CENTER` is false.
- * @type {number}
- */
- this.FIELD_TEXT_BASELINE_Y = Blockly.utils.userAgent.GECKO ? 12 : 13.09;
-
- /**
- * An text offset adjusting the Y position of text after positioning.
- * @type {number}
- */
- this.FIELD_TEXT_Y_OFFSET = 0;
-
/**
* A field's text element's dominant baseline.
* @type {boolean}
@@ -392,18 +404,6 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.FIELD_CHECKBOX_X_OFFSET = this.FIELD_BORDER_RECT_X_PADDING - 3;
- /**
- * A checkbox field's Y offset.
- * @type {number}
- */
- this.FIELD_CHECKBOX_Y_OFFSET = 14;
-
- /**
- * A checkbox field's default width.
- * @type {number}
- */
- this.FIELD_CHECKBOX_DEFAULT_WIDTH = 15;
-
/**
* A random identifier used to ensure a unique ID is used for each
* filter/pattern for the case of multiple Blockly instances on a page.
@@ -440,6 +440,13 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.disabledPattern_ = null;
+ /**
+ * The
@@ -631,6 +647,15 @@ var spaghettiXml = [
+
+ Rendering:
+
+
+