Esempio n. 1
0
    /// <summary>
    /// Draws the specified text string.
    /// </summary>
    public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format)
    {
      if (text == null)
        throw new ArgumentNullException("text");
      if (font == null)
        throw new ArgumentNullException("font");
      if (brush == null)
        throw new ArgumentNullException("brush");

      if (format != null && format.LineAlignment == XLineAlignment.BaseLine && layoutRectangle.Height != 0)
        throw new InvalidOperationException("DrawString: With XLineAlignment.BaseLine the height of the layout rectangle must be 0.");

      if (text.Length == 0)
        return;

      if (format == null)
        format = XStringFormats.Default;

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          RectangleF rect = layoutRectangle.ToRectangleF();
          if (format.LineAlignment == XLineAlignment.BaseLine)
          {
            double lineSpace = font.GetHeight(this);
            int cellSpace = font.FontFamily.GetLineSpacing(font.Style);
            int cellAscent = font.FontFamily.GetCellAscent(font.Style);
            int cellDescent = font.FontFamily.GetCellDescent(font.Style);
            double cyAscent = lineSpace * cellAscent / cellSpace;
            cyAscent = lineSpace * font.cellAscent / font.cellSpace;
            rect.Offset(0, (float)-cyAscent);
          }
          this.gfx.DrawString(text, font.RealizeGdiFont(), brush.RealizeGdiBrush(), rect,
            format != null ? format.RealizeGdiStringFormat() : null);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
#if !SILVERLIGHT
          double x = layoutRectangle.X;
          double y = layoutRectangle.Y;

          double lineSpace = font.GetHeight(this);
          double cyAscent = lineSpace * font.cellAscent / font.cellSpace;
          double cyDescent = lineSpace * font.cellDescent / font.cellSpace;

          bool bold = (font.Style & XFontStyle.Bold) != 0;
          bool italic = (font.Style & XFontStyle.Italic) != 0;
          bool strikeout = (font.Style & XFontStyle.Strikeout) != 0;
          bool underline = (font.Style & XFontStyle.Underline) != 0;

          //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"), // WPFHACK
          //  FlowDirection.LeftToRight, font.typeface, font.Size, brush.RealizeWpfBrush());
          FormattedText formattedText = FontHelper.CreateFormattedText(text, font.typeface, font.Size, brush.RealizeWpfBrush());

          //formattedText.SetTextDecorations(TextDecorations.OverLine);
          switch (format.Alignment)
          {
            case XStringAlignment.Near:
              // nothing to do, this is the default
              //formattedText.TextAlignment = TextAlignment.Left;
              break;

            case XStringAlignment.Center:
              x += layoutRectangle.Width / 2;
              formattedText.TextAlignment = TextAlignment.Center;
              break;

            case XStringAlignment.Far:
              x += layoutRectangle.Width;
              formattedText.TextAlignment = TextAlignment.Right;
              break;
          }
          if (PageDirection == XPageDirection.Downwards)
          {
            switch (format.LineAlignment)
            {
              case XLineAlignment.Near:
                //y += cyAscent;
                break;

              case XLineAlignment.Center:
                // TODO use CapHeight. PDFlib also uses 3/4 of ascent
                y += -formattedText.Baseline + (cyAscent * 1 / 3) + layoutRectangle.Height / 2;
                //y += -formattedText.Baseline + (font.Size * font.Metrics.CapHeight / font.unitsPerEm / 2) + layoutRectangle.Height / 2;
                break;

              case XLineAlignment.Far:
                y += -formattedText.Baseline - cyDescent + layoutRectangle.Height;
                break;

              case XLineAlignment.BaseLine:
                y -= formattedText.Baseline;
                break;
            }
          }
          else
          {
            // TODOWPF: make unit test
            switch (format.LineAlignment)
            {
              case XLineAlignment.Near:
                //y += cyDescent;
                break;

              case XLineAlignment.Center:
                // TODO use CapHeight. PDFlib also uses 3/4 of ascent
                //y += -(cyAscent * 3 / 4) / 2 + rect.Height / 2;
                break;

              case XLineAlignment.Far:
                //y += -cyAscent + rect.Height;
                break;

              case XLineAlignment.BaseLine:
                // nothing to do
                break;
            }
          }

          //if (bold && !descriptor.IsBoldFace)
          //{
          //  // TODO: emulate bold by thicker outline
          //}

          //if (italic && !descriptor.IsBoldFace)
          //{
          //  // TODO: emulate italic by shearing transformation
          //}

          if (underline)
          {
            formattedText.SetTextDecorations(TextDecorations.Underline);
            //double underlinePosition = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlinePosition / font.cellSpace;
            //double underlineThickness = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlineThickness / font.cellSpace;
            //DrawRectangle(null, brush, x, y - underlinePosition, width, underlineThickness);
          }

          if (strikeout)
          {
            formattedText.SetTextDecorations(TextDecorations.Strikethrough);
            //double strikeoutPosition = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutPosition / font.cellSpace;
            //double strikeoutSize = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutSize / font.cellSpace;
            //DrawRectangle(null, brush, x, y - strikeoutPosition - strikeoutSize, width, strikeoutSize);
          }

          //this.dc.DrawText(formattedText, layoutRectangle.Location.ToPoint());
          this.dc.DrawText(formattedText, new System.Windows.Point(x, y));
#else
          dc.DrawString(this, text, font, brush, layoutRectangle, format);
#endif
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawString(text, font, brush, layoutRectangle, format);
    }
