TextExtents MeasureTextExtents(ref TextBlock block, TextQuality quality)
        {
            // TODO: Parse layout options:
            var format = block.Font.Italic ? measure_string_format : measure_string_format_tight;

            //StringFormat format = measure_string_format_tight;

            if (block.Direction == TextDirection.Vertical)
            {
                format.FormatFlags |= StringFormatFlags.DirectionVertical;
            }
            else
            {
                format.FormatFlags &= ~StringFormatFlags.DirectionVertical;
            }

            if (block.Direction == TextDirection.RightToLeft)
            {
                format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
            }
            else
            {
                format.FormatFlags &= ~StringFormatFlags.DirectionRightToLeft;
            }

            if (block.Alignment == TextAlignment.Near)
            {
                format.Alignment = StringAlignment.Near;
            }
            else if (block.Alignment == TextAlignment.Center)
            {
                format.Alignment = StringAlignment.Center;
            }
            else
            {
                format.Alignment = StringAlignment.Far;
            }

            TextExtents extents = text_extents_pool.Acquire();

            RectangleF rect = block.Bounds;

            // Work around Mono/GDI+ bug, which causes incorrect
            // text wraping when block.Bounds == SizeF.Empty.
            if (block.Bounds.Size == SizeF.Empty)
            {
                rect.Size = MaximumGraphicsClipSize;
            }

            SetTextRenderingOptions(graphics, block.Font, quality);

            IntPtr native_graphics      = GdiPlus.GetNativeGraphics(graphics);
            IntPtr native_font          = GdiPlus.GetNativeFont(block.Font);
            IntPtr native_string_format = GdiPlus.GetNativeStringFormat(format);

            float max_width = 0, max_height = 0;

            // It seems that the mere presence of \n and \r characters
            // is enough for Mono to botch the layout (even if these
            // characters are not processed.) We'll need to find a
            // different way to perform layout on Mono, probably
            // through Pango.
            // TODO: This workaround allocates memory.
            //if (Configuration.RunningOnMono)
            {
                string[] lines = block.Text.Replace("\r", String.Empty).Split('\n');
                foreach (string s in lines)
                {
                    float width, height;

                    extents.AddRange(MeasureGlyphExtents(
                                         ref block, s,
                                         native_graphics, native_font, native_string_format,
                                         ref rect, out width, out height));

                    if ((block.Direction & TextDirection.Vertical) == 0)
                    {
                        rect.Y += block.Font.Height;
                    }
                    else
                    {
                        rect.X += block.Font.Height;
                    }

                    if (width > max_width)
                    {
                        max_width = width;
                    }
                    if (height > max_height)
                    {
                        max_height = height;
                    }
                }
            }

            if (extents.Count > 0)
            {
                extents.BoundingBox = new RectangleF(extents[0].X, extents[0].Y, max_width, max_height);
            }
            else
            {
                extents.BoundingBox = RectangleF.Empty;
            }

            return(extents);
        }