从truetype b样条曲线中获取x,y坐标的公式是什么?

在给定的TrueType字体中的b样条坐标的情况下,在x,y空间中绘制线的公式是什么?     
已邀请:
请注意,Truetype允许在字形定义中使用bspline曲线和直线。 如果您需要将这些命令更改为一系列MoveTo和LineTo,您可以使用以下命令: 将TrueType数据转换为提示坐标列表。这是您的操作系统可以为您做的事情(以下代码使用Windows API)。 遍历所有坐标并将曲线转换为线条(请参阅下面的代码片段):
procedure TGlyphEvaluator.EvaluateFromBuffer( Action: TGlyphEvaluatorAction );
var
    H                                   : TTPOLYGONHEADER;
    C                                   : TTPOLYCURVE;
    Points                              : array of TPointFX;
    P, PE                               : DWORD;
    i, j                                : Integer;
    F                                   : Double;
    PA, PB, PC                          : TPoint;
begin
    SetLength( Points, 10 );
    P := 0;
    repeat
        // Eat the polygon header
        Move( FBuffer[ P ], H, sizeof( H ) );
        if H.dwType <> TT_POLYGON_TYPE then Break;          // Sanity check!
        PE := P + H.cb;
        Inc( P, sizeof( H ) );
        Points[ 0 ] := H.pfxStart;
        // Eat all the curve records
        while P < PE do begin
            // Get the curve record
            Move( FBuffer[ P ], C, sizeof( C ) - sizeof( TPointFX ) );
            Inc( P, sizeof( C ) - sizeof( TPointFX ) );

            // Get the points from the curve record
            if Length( Points ) < C.cpfx + 1 then Setlength( Points, C.cpfx + 1 );
            Move( FBuffer[ P ], Points[ 1 ], sizeof( TPointFX ) * C.cpfx );
            Inc( P, sizeof( TPointFX ) * C.cpfx );

            case C.wType of
                TT_PRIM_LINE: begin
                        MoveTo( Action, Points[ 0 ].x.value, Points[ 0 ].y.value );
                        for i := 1 to C.cpfx do
                            LineTo( Action, Points[ i ].x.value, Points[ i ].y.value );
                    end;
                TT_PRIM_QSPLINE: begin
                        MoveTo( Action, Points[ 0 ].x.value, Points[ 0 ].y.value );
                        PA.X := Points[ 0 ].x.value;
                        PA.Y := Points[ 0 ].y.value;
                        for i := 1 to C.cpfx - 1 do begin   // DrawQSpline is called C.cpfx - 1 times
                            PB.X := Points[ i ].x.value;
                            PB.Y := Points[ i ].y.value;
                            PC.X := Points[ i + 1 ].x.value;
                            PC.Y := Points[ i + 1 ].y.value;
                            if i < C.cpfx - 1 then begin
                                PC.X := ( PC.X + PB.X ) div 2;
                                PC.Y := ( PC.Y + PB.Y ) div 2;
                            end;
                            for j := 1 to 8 do begin
                                F := j / 8;
                                LineTo( Action, Round( ( PA.x - 2 * PB.x + PC.x ) * Sqr( F ) + ( 2 * PB.x - 2 * PA.x ) * F + PA.x ),
                                    Round( ( PA.y - 2 * PB.y + PC.y ) * Sqr( F ) + ( 2 * PB.y - 2 * PA.y ) * F + PA.y ) );
                            end;
                            PA := PC;
                        end;
                    end;
            end;
            // Update last point.
            Points[ 0 ] := Points[ C.cpfx ];
        end;
        MoveTo( Action, Points[ 0 ].x.value, Points[ 0 ].y.value );
        LineTo( Action, H.pfxStart.x.value, H.pfxStart.y.value );
    until P >= Longword( Length( FBuffer ) );
end;
    

要回复问题请先登录注册