Esempio n. 2
0
    // ----- fill -----

    /// <summary>
    /// Draws a graphical path.
    /// </summary>
    public void DrawPath(XBrush brush, XGraphicsPath path)
    {
      if (brush == null)
        throw new ArgumentNullException("brush");
      if (path == null)
        throw new ArgumentNullException("path");

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
          this.gfx.FillPath(brush.RealizeGdiBrush(), path.gdipPath);
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
          this.dc.DrawGeometry(brush.RealizeWpfBrush(), null, path.pathGeometry);
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawPath(null, brush, path);
    }
Esempio n. 3
0
    // ----- stroke and fill -----

    /// <summary>
    /// Draws a graphical path.
    /// </summary>
    public void DrawPath(XPen pen, XBrush brush, XGraphicsPath path)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen and brush", PSSR.NeedPenOrBrush);
      if (path == null)
        throw new ArgumentNullException("path");

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          if (brush != null)
            this.gfx.FillPath(brush.RealizeGdiBrush(), path.gdipPath);
          if (pen != null)
            this.gfx.DrawPath(pen.RealizeGdiPen(), path.gdipPath);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          System.Windows.Media.Brush wpfBrush = brush != null ? brush.RealizeWpfBrush() : null;
          System.Windows.Media.Pen wpfPen = pen != null ? pen.RealizeWpfPen() : null;
          this.dc.DrawGeometry(wpfBrush, wpfPen, path.pathGeometry);
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawPath(pen, brush, path);
    }
Esempio n. 4
0
    /// <summary>
    /// Draws a pie defined by an ellipse.
    /// </summary>
    public void DrawPie(XPen pen, XBrush brush, double x, double y, double width, double height, double startAngle, double sweepAngle)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen", PSSR.NeedPenOrBrush);

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          this.gfx.FillPie(brush.RealizeGdiBrush(), (float)x, (float)y, (float)width, (float)height, (float)startAngle, (float)sweepAngle);
          this.gfx.DrawPie(pen.RealizeGdiPen(), (float)x, (float)y, (float)width, (float)height, (float)startAngle, (float)sweepAngle);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
#if !SILVERLIGHT
          System.Windows.Media.Brush wpfBrush = brush != null ? brush.RealizeWpfBrush() : null;
          System.Windows.Media.Pen wpfPen = pen != null ? pen.RealizeWpfPen() : null;
          System.Windows.Point center = new System.Windows.Point(x + width / 2, y + height / 2);
          System.Windows.Point startArc;
          ArcSegment arc = GeometryHelper.CreateArcSegment(x, y, width, height, startAngle, sweepAngle, out startArc);
          PathFigure figure = new PathFigure();
          figure.StartPoint = center;
          figure.Segments.Add(new LineSegment(startArc, true));
          figure.Segments.Add(arc);
          figure.IsClosed = true;
          PathGeometry geo = new PathGeometry();
          geo.Figures.Add(figure);
          this.dc.DrawGeometry(wpfBrush, wpfPen, geo);
#else
          // AGHACK
#endif
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawPie(pen, brush, x, y, width, height, startAngle, sweepAngle);
    }
