public Size MeasureString(FontConfig font, string text) { XftFontExt fontExt = objectCache.GetXftFont(font); byte[] utf32Text = Encoding.UTF32.GetBytes(text); int width = 0; GCHandle utf32TextHandle = GCHandle.Alloc(utf32Text, GCHandleType.Pinned); try { IntPtr utf32TextPtr = utf32TextHandle.AddrOfPinnedObject(); foreach (var range in fontExt.GetRanges(utf32Text)) { LibXft.XftTextExtents32( display, range.Font, utf32TextPtr + range.Start, (range.End - range.Start) / 4, out var extents ); width += extents.xOff; } } finally { utf32TextHandle.Free(); } var fontInfo = Marshal.PtrToStructure <XftFont>(fontExt.MainFont); return(new Size(width, fontInfo.height)); }
private int DrawString(IntPtr xftDraw, IntPtr xftColorPtr, XftFontExt fontExt, int x, int y, string text) { // todo: reuse buffer? byte[] utf32Text = Encoding.UTF32.GetBytes(text); GCHandle utf32TextHandle = GCHandle.Alloc(utf32Text, GCHandleType.Pinned); try { IntPtr utf32TextPtr = utf32TextHandle.AddrOfPinnedObject(); int xOffset = 0; foreach (var range in fontExt.GetRanges(utf32Text)) { xOffset += DrawStringRange(xftDraw, xftColorPtr, range.Font, x + xOffset, y, utf32TextPtr, range.Start, range.End); } return(xOffset); } finally { utf32TextHandle.Free(); } }