我正在开发一个项目,用于在flash中渲染xps内容,并且正在运行闪存中的twip(单位的1/20)精度限制。 swf文件格式中提到了twip限制,但在flash 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;
}
}
此posting也提到了这个问题。
问题在于,在解析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">
注意路径元素中的dx,这看似微不足道,但父Canvas(以及其上方的其他父项)将其缩放,因此将dx舍入为0或0.05非常明显。
我可以在发生这种情况时添加Sprite容器,就像上面的代码一样,但是这会使内存膨胀并降低渲染速度。
我的问题(最后),是否有人处理过这个问题?有关处理此限制的更好方法的任何想法?解决方法?任何帮助赞赏。欢呼声
答案 0 :(得分: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。