Projet

Général

Profil

Paste
Télécharger (14,3 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / libraries / simplepie / demo / for_the_demo / source_files / sIFR-r245 / sIFR.as @ 41cc1b08

1
/*=:project
2
    scalable Inman Flash Replacement (sIFR) version 3.
3

    
4
  =:file
5
    Copyright: 2006 Mark Wubben.
6
    Author: Mark Wubben, <http://novemberborn.net/>
7

    
8
  =:history
9
    * IFR: Shaun Inman
10
    * sIFR 1: Mike Davidson, Shaun Inman and Tomas Jogin
11
    * sIFR 2: Mike Davidson, Shaun Inman, Tomas Jogin and Mark Wubben
12

    
13
  =:license
14
    This software is licensed and provided under the CC-GNU LGPL.
15
    See <http://creativecommons.org/licenses/LGPL/2.1/>    
16
*/
17

    
18
import SifrStyleSheet;
19

    
20
class sIFR {
21
  public static var DEFAULT_TEXT                 = 'Rendered with sIFR 3, revision 245';
22
  public static var CSS_ROOT_CLASS               = 'sIFR-root';
23
  public static var DEFAULT_WIDTH                = 300;
24
  public static var DEFAULT_HEIGHT               = 100;
25
  public static var DEFAULT_ANTI_ALIAS_TYPE      = 'advanced';
26
  public static var MARGIN_LEFT                  = -3;
27
  public static var PADDING_BOTTOM               = 5; // Extra padding to make sure the movie is high enough in most cases.
28
  public static var LEADING_REMAINDER            = 2; // Flash uses the specified leading minus 2 as the applied leading.
29

    
30
  public static var MAX_FONT_SIZE                = 126;
31
  public static var ALIASING_MAX_FONT_SIZE       = 48;
32
  
33
  //= Holds CSS properties and other rendering properties for the Flash movie.
34
  //  *Don't overwrite!*
35
  public static var styles:SifrStyleSheet        = new SifrStyleSheet();
36
  //= Allow sIFR to be run from localhost
37
  public static var fromLocal:Boolean            = true;
38
  //= Array containing domains for which sIFR may render text. Used to prevent
39
  //  hotlinking. Use `*` to allow all domains.
40
  public static var domains:Array                = [];
41
  //= Whether kerning is enabled by default. This can be overriden from the client side.
42
  //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002811.html>.
43
  public static var defaultKerning:Boolean       = true;
44
  //= Default value which can be overriden from the client side.
45
  //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002788.html>.
46
  public static var defaultSharpness:Number      = 0;
47
  //= Default value which can be overriden from the client side.
48
  //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002787.html>.
49
  public static var defaultThickness:Number      = 0;
50
  //= Default value which can be overriden from the client side.
51
  //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002732.html>.
52
  public static var defaultOpacity:Number        = -1; // Use client settings
53
  //= Default value which can be overriden from the client side.
54
  //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002788.html>.
55
  public static var defaultBlendMode:Number      = -1; // Use cliest settings
56
  //= Overrides the grid fit type as defined on the client side.
57
  //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002444.html>.
58
  public static var enforcedGridFitType:String   = null;
59
  //= If `true` sIFR won't override the anti aliasing set in the Flash IDE when exporting.
60
  //  Thickness and sharpness won't be affected either.
61
  public static var preserveAntiAlias:Boolean    = false;
62
  //= If `true` sIFR will disable anti-aliasing if the font size is larger than `ALIASING_MAX_FONT_SIZE`.
63
  //  This setting is *independent* from `preserveAntiAlias`.
64
  public static var conditionalAntiAlias:Boolean = true;
65
  //= Sets the anti alias type. By default it's `DEFAULT_ANTI_ALIAS_TYPE`.
66
  //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002733.html>.
67
  public static var antiAliasType:String         = null;
68
  //= Flash filters can be added to this array and will be applied to the text field.
69
  public static var filters:Array                = [];
70
  //= A mapping from the names of the filters to their actual objecs, used when transforming
71
  //  filters defined on the client. You can add additional filters here so they'll be supported
72
  //  when defined on the client.
73
  public static var filterMap:Object             = {
74
    DisplacementMapFilter : flash.filters.DisplacementMapFilter,
75
    ColorMatrixFilter     : flash.filters.ColorMatrixFilter,
76
    ConvolutionFilter     : flash.filters.ConvolutionFilter,
77
    GradientBevelFilter   : flash.filters.GradientBevelFilter,
78
    GradientGlowFilter    : flash.filters.GradientGlowFilter,
79
    BevelFilter           : flash.filters.BevelFilter,
80
    GlowFilter            : flash.filters.GlowFilter,
81
    BlurFilter            : flash.filters.BlurFilter,
82
    DropShadowFilter      : flash.filters.DropShadowFilter
83
  };
84

    
85
  private static var instance;
86
  
87
  private var textField;
88
  private var content;
89
  private var realHeight;
90
  private var originalHeight;
91
  private var currentHeight;
92
  private var fontSize;
93
  private var tuneWidth;
94
  private var tuneHeight;
95
  
96

    
97
  
98
  //= Sets the default styles for `sIFR.styles`. This method is called
99
  //  directly in `sifr.fla`, before options are applied.
100
  public static function setDefaultStyles() {
101
    sIFR.styles.parseCSS([
102
      '.', CSS_ROOT_CLASS, ' { color: #000000; }',
103
      'strong { display: inline; font-weight: bold; } ',
104
      'em { display: inline; font-style: italic; }',
105
      'a { color: #0000FF; text-decoration: underline; }',
106
      'a:hover { color: #0000FF; text-decoration: none; }'
107
    ].join(''));
108
  }
109
  
110
  //= Validates the domain sIFR is being used on.
111
  //  Returns `true` if the domain is valid, `false` otherwise.  
112
  public static function checkDomain():Boolean {
113
    if(sIFR.domains.length == 0) return true;
114

    
115
    var domain = (new LocalConnection()).domain();
116
    if(sIFR.fromLocal) sIFR.domains.push('localhost');
117
    
118
    for(var i = 0; i < sIFR.domains.length; i++) {
119
      var match = sIFR.domains[i];
120
      if(match == '*' || match == domain) return true;
121

    
122
      var wildcard = match.lastIndexOf('*');
123
      if(wildcard > -1) {
124
        match = match.substr(wildcard + 1);
125
        var matchPosition = domain.lastIndexOf(match);
126
        if(matchPosition > -1 && (matchPosition + match.length) == domain.length) return true;
127
      }
128
    }
129
    
130
    return false;
131
  }
132
  
133
  //= Runs sIFR. Called automatically.
134
  public static function run() {
135
    var holder  = _root.holder;
136
    var content = checkDomain() ? unescape(_root.content) : DEFAULT_TEXT
137
    if(content == 'undefined' || content == '') {
138
      content = DEFAULT_TEXT;
139
      fscommand('resetmovie', '');
140
    } else fscommand('ping', '');
141

    
142
    // Sets stage parameters
143
    Stage.scaleMode = 'noscale';
144
    Stage.align = 'TL';
145
    Stage.showMenu = false;
146
    
147
    // Other parameters
148
    var opacity = parseInt(_root.opacity);
149
    if(!isNaN(opacity)) holder._alpha = sIFR.defaultOpacity == -1 ? opacity : sIFR.defaultOpacity;
150
    else holder._alpha = 100;
151
    _root.blendMode = sIFR.defaultBlendMode == -1 ? _root.blendmode : sIFR.defaultBlendMode;
152

    
153
    sIFR.instance = new sIFR(holder.txtF, content);
154
    // This should ignore resizes from the callback. Disabled for now.
155
/*    if(_root.zoomsupport == 'true') Stage.addListener({onResize: function() { sIFR.instance.scale() }});*/
156

    
157
    // Setup callbacks
158
    _root.watch('callbackTrigger', function() { 
159
      sIFR.callback();
160
      return false;
161
    });
162
  }
163
  
164
  private static function eval(str) {
165
    var as;
166
    
167
    if(str.charAt(0) == '{') { // Ah, we need to create an object
168
      as = {};
169
      str = str.substring(1, str.length - 1);
170
      var $ = str.split(',');
171
      for(var i = 0; i < $.length; i++) {
172
        var $1 = $[i].split(':');
173
        as[$1[0]] = sIFR.eval($1[1]);
174
      }
175
    } else if(str.charAt(0) == '"') { // String
176
      as = str.substring(1, str.length - 1);
177
    } else if(str == 'true' || str == 'false') { // Boolean
178
      as = str == 'true';
179
    } else { // Float
180
      as = parseFloat(str);
181
    }
182
    
183
    return as;
184
  }
185
  
186
  private function applyFilters() {
187
    var $filters = this.textField.filters;
188
    $filters = $filters.concat(sIFR.filters);
189
    
190
    var $ = _root.flashfilters.split(';'); // name,prop:value,...;
191
    for(var i = 0; i < $.length; i++) {
192
      var $1 = $[i].split(',');
193
      
194
      var newFilter = new sIFR.filterMap[$1[0]]();
195
      for(var j = 1; j < $1.length; j++) {
196
        var $2 = $1[j].split(':');
197
        newFilter[$2[0]] = sIFR.eval(unescape($2[1]));
198
      }
199
      
200
      $filters.push(newFilter);
201
    }
202

    
203
    this.textField.filters = $filters;
204
  }
205
  
206
  private function sIFR(textField, content) {
207
    this.textField = textField;
208
    this.content   = content;
209

    
210
    var offsetLeft = parseInt(_root.offsetleft);
211
    textField._x = MARGIN_LEFT + (isNaN(offsetLeft) ? 0 : offsetLeft);
212
    var offsetTop = parseInt(_root.offsettop);
213
    if(!isNaN(offsetTop)) textField._y += offsetTop;
214
    
215
    tuneWidth = parseInt(_root.tunewidth);
216
    if(isNaN(tuneWidth)) tuneWidth = 0;
217
    tuneHeight = parseInt(_root.tuneheight);
218
    if(isNaN(tuneHeight)) tuneHeight = 0;
219

    
220
    textField._width = tuneWidth + (isNaN(parseInt(_root.width)) ? DEFAULT_WIDTH : parseInt(_root.width));
221
    textField._height = tuneHeight + (isNaN(parseInt(_root.height)) ? DEFAULT_HEIGHT : parseInt(_root.height));
222
    textField.wordWrap = true;
223
    textField.selectable = _root.selectable == 'true';
224
    textField.gridFitType = sIFR.enforcedGridFitType || _root.gridfittype;
225
    this.applyFilters();
226

    
227
    // Determine font-size and the number of lines
228
    this.fontSize = parseInt(_root.size);
229
    if(isNaN(this.fontSize)) this.fontSize = 26;
230
    styles.fontSize = this.fontSize;
231
    
232
    if(!sIFR.preserveAntiAlias && (sIFR.conditionalAntiAlias && this.fontSize < ALIASING_MAX_FONT_SIZE
233
    || !sIFR.conditionalAntiAlias)) {
234
      textField.antiAliasType = sIFR.antiAliasType || DEFAULT_ANTI_ALIAS_TYPE;      
235
    }
236

    
237
    if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.sharpness))) {
238
      textField.sharpness = parseInt(_root.sharpness);
239
    }
