Created
October 6, 2011 19:53
-
-
Save trxcllnt/1268467 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package | |
| { | |
| import embeds.*; | |
| import flash.display.*; | |
| import org.swiftsuspenders.*; | |
| import org.tinytlf.*; | |
| import org.tinytlf.html.*; | |
| import org.tinytlf.util.TagSoup; | |
| [SWF(width = "452", height = "500")] | |
| public class Base extends Sprite | |
| { | |
| private var helvetica:Helvetica; | |
| private var helveticaBold:HelveticaBold; | |
| private var helveticaItalic:HelveticaItalic; | |
| private var helveticaBoldItalic:HelveticaBoldItalic; | |
| protected const injector:Injector = new TextEngineInjector(new TextEngine()); | |
| protected var dom:IDOMNode; | |
| public function Base() | |
| { | |
| super(); | |
| const g:Graphics = graphics; | |
| g.beginFill(0xFFFFFF, 1); | |
| g.lineStyle(1, 0xCCCCCC); | |
| g.drawRect(1, 1, stage.stageWidth - 1, stage.stageHeight - 1); | |
| const css:CSS = injector.getInstance(CSS); | |
| css.inject(new CSSSource().toString()); | |
| const source:String = new HTMLSource().toString(); | |
| const html:XML = TagSoup.toXML(source); | |
| css.inject(html..style.text().toString()); | |
| const body:XML = html.localName() == 'body' ? html : (html..body[0] || <body>{html}</body>); | |
| dom = new DOMNode(body); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package | |
| { | |
| import flash.events.MouseEvent; | |
| import org.tinytlf.ITextEngine; | |
| import org.tinytlf.html.CSS; | |
| import org.tinytlf.interaction.Observables; | |
| import org.tinytlf.layout.sector.*; | |
| [SWF(width = "452", height = "500")] | |
| public class Circle extends Base | |
| { | |
| public function Circle() | |
| { | |
| super(); | |
| const css:CSS = injector.getInstance(CSS); | |
| css.inject( | |
| '*{' + | |
| 'font-name: Helvetica;' + | |
| '}' + | |
| 'p{' + | |
| 'text-align: justify;' + | |
| '}'); | |
| injector.injectInto(dom); | |
| const tsfm:ITextSectorFactoryMap = injector.getInstance(ITextSectorFactoryMap); | |
| const panes:Array = injector.getInstance(Array, '<TextPane>'); | |
| const pane:TextPane = panes[0]; | |
| pane.width = 200; | |
| pane.height = 498; | |
| pane.textSectors = tsfm. | |
| instantiate(dom.nodeName). | |
| create(dom). | |
| map(function(rect:TextRectangle, ... args):TextRectangle { | |
| rect.aligner = new CircleAligner(); | |
| if(rect is TextSector) | |
| TextSector(rect).renderer = new CircleRenderer(); | |
| return rect; | |
| }); | |
| const containers:Array = injector.getInstance(Array, '<Sprite>'); | |
| addChild(containers[0]); | |
| containers[0].y += 1; | |
| containers[0].x += 1; | |
| const obs:Observables = injector.getInstance(Observables); | |
| obs.mouseWheel(stage).subscribe(function(me:MouseEvent):void { | |
| engine.scrollPosition -= me.delta; | |
| }); | |
| const engine:ITextEngine = injector.getInstance(ITextEngine); | |
| engine.invalidate(); | |
| } | |
| } | |
| } | |
| import flash.geom.*; | |
| import flash.text.engine.*; | |
| import org.tinytlf.layout.alignment.*; | |
| import org.tinytlf.layout.sector.*; | |
| import org.tinytlf.util.*; | |
| /** | |
| * CircleRenderer breaks the lines normally, lays them out, then breaks them | |
| * again in a circle shape. This is very inefficient, because the first render | |
| * pass creates lines with a single atom (so we're guaranteed to have more lines | |
| * the first time than the second, so we know how to break them the second time | |
| * around). | |
| */ | |
| internal class CircleRenderer extends StandardSectorRenderer | |
| { | |
| override public function render(block:TextBlock, sector:TextSector, lines:Array = null):Array /*<TextLine>*/ | |
| { | |
| lines = super.render(block, sector, lines); | |
| lines = sector.layout.layout(lines, sector); | |
| var line:TextLine = lines[0]; | |
| const newLines:Array = [line]; | |
| while(true) | |
| { | |
| line = createTextLine(block, line, a.getSize(sector, lines.shift())); | |
| if(line == null) break; | |
| newLines.push(line); | |
| } | |
| while(lines.length > 0) | |
| { | |
| TextLineUtil.checkIn(TextLineUtil.cleanLine(lines.pop())); | |
| } | |
| return newLines; | |
| } | |
| } | |
| internal class CircleAligner extends AlignerBase | |
| { | |
| override public function getSize(rect:TextRectangle, previousItem:* = null):Number | |
| { | |
| if(previousItem is TextRectangle) | |
| return rect.width; | |
| const pLine:TextLine = previousItem as TextLine; | |
| const d:Number = rect.width - rect.paddingLeft - rect.paddingRight; | |
| const r:Number = d * 0.5; | |
| var y:Number = 0; | |
| if(pLine) | |
| y = Math.max(pLine.y + pLine.descent + rect.leading, 0); | |
| if(y > d) | |
| y %= d; | |
| const indent:Number = (rect is TextSector) ? TextSector(rect).textIndent : 0; | |
| const point:Point = xAtY(y, new Point(r, r), r); | |
| return Math.floor(point.y - point.x - indent); | |
| } | |
| override public function getStart(rect:TextRectangle, thisItem:*):Number | |
| { | |
| if(thisItem is TextRectangle || !thisItem) | |
| return rect.paddingLeft; | |
| const indent:Number = (rect is TextSector) ? TextSector(rect).textIndent : 0; | |
| const d:Number = rect.width - rect.paddingLeft - rect.paddingRight; | |
| const r:Number = d * 0.5; | |
| var y:Number = Math.max(thisItem.y - thisItem.ascent, 0); | |
| if(y > d) | |
| y %= d; | |
| const point:Point = xAtY(y, new Point(r, r), r); | |
| return Math.floor(point.x); | |
| } | |
| private function xAtY(yValue:Number, center:Point, radius:Number):Point | |
| { | |
| // equation of circle is (x-h)^2 + (y-k)^2 = r^2 -> x^2 - 2hx + h^2 + (value-k)^2 = r^2 | |
| // use the textbook notation | |
| const a:Number = 1; | |
| const b:Number = -2 * center.x; | |
| const c:Number = center.x * center.x + (yValue - center.y) * (yValue - center.y) - radius * radius; | |
| var d:Number = b * b - 4 * a * c; | |
| if(d < 0) | |
| return null; | |
| d = Math.sqrt(d); | |
| // note that 2*a = 2 since a = 1 and 1/2a = 1/2, so I'm adjusting the quadratic formula appropriately | |
| return new Point(0.5 * (-b - d), 0.5 * (-b + d)); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment