/// <summary> /// Performs shaping on the native buffer using the specified font.. /// </summary> private unsafe void Shape(UltravioletFontFace fontFace, out hb_glyph_info_t *infos, out hb_glyph_position_t *positions, out UInt32 count) { ValidateUnicodeProperties(); var ftFontFace = fontFace as FreeTypeFontFace; if (ftFontFace == null) { throw new NotSupportedException(FreeTypeStrings.TextShaperRequiresFreeTypeFont); } PopulateNativeBuffer(); if (lastUsedFont != ftFontFace && lastUsedFontNative != IntPtr.Zero) { hb_font_destroy(lastUsedFontNative); lastUsedFont = null; lastUsedFontNative = IntPtr.Zero; } var fontNative = (lastUsedFontNative == IntPtr.Zero) ? hb_ft_font_create(ftFontFace.NativePointer, IntPtr.Zero) : lastUsedFontNative; var fontLoadFlags = ftFontFace.IsStroked ? FT_LOAD_NO_BITMAP : FT_LOAD_COLOR; hb_ft_font_set_load_flags(fontNative, fontLoadFlags); lastUsedFont = ftFontFace; lastUsedFontNative = fontNative; hb_shape(fontNative, native, IntPtr.Zero, 0); var glyphCount = 0u; infos = (hb_glyph_info_t *)hb_buffer_get_glyph_infos(native, (IntPtr)(&glyphCount)); positions = (hb_glyph_position_t *)hb_buffer_get_glyph_positions(native, IntPtr.Zero); count = glyphCount; }
private unsafe void CreateShapedChar(hb_glyph_info_t *info, hb_glyph_position_t *position, Int32 cluster, out ShapedChar result) { var cGlyphIndex = (Int32)info->codepoint; var cOffsetX = (Int16)Math.Round(position->x_offset / 64f, MidpointRounding.AwayFromZero); var cOffsetY = (Int16)Math.Round(position->y_offset / 64f, MidpointRounding.AwayFromZero); var cAdvance = (Int16)Math.Round((position->x_advance == 0 ? position->y_advance : position->x_advance) / 64f, MidpointRounding.AwayFromZero); result = new ShapedChar(cGlyphIndex, cluster, cOffsetX, cOffsetY, cAdvance); }