blob: 93e4ea79a6a58c432fd8188d5b7ec5f8dc45f0db [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package flashx.textLayout.compose
{
import flash.text.engine.TextBlock;
import flash.text.engine.TextLine;
import flash.text.engine.TextLineValidity;
import flash.utils.Dictionary;
CONFIG::debug { import flashx.textLayout.debug.assert; }
import flashx.textLayout.tlf_internal;
use namespace tlf_internal;
/**
* The TextLineRecycler class provides support for recycling of TextLines. Some player versions support a recreateTextLine. Passing TextLines
* to the recycler makes them available for reuse. This improves Player performance.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public class TextLineRecycler
{
static private const _textLineRecyclerCanBeEnabled:Boolean = (new TextBlock).hasOwnProperty("recreateTextLine");
static private var _textLineRecyclerEnabled:Boolean = _textLineRecyclerCanBeEnabled;
/** Controls if the TLF recycler enabled. It can only be enabled in 10.1 or later players.
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
static public function get textLineRecyclerEnabled():Boolean
{ return _textLineRecyclerEnabled; }
static public function set textLineRecyclerEnabled(value:Boolean):void
{ _textLineRecyclerEnabled = value ? _textLineRecyclerCanBeEnabled : false; }
// manage a cache of TextLine's that can be reused
// This version uses a dictionary that holds the TextLines as weak references
static private var reusableLineCache:Dictionary = new Dictionary(true);
/**
* Add a TextLine to the pool for reuse. TextLines for reuse should have null userData and null parent.
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
static public function addLineForReuse(textLine:TextLine):void
{
CONFIG::debug { assert(textLine.parent == null && textLine.userData == null && (textLine.validity == TextLineValidity.INVALID || textLine.validity == TextLineValidity.STATIC),"textLine not ready for reuse"); }
if (_textLineRecyclerEnabled)
{
CONFIG::debug
{
for each (var line:TextLine in reusableLineCache)
{
assert(line != textLine,"READDING LINE TO CACHE");
}
}
CONFIG::debug { cacheTotal++; }
reusableLineCache[textLine] = null;
}
}
CONFIG::debug
{
/** @private */
static tlf_internal var cacheTotal:int = 0;
/** @private */
static tlf_internal var fetchTotal:int = 0;
/** @private */
static tlf_internal var hitTotal:int = 0;
static private function recordFetch(hit:int):void
{
fetchTotal++;
hitTotal += hit;
/*if ((fetchTotal%100) == 0)
trace(fetchTotal,hitTotal,cacheTotal);*/
}
}
/**
* Return a TextLine from the pool for reuse.
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
static public function getLineForReuse():TextLine
{
if (_textLineRecyclerEnabled)
{
for (var obj:Object in reusableLineCache)
{
// remove from the cache
delete reusableLineCache[obj];
CONFIG::debug { assert(reusableLineCache[obj] === undefined,"Bad delete"); }
CONFIG::debug { recordFetch(1); }
return obj as TextLine;
}
CONFIG::debug { recordFetch(0); }
}
return null;
}
/** @private empty the reusableLineCache */
static tlf_internal function emptyReusableLineCache():void
{
reusableLineCache = new Dictionary(true);
}
}
}