1

xps コンテンツをフラッシュでレンダリングするプロジェクトに取り組んでおり、フラッシュで twip (単位の 1/20) の精度制限に達しています。twip 制限は swf ファイル形式で言及されていますが、フラッシュ as3 ドキュメントでは PrintJob.addPage メソッドでのみ言及されています。ただし、DisplayObject の x プロパティと y プロパティを設定すると、0.05 未満の精度は丸められます。スケーリングに関係なく。以下のコードは、この問題を示しています。


    package
    {
    import flash.display.DisplayObject;
    import flash.display.Graphics;
    import flash.display.GraphicsPathCommand;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.StageScaleMode;
    public class TWIPTest extends Sprite
    {
        // can change behaviour by switching between createPoint and drawPoint
        public function TWIPTest()
        {
            this.stage.scaleMode = StageScaleMode.NO_SCALE;
            // scale our unit square so we can see what is happening
            scaleX = 400; scaleY = 400;
            // draw grid
            var grid : Sprite = new Sprite();
            addChild(grid);
            grid.graphics.lineStyle(TWIP, 0x888888);
            drawGrid(1 / TWIP, 1 / TWIP, TWIP, TWIP, grid);
            // center of unit square
            var cx : Number = 0.5; 
            var cy : Number = 0.5;

            var shape : Shape;
            // GREEN in middle of unit square
            this.addChild(createPoint(cx, cy, 0x00FF00));
            //drawPoint(cx, cy, 0x00FF00, this.graphics);

            // BLUE one TWIP away from GREEN
            this.addChild(createPoint(cx + TWIP, cy + TWIP, 0x0000FF));
            //drawPoint(cx + TWIP, cy + TWIP, 0x0000FF, this.graphics);

            // RED half a TWIP away from GREEN (this does not work....) 
            this.addChild(createPoint(cx + (TWIP / 2), cy + (TWIP / 2), 0xFF0000, 0.5));
            //drawPoint(cx + (TWIP / 2), cy + (TWIP / 2), 0xFF0000, this.graphics, 0.5);

            // now insert new container to work around limit encontered with RED point
            var container : Sprite = new Sprite();
            this.addChild(container);
            container.scaleX = 0.5; container.scaleY = 0.5;
            container.addChild(createPoint(2 * cx + TWIP, 2 * cy + TWIP, 0xFF00FF, 1.0, 2 * TWIP));
            //drawPoint(cx + (TWIP / 2), cy + (TWIP / 2), 0xFF00FF, container.graphics);
        }
        static private function createPoint(x:Number, y:Number,color:uint,alpha:Number=1.0,radius:Number=0.05):Shape
        {
            var shape : Shape = new Shape();
            shape.x = x; shape.y = y;
            shape.graphics.beginFill(color,alpha);
            shape.graphics.drawCircle(0, 0, radius);
            shape.graphics.endFill();
            return shape;
        }
        static private function drawPoint(x:Number, y:Number,color:uint,target:Graphics,alpha:Number=1.0,radius:Number=0.05):void
        {
            target.beginFill(color,alpha);
            target.drawCircle(x, y, radius);
            target.endFill();
        }
        // drawGrid from @Feltope
        private function drawGrid(numColumns:Number, numRows:Number, cellHeight:Number, cellWidth:Number, grid:Sprite):void 
        {
            for (var col:Number = 0; col < numColumns + 1; col++)
            {
                for (var row:Number = 0; row < numRows + 1; row++)
                {
                    grid.graphics.moveTo(col * cellWidth, 0);
                    grid.graphics.lineTo(col * cellWidth, cellHeight * numRows);
                    grid.graphics.moveTo(0, row * cellHeight);
                    grid.graphics.lineTo(cellWidth * numColumns, row * cellHeight);
                }
            }
        }
        static private const TWIP : Number = 0.05;
    }
    }

この投稿では、この問題についても言及しています。

問題は、xps ファイルを解析する際に、これがいつでも何度でも発生する可能性があることです。たとえば、


<Canvas RenderTransform="96.201126,0,0,-95.787476,713.62598,207.05859">
<Path Data="..." RenderTransform="0.010394889,0,0,-0.010439778,-7.4180626,2.1616458">

Path 要素の dx に注目してください。これは些細なことのように見えますが、親の Canvas (およびこの上の他の親) はそれを拡大するため、dx の 0 または 0.05 への丸めが非常に目立ちます。

上記のコードのように、これが発生するたびにスプライト コンテナを追加できますが、メモリが肥大化し、レンダリングが遅くなります。

私の質問(最後に)、この問題に対処した人はいますか?この制限を処理するより良い方法についてのアイデアはありますか? 回避策?どんな助けでも感謝します。乾杯

4

1 に答える 1

0

ここでの最大の問題は何ですか?画面上でどのように見えるか、または解析後に精度が失われることは? レンダリングを行うことはできませんが、たとえば位置を格納する変更された DisplayObject を実行することはできます。それを読み取ると、維持された精度が含まれます。または私は要点を逃していますか?:)

編集: 以下は、カスタム表示オブジェクト (形状とスプライト) の例です。

import flash.display.Shape;
import flash.display.Sprite;
internal class MySprite extends Sprite
{
    protected var m_nX:Number;
    protected var m_nY:Number;


    override public function get x():Number 
    {
        return m_nX;
    }

    override public function set x(value:Number):void 
    {
        m_nX = value;
        super.x = m_nX;
    }
    override public function get y():Number 
    {
        return m_nY;
    }

    override public function set y(value:Number):void 
    {
        m_nY = value;
        super.y = m_nY;
    }
}
internal class MyShape extends Shape
{
    protected var m_nX:Number;
    protected var m_nY:Number;


    override public function get x():Number 
    {
        return m_nX;
    }

    override public function set x(value:Number):void 
    {
        m_nX = value;
        super.x = m_nX;
    }
    override public function get y():Number 
    {
        return m_nY;
    }

    override public function set y(value:Number):void 
    {
        m_nY = value;
        super.y = m_nY;
    }
}

これを例に追加し、Shape のインスタンス化を置き換えて MyShape を使用します。Sprite と同じように、MySprite に置き換えます。視覚的な違いはありませんが、x と y は正確な値を返します。

これは、精度を維持するためのサンプル テストです。

addChild(createPoint(0.51000005, 0.510000049, 0x800000, 1, TWIP));
var disp :DisplayObject = getChildAt(numChildren - 1);
trace(disp.x, disp.y);

0.51000005、0.510000049 をトレースしますが、MySprite と MyShape カスタム DisplayObjects を使用せずに上記のテストを例に追加すると、0.5 0.5 が返されます。

于 2012-09-14T10:22:53.953 に答える