/*=:project
scalable Inman Flash Replacement (sIFR) version 3.
=:file
Copyright: 2006 Mark Wubben.
Author: Mark Wubben,
=:history
* IFR: Shaun Inman
* sIFR 1: Mike Davidson, Shaun Inman and Tomas Jogin
* sIFR 2: Mike Davidson, Shaun Inman, Tomas Jogin and Mark Wubben
=:license
This software is licensed and provided under the CC-GNU LGPL.
See
*/
import SifrStyleSheet;
class sIFR {
public static var DEFAULT_TEXT = 'Rendered with sIFR 3';
public static var CSS_ROOT_CLASS = 'sIFR-root';
public static var DEFAULT_WIDTH = 300;
public static var DEFAULT_HEIGHT = 100;
public static var DEFAULT_ANTI_ALIAS_TYPE = 'advanced';
public static var MARGIN_LEFT = -3;
public static var PADDING_BOTTOM = 5;
public static var MAX_FONT_SIZE = 126;
public static var ALIASING_MAX_FONT_SIZE = 48;
//= Holds CSS properties and other rendering properties for the Flash movie.
// *Don't overwrite!*
public static var styles:SifrStyleSheet = new SifrStyleSheet();
//= Allow sIFR to be run from localhost
public static var fromLocal:Boolean = true;
//= Array containing domains for which sIFR may render text. Used to prevent
// hotlinking. Use `*` to allow all domains.
public static var domains:Array = [];
//= Whether kerning is enabled by default. This can be overriden from the client side.
// See also .
public static var defaultKerning:Boolean = true;
//= Default value which can be overriden from the client side.
// See also .
public static var defaultSharpness:Number = 0;
//= Default value which can be overriden from the client side.
// See also .
public static var defaultThickness:Number = 0;
//= Default value which can be overriden from the client side.
// See also .
public static var defaultOpacity:Number = -1; // Use client settings
//= Default value which can be overriden from the client side.
// See also .
public static var defaultBlendMode:Number = -1; // Use cliest settings
//= Overrides the grid fit type as defined on the client side.
// See also .
public static var enforcedGridFitType:String = null;
//= If `true` sIFR won't override the anti aliasing set in the Flash IDE when exporting.
// Thickness and sharpness won't be affected either.
public static var preserveAntiAlias:Boolean = false;
//= If `true` sIFR will disable anti-aliasing if the font size is larger than `ALIASING_MAX_FONT_SIZE`.
// This setting is *independent* from `preserveAntiAlias`.
public static var conditionalAntiAlias:Boolean = true;
//= Sets the anti alias type. By default it's `DEFAULT_ANTI_ALIAS_TYPE`.
// See also .
public static var antiAliasType:String = null;
//= Flash filters can be added to this array and will be applied to the text field.
public static var filters:Array = [];
//= A mapping from the names of the filters to their actual objecs, used when transforming
// filters defined on the client. You can add additional filters here so they'll be supported
// when defined on the client.
public static var filterMap:Object = {
DisplacementMapFilter : flash.filters.DisplacementMapFilter,
ColorMatrixFilter : flash.filters.ColorMatrixFilter,
ConvolutionFilter : flash.filters.ConvolutionFilter,
GradientBevelFilter : flash.filters.GradientBevelFilter,
GradientGlowFilter : flash.filters.GradientGlowFilter,
BevelFilter : flash.filters.BevelFilter,
GlowFilter : flash.filters.GlowFilter,
BlurFilter : flash.filters.BlurFilter,
DropShadowFilter : flash.filters.DropShadowFilter
};
private var textField;
private var originalHeight;
private var currentHeight;
//= Sets the default styles for `sIFR.styles`. This method is called
// directly in `sifr.fla`, before options are applied.
public static function setDefaultStyles() {
sIFR.styles.parseCSS([
'.', CSS_ROOT_CLASS, ' { color: #000000; }',
'strong { display: inline; font-weight: bold; } ',
'em { display: inline; font-style: italic; }',
'a { color: #0000FF; text-decoration: underline; }',
'a:hover { color: #0000FF; text-decoration: none; }'
].join(''));
}
//= Validates the domain sIFR is being used on.
// Returns `true` if the domain is valid, `false` otherwise.
public static function checkDomain():Boolean {
if(sIFR.domains.length == 0) return true;
var domain = (new LocalConnection()).domain();
if(sIFR.fromLocal) sIFR.domains.push('localhost');
for(var i = 0; i < sIFR.domains.length; i++) {
if(sIFR.domains[i] == '*' || sIFR.domains[i] == domain) {
return true;
}
}
return false;
}
//= Runs sIFR. Called automatically.
public static function run(holder:MovieClip, parsedContent:String):sIFR {
parsedContent = checkDomain() ? unescape(parsedContent) : DEFAULT_TEXT;
if(parsedContent == 'undefined' || parsedContent == '') parsedContent = DEFAULT_TEXT;
// Sets stage parameters
Stage.scaleMode = 'noscale';
Stage.align = 'TL';
Stage.showMenu = false;
// Other parameters
var opacity = parseInt(_root.opacity);
if(!isNaN(opacity)) holder._alpha = sIFR.defaultOpacity == -1 ? opacity : sIFR.defaultOpacity;
else holder._alpha = 100;
_root.blendMode = sIFR.defaultBlendMode == -1 ? _root.blendmode : sIFR.defaultBlendMode;
// Parse CSS
sIFR.styles.parseCSS(unescape(_root.css));
var sifr = new sIFR(holder.txtF, parsedContent);
if(_root.zoomsupport == 'true') Stage.addListener({onResize: function() { sifr.scale() }});
return sifr;
}
private static function eval(str) {
var as;
if(str.charAt(0) == '{') { // Ah, we need to create an object
as = {};
str = str.substring(1, str.length - 1);
var $ = str.split(',');
for(var i = 0; i < $.length; i++) {
var $1 = $[i].split(':');
as[$1[0]] = sIFR.eval($1[1]);
}
} else if(str.charAt(0) == '"') { // String
as = str.substring(1, str.length - 1);
} else if(str == 'true' || str == 'false') { // Boolean
as = str == 'true';
} else { // Float
as = parseFloat(str);
}
return as;
}
private function applyFilters() {
var $filters = this.textField.filters;
$filters = $filters.concat(sIFR.filters);
var $ = _root.filters.split(';'); // name,prop:value,...;
for(var i = 0; i < $.length; i++) {
var $1 = $[i].split(',');
var newFilter = new sIFR.filterMap[$1[0]]();
for(var j = 1; j < $1.length; j++) {
var $2 = $1[j].split(':');
newFilter[$2[0]] = sIFR.eval(unescape($2[1]));
}
$filters.push(newFilter);
}
this.textField.filters = $filters;
}
private function sIFR(textField, parsedContent) {
this.textField = textField;
var offsetLeft = parseInt(_root.offsetleft);
textField._x = MARGIN_LEFT + (isNaN(offsetLeft) ? 0 : offsetLeft);
var offsetTop = parseInt(_root.offsettop);
if(!isNaN(offsetTop)) textField._y += offsetTop;
var tuneWidth = parseInt(_root.tunewidth);
if(isNaN(tuneWidth)) tuneWidth = 0;
var tuneHeight = parseInt(_root.tuneheight);
if(isNaN(tuneHeight)) tuneHeight = 0;
textField._width = tuneWidth + (isNaN(parseInt(_root.width)) ? DEFAULT_WIDTH : parseInt(_root.width));
textField._height = tuneHeight + (isNaN(parseInt(_root.height)) ? DEFAULT_HEIGHT : parseInt(_root.height));
textField.wordWrap = true;
textField.gridFitType = sIFR.enforcedGridFitType || _root.gridfittype;
this.applyFilters();
// Determine font-size and the number of lines
var fontSize = parseInt(_root.size);
if(isNaN(fontSize)) fontSize = 26;
if(!sIFR.preserveAntiAlias && (sIFR.conditionalAntiAlias && fontSize < ALIASING_MAX_FONT_SIZE
|| !sIFR.conditionalAntiAlias)) {
textField.antiAliasType = sIFR.antiAliasType || DEFAULT_ANTI_ALIAS_TYPE;
}
if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.sharpness))) {
textField.sharpness = parseInt(_root.sharpness);
}
if(isNaN(textField.sharpness)) textField.sharpness = sIFR.defaultSharpness;
if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.thickness))) {
textField.thickness = parseInt(_root.thickness);
}
if(isNaN(textField.thickness)) textField.thickness = sIFR.defaultThickness;
// Set font-size and other styles
var rootStyle = styles.getStyle('.sIFR-root') || {};
rootStyle.fontSize = fontSize; // won't go higher than 126!
styles.setStyle('.sIFR-root', rootStyle);
textField.styleSheet = styles;
this.write(parsedContent);
// Flash wants to scroll the movie by one line, by adding the fontSize to the
// textField height this is no longer happens. We also add the absolute tuneHeight,
// to prevent a negative value from triggering the bug. We won't send the fake
// value to the JavaScript side, though.
textField._height = textField.textHeight + PADDING_BOTTOM + fontSize + Math.abs(tuneHeight) + tuneHeight;
fscommand('resize', 'height:' + (textField._height - fontSize - Math.abs(tuneHeight)));
if(_root.fitexactly == 'true') fscommand('resize', 'width:' + (textField.textWidth + tuneWidth));
this.originalHeight = textField._height;
this.currentHeight = Stage.height;
textField._xscale = textField._yscale = parseInt(_root.zoom);
}
private function write(content) {
this.textField.htmlText = ['',
content, '
'
].join('');
}
//= Scales the text field to the new scale of the Flash movie itself.
public function scale() {
this.currentHeight = Stage.height;
var scale = 100 * Math.round(this.currentHeight / this.originalHeight);
textField._xscale = textField._yscale = scale;
}
}