Esempio n. 5
0
    /// <summary>
    /// Draws a closed cardinal spline defined by an array of points.
    /// </summary>
    public void DrawClosedCurve(XPen pen, XBrush brush, XPoint[] points, XFillMode fillmode, double tension)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen and brush", PSSR.NeedPenOrBrush);

      int count = points.Length;
      if (count == 0)
        return;
      if (count < 2)
        throw new ArgumentException("Not enough points.", "points");

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          if (brush != null)
            this.gfx.FillClosedCurve(brush.RealizeGdiBrush(), MakePointFArray(points), (FillMode)fillmode, (float)tension);
          if (pen != null)
          {
            // The fillmode is not used by DrawClosedCurve
            this.gfx.DrawClosedCurve(pen.RealizeGdiPen(), MakePointFArray(points), (float)tension, (FillMode)fillmode);
          }
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
#if !SILVERLIGHT
          tension /= 3; // Simply tried out. Not proofed why it is correct.

          PathFigure figure = new PathFigure();
          figure.IsClosed = true;
          figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
          if (count == 2)
          {
            figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[1], tension));
          }
          else
          {
            figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 1], points[0], points[1], points[2], tension));
            for (int idx = 1; idx < count - 2; idx++)
              figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[idx - 1], points[idx], points[idx + 1], points[idx + 2], tension));
            figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 3], points[count - 2], points[count - 1], points[0], tension));
            figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 2], points[count - 1], points[0], points[1], tension));
          }
          PathGeometry geo = new PathGeometry();
          geo.FillRule = fillmode == XFillMode.Alternate ? FillRule.EvenOdd : FillRule.Nonzero;
          geo.Figures.Add(figure);
          System.Windows.Media.Brush wpfBrush = brush != null ? brush.RealizeWpfBrush() : null;
          System.Windows.Media.Pen wpfPen = pen != null ? pen.RealizeWpfPen() : null;
          this.dc.DrawGeometry(wpfBrush, wpfPen, geo);
#else
          // AGHACK
#endif
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawClosedCurve(pen, brush, points, tension, fillmode);
    }
Esempio n. 6
0
    /// <summary>
    /// Draws a polygon defined by an array of points.
    /// </summary>
    public void DrawPolygon(XBrush brush, XPoint[] points, XFillMode fillmode)
    {
      if (brush == null)
        throw new ArgumentNullException("brush");
      if (points == null)
        throw new ArgumentNullException("points");
      if (points.Length < 2)
        throw new ArgumentException("points", PSSR.PointArrayAtLeast(2));

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
          this.gfx.FillPolygon(brush.RealizeGdiBrush(), MakePointFArray(points), (FillMode)fillmode);
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          this.dc.DrawGeometry(brush.RealizeWpfBrush(), null, GeometryHelper.CreatePolygonGeometry(MakePointArray(points), fillmode, true));
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawPolygon(null, brush, points, fillmode);
    }
Esempio n. 7
0
    /// <summary>
    /// Draws a polygon defined by an array of points.
    /// </summary>
    public void DrawPolygon(XPen pen, XBrush brush, XPoint[] points, XFillMode fillmode)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen and brush", PSSR.NeedPenOrBrush);
      if (points == null)
        throw new ArgumentNullException("points");
      if (points.Length < 2)
        throw new ArgumentException("points", PSSR.PointArrayAtLeast(2));

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          PointF[] pts = MakePointFArray(points);
          this.gfx.FillPolygon(brush.RealizeGdiBrush(), pts, (FillMode)fillmode);
          this.gfx.DrawPolygon(pen.RealizeGdiPen(), pts);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          System.Windows.Media.Brush wpfBrush = brush != null ? brush.RealizeWpfBrush() : null;
          System.Windows.Media.Pen wpfPen = brush != null ? pen.RealizeWpfPen() : null;
          this.dc.DrawGeometry(wpfBrush, wpfPen, GeometryHelper.CreatePolygonGeometry(MakePointArray(points), fillmode, true));
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawPolygon(pen, brush, points, fillmode);
    }
Esempio n. 8
0
    /// <summary>
    /// Draws an ellipse defined by a bounding rectangle.
    /// </summary>
    public void DrawEllipse(XBrush brush, double x, double y, double width, double height)
    {
      if (brush == null)
        throw new ArgumentNullException("brush");

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
          this.gfx.FillEllipse(brush.RealizeGdiBrush(), (float)x, (float)y, (float)width, (float)height);
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          double radiusX = width / 2;
          double radiusY = height / 2;
          this.dc.DrawEllipse(brush.RealizeWpfBrush(), null, new System.Windows.Point(x + radiusX, y + radiusY), radiusX, radiusY);
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawEllipse(null, brush, x, y, width, height);
    }