240
    if(isNaN(textField.sharpness)) textField.sharpness = sIFR.defaultSharpness;
241

    
242
    if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.thickness))) {
243
      textField.thickness = parseInt(_root.thickness);
244
    }
245
    if(isNaN(textField.thickness)) textField.thickness = sIFR.defaultThickness;
246
    
247
    // Set font-size and other styles
248
    sIFR.styles.parseCSS(unescape(_root.css));
249
    
250
    var rootStyle = styles.getStyle('.sIFR-root') || {};
251
    rootStyle.fontSize = this.fontSize; // won't go higher than 126!
252
    styles.setStyle('.sIFR-root', rootStyle);
253
    textField.styleSheet = styles;
254
    
255
    this.write(content);
256
    this.repaint();
257
  }
258
  
259
  private function repaint() {
260
    var leadingFix = this.isSingleLine() ? sIFR.styles.latestLeading : 0;
261
    if(leadingFix > 0) leadingFix -= LEADING_REMAINDER;
262

    
263
    // Flash wants to scroll the movie by one line, by adding the fontSize to the
264
    // textField height this is no longer happens. We also add the absolute tuneHeight,
265
    // to prevent a negative value from triggering the bug. We won't send the fake
266
    // value to the JavaScript side, though.
267
    textField._height = textField.textHeight + PADDING_BOTTOM + this.fontSize + Math.abs(tuneHeight) + tuneHeight - leadingFix;
268
    this.realHeight = textField._height - this.fontSize - Math.abs(tuneHeight);
269
    var arg = 'height:' + this.realHeight;
270
    if(_root.fitexactly == 'true') arg += ',width:' + (textField.textWidth + tuneWidth);
271
    fscommand('resize', arg);
272
        
273
    this.originalHeight = textField._height;
274
    this.currentHeight = Stage.height;
275

    
276
    textField._xscale = textField._yscale = parseInt(_root.zoom);
277
  }
