| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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.utils |
| { |
| import flash.geom.Rectangle; |
| import flash.text.engine.TextLine; |
| import flash.text.engine.TextLineValidity |
| |
| import flashx.textLayout.debug.assert; |
| import flashx.textLayout.compose.IFlowComposer; |
| import flashx.textLayout.compose.TextFlowLine; |
| import flashx.textLayout.elements.TextRange; |
| import flashx.textLayout.tlf_internal; |
| |
| use namespace tlf_internal; |
| /** |
| * Utilities for getting information about text geometry and bounds. |
| * The methods of this class are static and must be called using |
| * the syntax <code>GeometryUtil.method(<em>parameter</em>)</code>. |
| * |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @langversion 3.0 |
| */ |
| [ExcludeClass] |
| public final class GeometryUtil |
| { |
| /** |
| * Returns an array of line/rectangle object pairs describing the highlight area of the text |
| * based on the content bounded within the indicies. The rectangles are the same as those which would be |
| * created if the text were selected. May return one or more pair per line. |
| * |
| * |
| * @param range - a TextRange describing the TextFlow as well as the beginning and end indicies |
| * @return Array - An array of TextLine and Rectangle pairs. The objects can be referenced as: |
| * obj.textLine - to access the TextLine object |
| * obj.rect - to access the rectangle describing the selection in TextLine coordinates |
| * |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @langversion 3.0 |
| * |
| * Example Usage: |
| * var theRect:Rectangle = returnArray[0].rect.clone(); |
| * var textLine:TextLine = returnArray[0].textLine; |
| * var globalStart:Point = new Point(theRect.x, theRect.y); |
| * globalStart = textLine.localToGlobal(globalStart); |
| * globalStart = textLine.parent.globalToLocal(globalStart); |
| * theRect.x = globalStart.x; |
| * theRect.y = globalStart.y; |
| * |
| * [Make a new shape and draw the path into it. See flash.display.graphics] |
| * textLine.parent.addChild(newShape); |
| */ |
| public static function getHighlightBounds(range:TextRange):Array |
| { |
| var flowComposer:IFlowComposer = range.textFlow.flowComposer; |
| if (!flowComposer) |
| return null; |
| |
| |
| var resultShapes:Array = new Array(); |
| |
| var begLine:int = flowComposer.findLineIndexAtPosition(range.absoluteStart); |
| var endLine:int = range.absoluteStart == range.absoluteEnd ? begLine : flowComposer.findLineIndexAtPosition(range.absoluteEnd); |
| |
| // watch for going past the end |
| if (endLine >= flowComposer.numLines) |
| endLine = flowComposer.numLines-1; |
| |
| var prevLine:TextFlowLine = begLine > 0 ? flowComposer.getLineAt(begLine-1) : null; |
| var nextLine:TextFlowLine; |
| |
| var line:TextFlowLine = flowComposer.getLineAt(begLine); |
| |
| var mainRects:Array = []; |
| |
| for (var curLineIndex:int = begLine; curLineIndex <= endLine; curLineIndex++) |
| { |
| nextLine = curLineIndex != (flowComposer.numLines - 1) ? flowComposer.getLineAt(curLineIndex + 1) : null; |
| |
| |
| var heightAndAdj:Array = line.getRomanSelectionHeightAndVerticalAdjustment(prevLine, nextLine); |
| |
| var textLine:TextLine = line.getTextLine(true); |
| |
| line.calculateSelectionBounds(textLine, mainRects, |
| range.absoluteStart < line.absoluteStart ? line.absoluteStart - line.paragraph.getAbsoluteStart() |
| : range.absoluteStart - line.paragraph.getAbsoluteStart(), |
| range.absoluteEnd > (line.absoluteStart + line.textLength) ? line.absoluteStart + line.textLength - line.paragraph.getAbsoluteStart() |
| : range.absoluteEnd - line.paragraph.getAbsoluteStart(), |
| range.textFlow.computedFormat.blockProgression, heightAndAdj); |
| |
| |
| for each(var rect:Rectangle in mainRects) |
| { |
| var obj:Object = new Object(); // NO PMD |
| obj.textLine = textLine; |
| obj.rect = rect.clone(); |
| |
| resultShapes.push(obj); |
| } |
| mainRects.length = 0; |
| |
| var temp:TextFlowLine = line; |
| line = nextLine; |
| prevLine = temp; |
| } |
| |
| return resultShapes; |
| } |
| } |
| |
| } |