Esempio n. 9
0
    /// <summary>
    /// Draws an ellipse defined by a bounding rectangle.
    /// </summary>
    public void DrawEllipse(XPen pen, XBrush brush, double x, double y, double width, double height)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen and brush", PSSR.NeedPenOrBrush);

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          this.gfx.FillEllipse(brush.RealizeGdiBrush(), (float)x, (float)y, (float)width, (float)height);
          this.gfx.DrawArc(pen.RealizeGdiPen(), (float)x, (float)y, (float)width, (float)height, 0, 360);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          double radiusX = width / 2;
          double radiusY = height / 2;
          this.dc.DrawEllipse(brush.RealizeWpfBrush(), pen.RealizeWpfPen(), new System.Windows.Point(x + radiusX, y + radiusY), radiusX, radiusY);
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawEllipse(pen, brush, x, y, width, height);
    }
Esempio n. 10
0
    /// <summary>
    /// Draws a rectangles with round corners.
    /// </summary>
    public void DrawRoundedRectangle(XPen pen, XBrush brush, double x, double y, double width, double height,
      double ellipseWidth, double ellipseHeight)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen and brush", PSSR.NeedPenOrBrush);

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          XGraphicsPath path = new XGraphicsPath();
          path.AddRoundedRectangle(x, y, width, height, ellipseWidth, ellipseHeight);
          DrawPath(pen, brush, path);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          this.dc.DrawRoundedRectangle(
            brush != null ? brush.RealizeWpfBrush() : null,
            pen != null ? pen.RealizeWpfPen() : null,
            new Rect(x, y, width, height), ellipseWidth / 2, ellipseHeight / 2);
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawRoundedRectangle(pen, brush, x, y, width, height, ellipseWidth, ellipseHeight);
    }
Esempio n. 11
0
    /// <summary>
    /// Draws a series of rectangles.
    /// </summary>
    public void DrawRectangles(XPen pen, XBrush brush, XRect[] rectangles)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen and brush", PSSR.NeedPenOrBrush);
      if (rectangles == null)
        throw new ArgumentNullException("rectangles");

      int count = rectangles.Length;
      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          RectangleF[] rects = new RectangleF[count];
          for (int idx = 0; idx < count; idx++)
          {
            XRect rect = rectangles[idx];
            rects[idx] = new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height);
          }
          if (brush != null)
            this.gfx.FillRectangles(brush.RealizeGdiBrush(), rects);
          if (pen != null)
            this.gfx.DrawRectangles(pen.RealizeGdiPen(), rects);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          System.Windows.Media.Brush wpfBrush = brush != null ? brush.RealizeWpfBrush() : null;
          System.Windows.Media.Pen wpfPen = pen != null ? pen.RealizeWpfPen() : null;
          for (int idx = 0; idx < count; idx++)
          {
            XRect rect = rectangles[idx];
            this.dc.DrawRectangle(wpfBrush, wpfPen, new System.Windows.Rect(new System.Windows.Point(rect.x, rect.y), new System.Windows.Size(rect.width, rect.height)));
          }
        }
#endif
      }

      if (this.renderer != null)
      {
        for (int idx = 0; idx < count; idx++)
        {
          XRect rect = rectangles[idx];
          this.renderer.DrawRectangle(pen, brush, rect.X, rect.Y, rect.Width, rect.Height);
        }
      }
    }
Esempio n. 12
0
    /// <summary>
    /// Draws a rectangle.
    /// </summary>
    public void DrawRectangle(XPen pen, XBrush brush, double x, double y, double width, double height)
    {
      if (pen == null && brush == null)
        throw new ArgumentNullException("pen and brush", PSSR.NeedPenOrBrush);

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          this.gfx.FillRectangle(brush.RealizeGdiBrush(), (float)x, (float)y, (float)width, (float)height);
          this.gfx.DrawRectangle(pen.RealizeGdiPen(), (float)x, (float)y, (float)width, (float)height);
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
          this.dc.DrawRectangle(brush.RealizeWpfBrush(), pen.RealizeWpfPen(), new Rect(x, y, width, height));
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawRectangle(pen, brush, x, y, width, height);
    }