278
  
279
  private function write(content) {
280
    this.textField.htmlText = ['<p class="', CSS_ROOT_CLASS, '">', 
281
                                content, '</p>'
282
                              ].join('');
283
  }
284
  
285
  private function isSingleLine() {
286
    return Math.round((this.textField.textHeight - sIFR.styles.latestLeading) / this.fontSize) == 1;
287
  }
288

    
289
  //= Scales the text field to the new scale of the Flash movie itself.
290
  public function scale() {
291
    this.currentHeight = Stage.height;
292
    var scale = 100 * Math.round(this.currentHeight / this.originalHeight);
293
    textField._xscale = textField._yscale = scale;
294
  }
295
  
296
  private function calculateRatios() {
297
    var strings = ['X', 'X<br>X', 'X<br>X<br>X', 'X<br>X<br>X<br>X'];
298
    var results = {};
299

    
300
    for(var i = 1; i <= strings.length; i++) {
301
      var size = 6;
302
    
303
      this.write(strings[i - 1]);
304
      while(size < MAX_FONT_SIZE) {
305
        var rootStyle = sIFR.styles.getStyle('.sIFR-root') || {};
306
        rootStyle.fontSize = size;
307
        sIFR.styles.setStyle('.sIFR-root', rootStyle);
308
        this.textField.styleSheet = sIFR.styles;
309
        this.repaint();
310
        var ratio = (this.realHeight - PADDING_BOTTOM) / i / size;
311
        if(!results[size]) results[size] = ratio;
312
        else results[size] = ((i - 1) * results[size] + ratio) / i;
313
        size++;
314
      }
315
    }
316

    
317
    var sizes = [], ratios = [];
318
    var ratiosToSizes = {}, sizesToRatios = {};
319

    
320
    for(var size in results) {
321
      if(results[size] == Object.prototype[size]) continue;
322
      var ratio = results[size];
323
      ratiosToSizes[ratio] = Math.max(ratio, parseInt(size));
324
    }
325

    
326
    for(var ratio in ratiosToSizes) {
327
      if(ratiosToSizes[ratio] == Object.prototype[ratio]) continue;
328
      sizesToRatios[ratiosToSizes[ratio]] = roundDecimals(ratio, 2);
329
      sizes.push(ratiosToSizes[ratio]);
330
    }
331

    
332
    sizes.sort(function(a, b) { return a - b; });
333
    for(var j = 0; j < sizes.length - 1; j++) ratios.push(sizes[j], sizesToRatios[sizes[j]]);
334
    ratios.push(sizesToRatios[sizes[sizes.length - 1]]);
335

    
336
    fscommand('debug:ratios', '[' + ratios.join(',') + ']');
337
  }
338
  
339
  private function roundDecimals(value, decimals) {
340
    return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
341
  }
342
  
343
  public static function callback() {
344
    switch(_root.callbackType) {
345
      case 'replacetext':
346
        sIFR.instance.content = _root.callbackValue;
347
        sIFR.instance.write(_root.callbackValue);
348
        sIFR.instance.repaint();
349
        break;
350
      case 'resettext':
351
        sIFR.instance.write('');
352
        sIFR.instance.write(sIFR.instance.content);
353
        break;
354
      case 'ratios':
355
        sIFR.instance.calculateRatios();
356
        break;
357
    }
358
  }
359
}