internal static extern void FT_Vector_Polarize(ref FTVector vec, out int length, out int angle);
internal static extern Error FT_Stroker_CubicTo(IntPtr stroker, ref FTVector control1, ref FTVector control2, ref FTVector to);
internal static extern void FT_Vector_From_Polar(out FTVector vec, int length, int angle);
internal static extern Error FT_Get_PFR_Kerning(IntPtr face, uint left, uint right, out FTVector avector);
internal static extern Error FT_Glyph_Transform(IntPtr glyph, ref FTMatrix matrix, ref FTVector delta);
public bool RastTest(int resX, int resY, int[] arrPointSizes, float stretchX, float stretchY, float rotation, float skew, float[,] matrix, bool setBW, bool setGrayscale, bool setCleartype, uint CTFlags, RastTestErrorDelegate pRastTestErrorDelegate, UpdateProgressDelegate pUpdateProgressDelegate, int numGlyphs) { int count_sets = 0; LoadFlags lf = LoadFlags.Default; LoadTarget lt = LoadTarget.Normal; if ( setBW ) { lf = LoadFlags.Default|LoadFlags.NoAutohint|LoadFlags.Monochrome|LoadFlags.ComputeMetrics; lt = LoadTarget.Mono; _lib.PropertySet("truetype", "interpreter-version", 35); count_sets++; } if ( setGrayscale ) { lf = LoadFlags.Default|LoadFlags.NoAutohint|LoadFlags.ComputeMetrics; lt = LoadTarget.Normal; _lib.PropertySet("truetype", "interpreter-version", 35); count_sets++; } if ( setCleartype ) { lf = LoadFlags.Default|LoadFlags.NoAutohint|LoadFlags.ComputeMetrics; lt = LoadTarget.Lcd; _lib.PropertySet("truetype", "interpreter-version", 40); count_sets++; } if ( count_sets != 1 ) throw new ArgumentOutOfRangeException("Only one of BW/Grayscale/Cleartype should be set"); try { TT_Diagnostics_Unset(); } catch (Exception e) { throw new NotImplementedException("UnImplemented in this version of Freetype: " + FTVersion); }; FTMatrix fmatrix = new FTMatrix(new Fixed16Dot16( matrix[0,0] * stretchX ), new Fixed16Dot16( matrix[0,1] * stretchX ), new Fixed16Dot16( matrix[1,0] * stretchY ), new Fixed16Dot16( matrix[1,1] * stretchY )); FTVector fdelta = new FTVector(new Fixed16Dot16( matrix[0,2] * stretchX ), new Fixed16Dot16( matrix[1,2] * stretchY )); /* matrix[2,0] = matrix[2,1] = 0, matrix[2,2] =1, not used */ FTMatrix mskew = new FTMatrix(new Fixed16Dot16( 1 ), new Fixed16Dot16( 0 ), (new Fixed16Dot16(skew)).Tan(), new Fixed16Dot16( 1 )); FTMatrix.Multiply(ref mskew, ref fmatrix); fdelta.Transform(mskew); FTVector rot_row1 = new FTVector(new Fixed16Dot16( 1 ), new Fixed16Dot16( 0 )); FTVector rot_row2 = new FTVector(new Fixed16Dot16( 1 ), new Fixed16Dot16( 0 )); rot_row1.Rotate(new Fixed16Dot16(rotation)); rot_row2.Rotate(new Fixed16Dot16(rotation + 90)); FTMatrix mrot = new FTMatrix(rot_row1, rot_row2); FTMatrix.Multiply(ref mrot, ref fmatrix); fdelta.Rotate(new Fixed16Dot16(-rotation)); for (int i = 0; i < arrPointSizes.Length ; i++) { if ( m_UserCancelledTest ) return true; pUpdateProgressDelegate("Processing Size " + arrPointSizes[i]); _face.SetCharSize(new Fixed26Dot6(arrPointSizes[i]), new Fixed26Dot6(arrPointSizes[i]), (uint) resX, (uint) resY); _face.SetTransform(fmatrix, fdelta); for (uint ig = 0; ig < numGlyphs; ig++) { diagnostics_Function diagnostics = (message, opcode, range_base, is_composite, IP, callTop, opc, start) => { string sDetails = "Size " + arrPointSizes[i] + ", " + opcode; switch ( range_base ) { case 3: if (is_composite != 0) sDetails += ", Composite Glyph ID " + ig; else sDetails += ", Glyph ID " + ig; break; case 1: /* font */ case 2: /* cvt */ // ? sDetails += ", Pre-Program"; break; default: /* none */ sDetails += ", Unknown?"; // ? break; } sDetails += ", At ByteOffset " + IP; if (callTop > 0) sDetails += ", In function " + opc + " offsetted by " + (IP - start); pRastTestErrorDelegate(message, sDetails); m_RastErrorCount += 1; return 0; // Not used currently. }; TT_Diagnostics_Set(diagnostics); _face.LoadGlyph(ig, lf, lt); TT_Diagnostics_Unset(); } } return true; }
/// <summary> /// A function used to set the transformation that is applied to glyph images when they are loaded into a glyph /// slot through <see cref="LoadGlyph"/>. /// </summary> /// <remarks><para> /// The transformation is only applied to scalable image formats after the glyph has been loaded. It means that /// hinting is unaltered by the transformation and is performed on the character size given in the last call to /// <see cref="SetCharSize"/> or <see cref="SetPixelSizes"/>. /// </para><para> /// Note that this also transforms the ‘face.glyph.advance’ field, but not the values in ‘face.glyph.metrics’. /// </para></remarks> /// <param name="matrix">A pointer to the transformation's 2x2 matrix. Use 0 for the identity matrix.</param> /// <param name="delta">A pointer to the translation vector. Use 0 for the null vector.</param> public void SetTransform(FTMatrix matrix, FTVector delta) { if (disposed) throw new ObjectDisposedException("face", "Cannot access a disposed object."); FT.FT_Set_Transform(Reference, ref matrix, ref delta); }
internal static extern IntPtr FT_Vector_Length(ref FTVector vec);
internal static extern Error FT_Glyph_To_Bitmap(ref IntPtr the_glyph, RenderMode render_mode, ref FTVector origin, [MarshalAs(UnmanagedType.U1)] bool destroy);
internal static extern int FT_Vector_Length(ref FTVector vec);
internal static extern Error FT_Get_Kerning(IntPtr face, uint left_glyph, uint right_glyph, KerningMode kern_mode, out FTVector akerning);
internal static extern void FT_Set_Transform(IntPtr face, ref FTMatrix matrix, ref FTVector delta);
/// <summary> /// Initializes a new instance of the <see cref="FTMatrix"/> struct. /// </summary> /// <param name="row0">Matrix coefficients XX, XY.</param> /// <param name="row1">Matrix coefficients YX, YY.</param> public FTMatrix(FTVector row0, FTVector row1) : this(row0.X, row0.Y, row1.X, row1.Y) { }
internal static extern void FT_Vector_Transform(ref FTVector vec, ref FTMatrix matrix);
internal static extern void FT_Vector_Polarize(ref FTVector vec, out IntPtr length, out IntPtr angle);
/// <summary> /// Convert a given glyph object to a bitmap glyph object. /// </summary> /// <remarks><para> /// This function does nothing if the glyph format isn't scalable. /// </para><para> /// The glyph image is translated with the ‘origin’ vector before rendering. /// </para><para> /// The first parameter is a pointer to an <see cref="Glyph"/> handle, that will be replaced by this function /// (with newly allocated data). Typically, you would use (omitting error handling): /// </para><para> /// --sample code ommitted-- /// </para></remarks> /// <param name="renderMode">An enumeration that describes how the data is rendered.</param> /// <param name="origin"> /// A pointer to a vector used to translate the glyph image before rendering. Can be 0 (if no translation). The /// origin is expressed in 26.6 pixels. /// </param> /// <param name="destroy"> /// A boolean that indicates that the original glyph image should be destroyed by this function. It is never /// destroyed in case of error. /// </param> public void ToBitmap(RenderMode renderMode, FTVector origin, bool destroy) { if (disposed) throw new ObjectDisposedException("Glyph", "Cannot access a disposed object."); IntPtr glyphRef = Reference; Error err = FT.FT_Glyph_To_Bitmap(ref glyphRef, renderMode, ref origin, destroy); Reference = glyphRef; if (err != Error.Ok) throw new FreeTypeException(err); }
internal static extern void FT_Vector_From_Polar(out FTVector vec, IntPtr length, IntPtr angle);
/// <summary> /// Start a new sub-path in the stroker. /// </summary> /// <remarks> /// This function is useful when you need to stroke a path that is not stored as an <see cref="Outline"/> /// object. /// </remarks> /// <param name="to">A pointer to the start vector.</param> /// <param name="open">A boolean. If 1, the sub-path is treated as an open one.</param> public void BeginSubPath(FTVector to, bool open) { if (disposed) throw new ObjectDisposedException("Stroker", "Cannot access a disposed object."); Error err = FT.FT_Stroker_BeginSubPath(Reference, ref to, open); if (err != Error.Ok) throw new FreeTypeException(err); }
internal static extern Error FT_Stroker_BeginSubPath(IntPtr stroker, ref FTVector to, [MarshalAs(UnmanagedType.U1)] bool open);
internal static extern Error FT_Stroker_LineTo(IntPtr stroker, ref FTVector to);
internal static extern void FT_Vector_Rotate(ref FTVector vec, int angle);
internal static extern void FT_Vector_Unit(out FTVector vec, int angle);
/// <summary> /// Transform a glyph image if its format is scalable. /// </summary> /// <param name="matrix">A pointer to a 2x2 matrix to apply.</param> /// <param name="delta"> /// A pointer to a 2d vector to apply. Coordinates are expressed in 1/64th of a pixel. /// </param> public void Transform(FTMatrix matrix, FTVector delta) { if (disposed) throw new ObjectDisposedException("Glyph", "Cannot access a disposed object."); Error err = FT.FT_Glyph_Transform(Reference, ref matrix, ref delta); if (err != Error.Ok) throw new FreeTypeException(err); }
internal static extern void FT_Vector_Unit(out FTVector vec, IntPtr angle);
/// <summary> /// A function used to set the transformation that is applied to glyph images when they are loaded into a glyph /// slot through <see cref="LoadGlyph"/> with the identity matrix. /// </summary> /// <remarks><para> /// The transformation is only applied to scalable image formats after the glyph has been loaded. It means that /// hinting is unaltered by the transformation and is performed on the character size given in the last call to /// <see cref="SetCharSize"/> or <see cref="SetPixelSizes"/>. /// </para><para> /// Note that this also transforms the ‘face.glyph.advance’ field, but not the values in ‘face.glyph.metrics’. /// </para></remarks> /// <param name="delta"> /// A pointer to the translation vector. Use the method overloads for the null vector. /// </param> public unsafe void SetTransform(FTVector delta) { if (disposed) throw new ObjectDisposedException("face", "Cannot access a disposed object."); FT.FT_Set_Transform(Reference, IntPtr.Zero, (IntPtr)(&delta)); }
internal static extern void FT_Vector_Rotate(ref FTVector vec, IntPtr angle);
/// <summary> /// ‘Draw’ a single line segment in the stroker's current sub-path, from the last position. /// </summary> /// <remarks> /// You should call this function between <see cref="BeginSubPath"/> and <see cref="EndSubPath"/>. /// </remarks> /// <param name="to">A pointer to the destination point.</param> public void LineTo(FTVector to) { if (disposed) throw new ObjectDisposedException("Stroker", "Cannot access a disposed object."); Error err = FT.FT_Stroker_LineTo(Reference, ref to); if (err != Error.Ok) throw new FreeTypeException(err); }
/// <summary> /// Initializes a new instance of the <see cref="FTMatrix" /> struct. /// </summary> /// <param name="row0">Matrix coefficients XX, XY.</param> /// <param name="row1">Matrix coefficients YX, YY.</param> public FTMatrix(FTVector row0, FTVector row1) : this(row0.X.Value, row0.Y.Value, row1.X.Value, row1.Y.Value) { }