Esempio n. 13
0
    /// <summary>
    /// Draws a rectangle.
    /// </summary>
    public void DrawRectangle(XBrush brush, double x, double y, double width, double height)
    {
      if (brush == null)
        throw new ArgumentNullException("brush");

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
          this.gfx.FillRectangle(brush.RealizeGdiBrush(), (float)x, (float)y, (float)width, (float)height);
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
          this.dc.DrawRectangle(brush.RealizeWpfBrush(), null, new Rect(x, y, width, height));
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawRectangle(null, brush, x, y, width, height);
    }
Esempio n. 14
0
    public void DrawString(XGraphics gfx, string text, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format)
    {
      double x = layoutRectangle.X;
      double y = layoutRectangle.Y;

      double lineSpace = font.GetHeight(gfx);
      double cyAscent = lineSpace * font.cellAscent / font.cellSpace;
      double cyDescent = lineSpace * font.cellDescent / font.cellSpace;

      bool bold = (font.Style & XFontStyle.Bold) != 0;
      bool italic = (font.Style & XFontStyle.Italic) != 0;
      bool strikeout = (font.Style & XFontStyle.Strikeout) != 0;
      bool underline = (font.Style & XFontStyle.Underline) != 0;

      //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"), // WPFHACK
      //  FlowDirection.LeftToRight, font.typeface, font.Size, brush.RealizeWpfBrush());
      TextBlock textBlock = FontHelper.CreateTextBlock(text, null, font.Size, brush.RealizeWpfBrush());

      Canvas.SetLeft(textBlock, x);
      Canvas.SetTop(textBlock, y);

      //formattedText.SetTextDecorations(TextDecorations.OverLine);
      switch (format.Alignment)
      {
        case XStringAlignment.Near:
          // nothing to do, this is the default
          //formattedText.TextAlignment = TextAlignment.Left;
          break;

        case XStringAlignment.Center:
          x += layoutRectangle.Width / 2;
          textBlock.TextAlignment = TextAlignment.Center;
          break;

        case XStringAlignment.Far:
          x += layoutRectangle.Width;
          textBlock.TextAlignment = TextAlignment.Right;
          break;
      }
      if (gfx.PageDirection == XPageDirection.Downwards)
      {
        switch (format.LineAlignment)
        {
          case XLineAlignment.Near:
            //y += cyAscent;
            break;

          //case XLineAlignment.Center:
          //  // TODO use CapHeight. PDFlib also uses 3/4 of ascent
          //  y += -formattedText.Baseline + (cyAscent * 1 / 3) + layoutRectangle.Height / 2;
          //  //y += -formattedText.Baseline + (font.Size * font.Metrics.CapHeight / font.unitsPerEm / 2) + layoutRectangle.Height / 2;
          //  break;

          //case XLineAlignment.Far:
          //  y += -formattedText.Baseline - cyDescent + layoutRectangle.Height;
          //  break;

          //case XLineAlignment.BaseLine:
          //  y -= formattedText.Baseline;
          //  break;
        }
      }
      else
      {
        // TODOWPF: make unit test
        switch (format.LineAlignment)
        {
          case XLineAlignment.Near:
            //y += cyDescent;
            break;

          case XLineAlignment.Center:
            // TODO use CapHeight. PDFlib also uses 3/4 of ascent
            //y += -(cyAscent * 3 / 4) / 2 + rect.Height / 2;
            break;

          case XLineAlignment.Far:
            //y += -cyAscent + rect.Height;
            break;

          case XLineAlignment.BaseLine:
            // nothing to do
            break;
        }
      }

      //if (bold && !descriptor.IsBoldFace)
      //{
      //  // TODO: emulate bold by thicker outline
      //}

      //if (italic && !descriptor.IsBoldFace)
      //{
      //  // TODO: emulate italic by shearing transformation
      //}

      //if (underline)
      //{
      //  formattedText.FontStyle.SetTextDecorations(TextDecorations.Underline);
      //  //double underlinePosition = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlinePosition / font.cellSpace;
      //  //double underlineThickness = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlineThickness / font.cellSpace;
      //  //DrawRectangle(null, brush, x, y - underlinePosition, width, underlineThickness);
      //}

      //if (strikeout)
      //{
      //  formattedText.SetTextDecorations(TextDecorations.Strikethrough);
      //  //double strikeoutPosition = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutPosition / font.cellSpace;
      //  //double strikeoutSize = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutSize / font.cellSpace;
      //  //DrawRectangle(null, brush, x, y - strikeoutPosition - strikeoutSize, width, strikeoutSize);
      //}

      //formattedText 
      _canvas.Children.Add(textBlock);
    }