avm2: Implement StyleSheet.transform()
This commit is contained in:
parent
7e1bc84bdf
commit
24b01b8f89
|
@ -1,6 +1,4 @@
|
|||
package flash.text {
|
||||
import __ruffle__.stub_method;
|
||||
|
||||
public dynamic class StyleSheet {
|
||||
// Shallow copies of the original style objects. Not used by Ruffle itself, just for getStyle()
|
||||
private var _styles: Object = {};
|
||||
|
@ -40,8 +38,82 @@ package flash.text {
|
|||
}
|
||||
|
||||
public function transform(formatObject:Object):TextFormat {
|
||||
stub_method("flash.text.StyleSheet", "transform");
|
||||
return null;
|
||||
if (!formatObject) {
|
||||
return null;
|
||||
}
|
||||
var result = new TextFormat();
|
||||
|
||||
if (formatObject.color) {
|
||||
result.color = innerParseColor(formatObject.color);
|
||||
}
|
||||
|
||||
if (formatObject.display) {
|
||||
result.display = formatObject.display;
|
||||
}
|
||||
|
||||
if (formatObject.fontFamily) {
|
||||
result.font = innerParseFontFamily(formatObject.fontFamily);
|
||||
}
|
||||
|
||||
if (formatObject.fontSize) {
|
||||
var size = parseInt(formatObject.fontSize);
|
||||
if (size > 0) {
|
||||
result.size = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (formatObject.fontStyle == "italic") {
|
||||
result.italic = true;
|
||||
} else if (formatObject.fontStyle == "normal") {
|
||||
result.italic = false;
|
||||
}
|
||||
|
||||
if (formatObject.fontWeight == "bold") {
|
||||
result.bold = true;
|
||||
} else if (formatObject.fontWeight == "normal") {
|
||||
result.bold = false;
|
||||
}
|
||||
|
||||
if (formatObject.kerning == "true") {
|
||||
result.kerning = true;
|
||||
} else if (formatObject.kerning == "false") {
|
||||
result.kerning = false;
|
||||
} else {
|
||||
// Seems to always set, not just if defined
|
||||
result.kerning = parseInt(formatObject.kerning);
|
||||
}
|
||||
|
||||
if (formatObject.leading) {
|
||||
result.leading = parseInt(formatObject.leading);
|
||||
}
|
||||
|
||||
if (formatObject.letterSpacing) {
|
||||
result.letterSpacing = parseFloat(formatObject.letterSpacing);
|
||||
}
|
||||
|
||||
if (formatObject.marginLeft) {
|
||||
result.leftMargin = parseFloat(formatObject.marginLeft);
|
||||
}
|
||||
|
||||
if (formatObject.marginRight) {
|
||||
result.rightMargin = parseFloat(formatObject.marginRight);
|
||||
}
|
||||
|
||||
if (formatObject.textAlign) {
|
||||
result.align = formatObject.textAlign;
|
||||
}
|
||||
|
||||
if (formatObject.textDecoration == "underline") {
|
||||
result.underline = true;
|
||||
} else if (formatObject.textDecoration == "none") {
|
||||
result.underline = false;
|
||||
}
|
||||
|
||||
if (formatObject.textIndent) {
|
||||
result.indent = parseInt(formatObject.textIndent);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private function _createShallowCopy(original: *): Object {
|
||||
|
@ -54,5 +126,7 @@ package flash.text {
|
|||
|
||||
// Avoid doing potentially expensive string parsing in AS :D
|
||||
private native function innerParseCss(css: String): Object;
|
||||
private native function innerParseColor(color: String): Number;
|
||||
private native function innerParseFontFamily(fontFamily: String): String;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::avm2::parameters::ParametersExt;
|
|||
use crate::avm2::{Activation, Error, Object, TObject, Value};
|
||||
use crate::html::CssStream;
|
||||
use crate::string::AvmString;
|
||||
use ruffle_wstr::{WStr, WString};
|
||||
|
||||
pub fn inner_parse_css<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
|
@ -39,3 +40,69 @@ pub fn inner_parse_css<'gc>(
|
|||
|
||||
Ok(Value::Object(result))
|
||||
}
|
||||
|
||||
pub fn inner_parse_color<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let input = args.get_string(activation, 0)?;
|
||||
|
||||
if let Some(stripped) = input.strip_prefix(WStr::from_units(b"#")) {
|
||||
if stripped.len() <= 6 {
|
||||
if let Ok(number) = u32::from_str_radix(&stripped.to_string(), 16) {
|
||||
return Ok(number.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0.into())
|
||||
}
|
||||
|
||||
pub fn inner_parse_font_family<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let input = args.get_string(activation, 0)?;
|
||||
let mut result = WString::new();
|
||||
|
||||
let mut pos = 0;
|
||||
while pos < input.len() {
|
||||
// Skip whitespace
|
||||
while input.get(pos) == Some(' ' as u16) {
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
// Find the whole value
|
||||
let start = pos;
|
||||
while input.get(pos) != Some(',' as u16) && pos < input.len() {
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
let mut value = &input[start..pos];
|
||||
|
||||
if pos < input.len() {
|
||||
pos += 1; // move past the comma
|
||||
}
|
||||
|
||||
// Transform some names
|
||||
if value == WStr::from_units(b"mono") {
|
||||
value = WStr::from_units(b"_typewriter");
|
||||
} else if value == WStr::from_units(b"sans-serif") {
|
||||
value = WStr::from_units(b"_sans");
|
||||
} else if value == WStr::from_units(b"serif") {
|
||||
value = WStr::from_units(b"_serif");
|
||||
}
|
||||
|
||||
// Add it to the result (without any extra space)
|
||||
if !value.is_empty() {
|
||||
if !result.is_empty() {
|
||||
result.push_char(',');
|
||||
}
|
||||
result.push_str(value);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::String(AvmString::new(activation.gc(), result)))
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ use crate::avm2::object::{ArrayObject, Object, TObject};
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::ecma_conversions::round_to_even;
|
||||
use crate::html::TextDisplay;
|
||||
use crate::string::{AvmString, WStr};
|
||||
use crate::{avm2_stub_getter, avm2_stub_setter};
|
||||
|
||||
pub use crate::avm2::object::textformat_allocator as text_format_allocator;
|
||||
|
||||
|
@ -185,20 +185,51 @@ pub fn set_color<'gc>(
|
|||
}
|
||||
|
||||
pub fn get_display<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
avm2_stub_getter!(activation, "flash.text.TextFormat", "display");
|
||||
Ok("block".into())
|
||||
if let Some(text_format) = this.as_text_format() {
|
||||
return Ok(text_format
|
||||
.display
|
||||
.as_ref()
|
||||
.map_or(Value::Null, |display| match display {
|
||||
TextDisplay::Block => "block".into(),
|
||||
TextDisplay::Inline => "inline".into(),
|
||||
TextDisplay::None => "none".into(),
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn set_display<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
avm2_stub_setter!(activation, "flash.text.TextFormat", "display");
|
||||
if let Some(mut text_format) = this.as_text_format_mut() {
|
||||
let value = args.get(0).unwrap_or(&Value::Undefined);
|
||||
let value = match value {
|
||||
Value::Undefined | Value::Null => {
|
||||
text_format.display = None;
|
||||
return Ok(Value::Undefined);
|
||||
}
|
||||
value => value.coerce_to_string(activation)?,
|
||||
};
|
||||
|
||||
text_format.display = if value == WStr::from_units(b"block") {
|
||||
Some(TextDisplay::Block)
|
||||
} else if value == WStr::from_units(b"inline") {
|
||||
Some(TextDisplay::Inline)
|
||||
} else if value == WStr::from_units(b"none") {
|
||||
Some(TextDisplay::None)
|
||||
} else {
|
||||
// No error message for this, silently set it to None/null
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::avm2::object::script_object::ScriptObjectData;
|
|||
use crate::avm2::object::{ClassObject, Object, ObjectPtr, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::html::TextFormat;
|
||||
use crate::html::{TextDisplay, TextFormat};
|
||||
use core::fmt;
|
||||
use gc_arena::barrier::unlock;
|
||||
use gc_arena::lock::RefLock;
|
||||
|
@ -21,7 +21,10 @@ pub fn textformat_allocator<'gc>(
|
|||
activation.gc(),
|
||||
TextFormatObjectData {
|
||||
base: RefLock::new(ScriptObjectData::new(class)),
|
||||
text_format: Default::default(),
|
||||
text_format: RefCell::new(TextFormat {
|
||||
display: Some(TextDisplay::Block),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
))
|
||||
.into())
|
||||
|
|
|
@ -9,7 +9,7 @@ pub use dimensions::BoxBounds;
|
|||
pub use dimensions::Position;
|
||||
pub use layout::{LayoutBox, LayoutContent, LayoutMetrics};
|
||||
pub use stylesheet::CssStream;
|
||||
pub use text_format::{FormatSpans, TextFormat, TextSpan};
|
||||
pub use text_format::{FormatSpans, TextDisplay, TextFormat, TextSpan};
|
||||
|
||||
mod stylesheet;
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -101,6 +101,14 @@ fn process_html_entity(src: &WStr) -> Option<WString> {
|
|||
Some(result_str)
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum TextDisplay {
|
||||
#[default]
|
||||
Block,
|
||||
Inline,
|
||||
None,
|
||||
}
|
||||
|
||||
/// A set of text formatting options to be applied to some part, or the whole
|
||||
/// of, a given text field.
|
||||
///
|
||||
|
@ -131,6 +139,7 @@ pub struct TextFormat {
|
|||
pub bullet: Option<bool>,
|
||||
pub url: Option<WString>,
|
||||
pub target: Option<WString>,
|
||||
pub display: Option<TextDisplay>,
|
||||
}
|
||||
|
||||
impl TextFormat {
|
||||
|
@ -191,6 +200,7 @@ impl TextFormat {
|
|||
// TODO: These are probably empty strings by default
|
||||
url: Some(WString::new()),
|
||||
target: Some(WString::new()),
|
||||
display: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,6 +294,11 @@ impl TextFormat {
|
|||
} else {
|
||||
None
|
||||
},
|
||||
display: if self.display == rhs.display {
|
||||
self.display
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,6 +326,7 @@ impl TextFormat {
|
|||
bullet: self.bullet.or(rhs.bullet),
|
||||
url: self.url.or(rhs.url),
|
||||
target: self.target.or(rhs.target),
|
||||
display: self.display.or(rhs.display),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -542,6 +558,7 @@ impl TextSpan {
|
|||
bullet: Some(self.bullet),
|
||||
url: Some(self.url.clone()),
|
||||
target: Some(self.target.clone()),
|
||||
display: None, // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
package {
|
||||
import flash.display.MovieClip;
|
||||
import flash.text.StyleSheet;
|
||||
import flash.text.TextFormat;
|
||||
|
||||
|
||||
public class Test extends MovieClip {
|
||||
// this is only relevant properties, some can't be set through css
|
||||
var textFormatProperties = [
|
||||
"align",
|
||||
"bold",
|
||||
"color",
|
||||
"font",
|
||||
"indent",
|
||||
"italic",
|
||||
"kerning",
|
||||
"leading",
|
||||
"leftMargin",
|
||||
"letterSpacing",
|
||||
"rightMargin",
|
||||
"size",
|
||||
"underline",
|
||||
"display" // undocumented!
|
||||
];
|
||||
|
||||
var interestingNumbers = [
|
||||
"",
|
||||
"50",
|
||||
"50.5 px",
|
||||
"50 pt",
|
||||
"50xx",
|
||||
" 50",
|
||||
"x50",
|
||||
"0",
|
||||
"-50",
|
||||
"09"
|
||||
];
|
||||
|
||||
public function Test() {
|
||||
var styleSheet: StyleSheet = new StyleSheet();
|
||||
|
||||
test("Empty", styleSheet, {});
|
||||
test("Null", styleSheet, null);
|
||||
test("Undefined", styleSheet, undefined);
|
||||
test("Number", styleSheet, 5);
|
||||
|
||||
testSingleProperty("Color", styleSheet, "color", "color", [
|
||||
"red",
|
||||
"",
|
||||
"123",
|
||||
"#",
|
||||
"#1",
|
||||
"#12",
|
||||
"#123",
|
||||
"#1234",
|
||||
"#12345",
|
||||
"#123456",
|
||||
"#1234567",
|
||||
"#red"
|
||||
]);
|
||||
|
||||
testSingleProperty("Display", styleSheet, "display", "display", [
|
||||
"inline",
|
||||
"block",
|
||||
"none",
|
||||
"invalid",
|
||||
""
|
||||
]);
|
||||
|
||||
testSingleProperty("Font Family", styleSheet, "fontFamily", "font", [
|
||||
"",
|
||||
"mono, sans-serif, serif",
|
||||
"a b c, d e f , , g h",
|
||||
"Times New Roman"
|
||||
]);
|
||||
|
||||
testSingleProperty("Font Size", styleSheet, "fontSize", "size", interestingNumbers);
|
||||
|
||||
testSingleProperty("Font Style", styleSheet, "fontStyle", "italic", [
|
||||
"",
|
||||
"bold",
|
||||
"italic",
|
||||
"normal"
|
||||
]);
|
||||
|
||||
testSingleProperty("Font Weight", styleSheet, "fontWeight", "bold", [
|
||||
"",
|
||||
"bold",
|
||||
"italic",
|
||||
"normal"
|
||||
]);
|
||||
|
||||
testSingleProperty("Kerning", styleSheet, "kerning", "kerning", [
|
||||
"",
|
||||
"true",
|
||||
"false",
|
||||
"lots",
|
||||
"50",
|
||||
"0"
|
||||
]);
|
||||
|
||||
testSingleProperty("Leading", styleSheet, "leading", "leading", interestingNumbers);
|
||||
|
||||
testSingleProperty("Letter Spacing", styleSheet, "letterSpacing", "letterSpacing", interestingNumbers);
|
||||
|
||||
testSingleProperty("Margin Left", styleSheet, "marginLeft", "leftMargin", interestingNumbers);
|
||||
|
||||
testSingleProperty("Margin Right", styleSheet, "marginRight", "rightMargin", interestingNumbers);
|
||||
|
||||
testSingleProperty("Text Align", styleSheet, "textAlign", "align", [
|
||||
"",
|
||||
"invalid",
|
||||
"left",
|
||||
"right",
|
||||
"justify",
|
||||
"center"
|
||||
]);
|
||||
|
||||
testSingleProperty("Text Decoration", styleSheet, "textDecoration", "underline", [
|
||||
"",
|
||||
"bold",
|
||||
"none",
|
||||
"underline"
|
||||
]);
|
||||
|
||||
testSingleProperty("Text Indent", styleSheet, "textIndent", "indent", interestingNumbers);
|
||||
|
||||
test("Every property is valid", styleSheet, {
|
||||
"color": "#FF0000",
|
||||
"display": "block",
|
||||
"fontFamily": "sans-serif",
|
||||
"fontSize": "75px",
|
||||
"fontStyle": "italic",
|
||||
"fontWeight": "bold",
|
||||
"kerning": "true",
|
||||
"leading": "5",
|
||||
"letterSpacing": "0",
|
||||
"marginLeft": "0",
|
||||
"marginRight": "0",
|
||||
"textAlign": "justify",
|
||||
"textDecoration": "underline",
|
||||
"textIndent": "0"
|
||||
});
|
||||
}
|
||||
|
||||
function test(name: String, styleSheet: StyleSheet, style: *) {
|
||||
trace("/// " + name);
|
||||
dumpStyle("style", style);
|
||||
trace("");
|
||||
try {
|
||||
dumpFormat("format", styleSheet.transform(style));
|
||||
} catch (e) {
|
||||
// [NA] The exact error message deviates at time of writing because of int vs Number
|
||||
trace("! " + e.errorID);
|
||||
}
|
||||
trace("");
|
||||
}
|
||||
|
||||
function testSingleProperty(name: String, styleSheet: StyleSheet, property: String, transformProperty: String, values: Array) {
|
||||
trace("/// " + name);
|
||||
|
||||
for each (var value in values) {
|
||||
trace("// styleSheet.transform({" + escapeString(property) + ": " + escapeString(value) + "})");
|
||||
try {
|
||||
var input = {};
|
||||
input[property] = value;
|
||||
var result = styleSheet.transform(input);
|
||||
dumpValue(transformProperty, result[transformProperty]);
|
||||
} catch (e) {
|
||||
trace("! " + e);
|
||||
}
|
||||
}
|
||||
|
||||
trace("");
|
||||
}
|
||||
|
||||
function dumpStyle(name: String, style: *) {
|
||||
if (style === undefined) {
|
||||
trace( name + " = undefined");
|
||||
} else if (style === null) {
|
||||
trace( name + " = null");
|
||||
} else {
|
||||
var first = true;
|
||||
|
||||
// Sort is not deterministic
|
||||
var sortedKeys = [];
|
||||
for (var key in style) {
|
||||
sortedKeys.push(key);
|
||||
}
|
||||
sortedKeys.sort();
|
||||
|
||||
for each (var key in sortedKeys) {
|
||||
if (first) {
|
||||
first = false;
|
||||
trace(name + " = {");
|
||||
}
|
||||
dumpValue(" " + escapeString(key), style[key]);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
trace(name + " = {}");
|
||||
} else {
|
||||
trace("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dumpFormat(name: String, format: *) {
|
||||
if (format === undefined) {
|
||||
trace( name + " = undefined");
|
||||
} else if (format === null) {
|
||||
trace( name + " = null");
|
||||
} else {
|
||||
var first = true;
|
||||
|
||||
for each (var key in textFormatProperties) {
|
||||
if (first) {
|
||||
first = false;
|
||||
trace(name + " = {");
|
||||
}
|
||||
dumpValue(" " + escapeString(key), format[key]);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
trace(name + " = {}");
|
||||
} else {
|
||||
trace("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dumpValue(name: String, value: *) {
|
||||
if (value === undefined) {
|
||||
return;
|
||||
} else if (value === null) {
|
||||
trace(name + " = null");
|
||||
} else if (value is Number) {
|
||||
trace(name + " = number " + value);
|
||||
} else if (value is String) {
|
||||
trace(name + " = string " + escapeString(value));
|
||||
} else if (value is Boolean) {
|
||||
trace(name + " = boolean " + value);
|
||||
} else if (value is Object) {
|
||||
trace(name + " = object " + value);
|
||||
} else {
|
||||
trace(name + " = unknown " + value);
|
||||
}
|
||||
}
|
||||
|
||||
function escapeString(input: String): String {
|
||||
var output:String = "\"";
|
||||
for (var i:int = 0; i < input.length; i++) {
|
||||
var char:String = input.charAt(i);
|
||||
switch (char) {
|
||||
case "\\":
|
||||
output += "\\\\";
|
||||
break;
|
||||
case "\"":
|
||||
output += "\\\"";
|
||||
break;
|
||||
case "\n":
|
||||
output += "\\n";
|
||||
break;
|
||||
case "\r":
|
||||
output += "\\r";
|
||||
break;
|
||||
case "\t":
|
||||
output += "\\t";
|
||||
break;
|
||||
default:
|
||||
output += char;
|
||||
}
|
||||
}
|
||||
return output + "\"";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
/// Empty
|
||||
style = {}
|
||||
|
||||
format = {
|
||||
"align" = null
|
||||
"bold" = null
|
||||
"color" = null
|
||||
"font" = null
|
||||
"indent" = null
|
||||
"italic" = null
|
||||
"kerning" = boolean false
|
||||
"leading" = null
|
||||
"leftMargin" = null
|
||||
"letterSpacing" = null
|
||||
"rightMargin" = null
|
||||
"size" = null
|
||||
"underline" = null
|
||||
"display" = string "block"
|
||||
}
|
||||
|
||||
/// Null
|
||||
style = null
|
||||
|
||||
format = null
|
||||
|
||||
/// Undefined
|
||||
style = undefined
|
||||
|
||||
format = null
|
||||
|
||||
/// Number
|
||||
style = {}
|
||||
|
||||
! 1069
|
||||
|
||||
/// Color
|
||||
// styleSheet.transform({"color": "red"})
|
||||
color = number 0
|
||||
// styleSheet.transform({"color": ""})
|
||||
color = null
|
||||
// styleSheet.transform({"color": "123"})
|
||||
color = number 0
|
||||
// styleSheet.transform({"color": "#"})
|
||||
color = number 0
|
||||
// styleSheet.transform({"color": "#1"})
|
||||
color = number 1
|
||||
// styleSheet.transform({"color": "#12"})
|
||||
color = number 18
|
||||
// styleSheet.transform({"color": "#123"})
|
||||
color = number 291
|
||||
// styleSheet.transform({"color": "#1234"})
|
||||
color = number 4660
|
||||
// styleSheet.transform({"color": "#12345"})
|
||||
color = number 74565
|
||||
// styleSheet.transform({"color": "#123456"})
|
||||
color = number 1193046
|
||||
// styleSheet.transform({"color": "#1234567"})
|
||||
color = number 0
|
||||
// styleSheet.transform({"color": "#red"})
|
||||
color = number 0
|
||||
|
||||
/// Display
|
||||
// styleSheet.transform({"display": "inline"})
|
||||
display = string "inline"
|
||||
// styleSheet.transform({"display": "block"})
|
||||
display = string "block"
|
||||
// styleSheet.transform({"display": "none"})
|
||||
display = string "none"
|
||||
// styleSheet.transform({"display": "invalid"})
|
||||
display = null
|
||||
// styleSheet.transform({"display": ""})
|
||||
display = string "block"
|
||||
|
||||
/// Font Family
|
||||
// styleSheet.transform({"fontFamily": ""})
|
||||
font = null
|
||||
// styleSheet.transform({"fontFamily": "mono, sans-serif, serif"})
|
||||
font = string "_typewriter,_sans,_serif"
|
||||
// styleSheet.transform({"fontFamily": "a b c, d e f , , g h"})
|
||||
font = string "a b c,d e f ,g h"
|
||||
// styleSheet.transform({"fontFamily": "Times New Roman"})
|
||||
font = string "Times New Roman"
|
||||
|
||||
/// Font Size
|
||||
// styleSheet.transform({"fontSize": ""})
|
||||
size = null
|
||||
// styleSheet.transform({"fontSize": "50"})
|
||||
size = number 50
|
||||
// styleSheet.transform({"fontSize": "50.5 px"})
|
||||
size = number 50
|
||||
// styleSheet.transform({"fontSize": "50 pt"})
|
||||
size = number 50
|
||||
// styleSheet.transform({"fontSize": "50xx"})
|
||||
size = number 50
|
||||
// styleSheet.transform({"fontSize": " 50"})
|
||||
size = number 50
|
||||
// styleSheet.transform({"fontSize": "x50"})
|
||||
size = null
|
||||
// styleSheet.transform({"fontSize": "0"})
|
||||
size = null
|
||||
// styleSheet.transform({"fontSize": "-50"})
|
||||
size = null
|
||||
// styleSheet.transform({"fontSize": "09"})
|
||||
size = number 9
|
||||
|
||||
/// Font Style
|
||||
// styleSheet.transform({"fontStyle": ""})
|
||||
italic = null
|
||||
// styleSheet.transform({"fontStyle": "bold"})
|
||||
italic = null
|
||||
// styleSheet.transform({"fontStyle": "italic"})
|
||||
italic = boolean true
|
||||
// styleSheet.transform({"fontStyle": "normal"})
|
||||
italic = boolean false
|
||||
|
||||
/// Font Weight
|
||||
// styleSheet.transform({"fontWeight": ""})
|
||||
bold = null
|
||||
// styleSheet.transform({"fontWeight": "bold"})
|
||||
bold = boolean true
|
||||
// styleSheet.transform({"fontWeight": "italic"})
|
||||
bold = null
|
||||
// styleSheet.transform({"fontWeight": "normal"})
|
||||
bold = boolean false
|
||||
|
||||
/// Kerning
|
||||
// styleSheet.transform({"kerning": ""})
|
||||
kerning = boolean false
|
||||
// styleSheet.transform({"kerning": "true"})
|
||||
kerning = boolean true
|
||||
// styleSheet.transform({"kerning": "false"})
|
||||
kerning = boolean false
|
||||
// styleSheet.transform({"kerning": "lots"})
|
||||
kerning = boolean false
|
||||
// styleSheet.transform({"kerning": "50"})
|
||||
kerning = boolean true
|
||||
// styleSheet.transform({"kerning": "0"})
|
||||
kerning = boolean false
|
||||
|
||||
/// Leading
|
||||
// styleSheet.transform({"leading": ""})
|
||||
leading = null
|
||||
// styleSheet.transform({"leading": "50"})
|
||||
leading = number 50
|
||||
// styleSheet.transform({"leading": "50.5 px"})
|
||||
leading = number 50
|
||||
// styleSheet.transform({"leading": "50 pt"})
|
||||
leading = number 50
|
||||
// styleSheet.transform({"leading": "50xx"})
|
||||
leading = number 50
|
||||
// styleSheet.transform({"leading": " 50"})
|
||||
leading = number 50
|
||||
// styleSheet.transform({"leading": "x50"})
|
||||
leading = number -2147483648
|
||||
// styleSheet.transform({"leading": "0"})
|
||||
leading = number 0
|
||||
// styleSheet.transform({"leading": "-50"})
|
||||
leading = number -50
|
||||
// styleSheet.transform({"leading": "09"})
|
||||
leading = number 9
|
||||
|
||||
/// Letter Spacing
|
||||
// styleSheet.transform({"letterSpacing": ""})
|
||||
letterSpacing = null
|
||||
// styleSheet.transform({"letterSpacing": "50"})
|
||||
letterSpacing = number 50
|
||||
// styleSheet.transform({"letterSpacing": "50.5 px"})
|
||||
letterSpacing = number 50.5
|
||||
// styleSheet.transform({"letterSpacing": "50 pt"})
|
||||
letterSpacing = number 50
|
||||
// styleSheet.transform({"letterSpacing": "50xx"})
|
||||
letterSpacing = number 50
|
||||
// styleSheet.transform({"letterSpacing": " 50"})
|
||||
letterSpacing = number 50
|
||||
// styleSheet.transform({"letterSpacing": "x50"})
|
||||
letterSpacing = number NaN
|
||||
// styleSheet.transform({"letterSpacing": "0"})
|
||||
letterSpacing = number 0
|
||||
// styleSheet.transform({"letterSpacing": "-50"})
|
||||
letterSpacing = number -50
|
||||
// styleSheet.transform({"letterSpacing": "09"})
|
||||
letterSpacing = number 9
|
||||
|
||||
/// Margin Left
|
||||
// styleSheet.transform({"marginLeft": ""})
|
||||
leftMargin = null
|
||||
// styleSheet.transform({"marginLeft": "50"})
|
||||
leftMargin = number 50
|
||||
// styleSheet.transform({"marginLeft": "50.5 px"})
|
||||
leftMargin = number 50
|
||||
// styleSheet.transform({"marginLeft": "50 pt"})
|
||||
leftMargin = number 50
|
||||
// styleSheet.transform({"marginLeft": "50xx"})
|
||||
leftMargin = number 50
|
||||
// styleSheet.transform({"marginLeft": " 50"})
|
||||
leftMargin = number 50
|
||||
// styleSheet.transform({"marginLeft": "x50"})
|
||||
leftMargin = number -2147483648
|
||||
// styleSheet.transform({"marginLeft": "0"})
|
||||
leftMargin = number 0
|
||||
// styleSheet.transform({"marginLeft": "-50"})
|
||||
leftMargin = number -50
|
||||
// styleSheet.transform({"marginLeft": "09"})
|
||||
leftMargin = number 9
|
||||
|
||||
/// Margin Right
|
||||
// styleSheet.transform({"marginRight": ""})
|
||||
rightMargin = null
|
||||
// styleSheet.transform({"marginRight": "50"})
|
||||
rightMargin = number 50
|
||||
// styleSheet.transform({"marginRight": "50.5 px"})
|
||||
rightMargin = number 50
|
||||
// styleSheet.transform({"marginRight": "50 pt"})
|
||||
rightMargin = number 50
|
||||
// styleSheet.transform({"marginRight": "50xx"})
|
||||
rightMargin = number 50
|
||||
// styleSheet.transform({"marginRight": " 50"})
|
||||
rightMargin = number 50
|
||||
// styleSheet.transform({"marginRight": "x50"})
|
||||
rightMargin = number -2147483648
|
||||
// styleSheet.transform({"marginRight": "0"})
|
||||
rightMargin = number 0
|
||||
// styleSheet.transform({"marginRight": "-50"})
|
||||
rightMargin = number -50
|
||||
// styleSheet.transform({"marginRight": "09"})
|
||||
rightMargin = number 9
|
||||
|
||||
/// Text Align
|
||||
// styleSheet.transform({"textAlign": ""})
|
||||
align = null
|
||||
// styleSheet.transform({"textAlign": "invalid"})
|
||||
! ArgumentError: Error #2008: Parameter align must be one of the accepted values.
|
||||
// styleSheet.transform({"textAlign": "left"})
|
||||
align = string "left"
|
||||
// styleSheet.transform({"textAlign": "right"})
|
||||
align = string "right"
|
||||
// styleSheet.transform({"textAlign": "justify"})
|
||||
align = string "justify"
|
||||
// styleSheet.transform({"textAlign": "center"})
|
||||
align = string "center"
|
||||
|
||||
/// Text Decoration
|
||||
// styleSheet.transform({"textDecoration": ""})
|
||||
underline = null
|
||||
// styleSheet.transform({"textDecoration": "bold"})
|
||||
underline = null
|
||||
// styleSheet.transform({"textDecoration": "none"})
|
||||
underline = boolean false
|
||||
// styleSheet.transform({"textDecoration": "underline"})
|
||||
underline = boolean true
|
||||
|
||||
/// Text Indent
|
||||
// styleSheet.transform({"textIndent": ""})
|
||||
indent = null
|
||||
// styleSheet.transform({"textIndent": "50"})
|
||||
indent = number 50
|
||||
// styleSheet.transform({"textIndent": "50.5 px"})
|
||||
indent = number 50
|
||||
// styleSheet.transform({"textIndent": "50 pt"})
|
||||
indent = number 50
|
||||
// styleSheet.transform({"textIndent": "50xx"})
|
||||
indent = number 50
|
||||
// styleSheet.transform({"textIndent": " 50"})
|
||||
indent = number 50
|
||||
// styleSheet.transform({"textIndent": "x50"})
|
||||
indent = number -2147483648
|
||||
// styleSheet.transform({"textIndent": "0"})
|
||||
indent = number 0
|
||||
// styleSheet.transform({"textIndent": "-50"})
|
||||
indent = number -50
|
||||
// styleSheet.transform({"textIndent": "09"})
|
||||
indent = number 9
|
||||
|
||||
/// Every property is valid
|
||||
style = {
|
||||
"color" = string "#FF0000"
|
||||
"display" = string "block"
|
||||
"fontFamily" = string "sans-serif"
|
||||
"fontSize" = string "75px"
|
||||
"fontStyle" = string "italic"
|
||||
"fontWeight" = string "bold"
|
||||
"kerning" = string "true"
|
||||
"leading" = string "5"
|
||||
"letterSpacing" = string "0"
|
||||
"marginLeft" = string "0"
|
||||
"marginRight" = string "0"
|
||||
"textAlign" = string "justify"
|
||||
"textDecoration" = string "underline"
|
||||
"textIndent" = string "0"
|
||||
}
|
||||
|
||||
format = {
|
||||
"align" = string "justify"
|
||||
"bold" = boolean true
|
||||
"color" = number 16711680
|
||||
"font" = string "_sans"
|
||||
"indent" = number 0
|
||||
"italic" = boolean true
|
||||
"kerning" = boolean true
|
||||
"leading" = number 5
|
||||
"leftMargin" = number 0
|
||||
"letterSpacing" = number 0
|
||||
"rightMargin" = number 0
|
||||
"size" = number 75
|
||||
"underline" = boolean true
|
||||
"display" = string "block"
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
num_ticks = 1
|
Loading…
Reference in New Issue