예제 #1
0
파일: FontData.cs 프로젝트: GNOME/pdfmod
    /// <summary>
    /// Initializes a new instance of the <see cref="FontData"/> class.
    /// </summary>
    public FontData(XFont font, XPdfFontOptions options)
    {
#if GDI && !WPF
      CreateGdiFontImage(font, options, font.privateFontCollection);
#endif
#if WPF && !GDI
      CreateWpfFontData(font, options);
#endif
#if WPF && GDI
      System.Drawing.Font gdiFont = font.RealizeGdiFont();
      if (font.font != null)
        CreateGdiFontImage(font, options, font.privateFontCollection);
      else if (font.typeface != null)
        CreateWpfFontData(font, options);
#endif
      if (this.data == null)
        throw new InvalidOperationException("Cannot allocate font image.");
      Read();
    }
예제 #2
0
    // ----- MeasureString ------------------------------------------------------------------------

    /// <summary>
    /// Measures the specified string when drawn with the specified font.
    /// </summary>
    public XSize MeasureString(string text, XFont font, XStringFormat stringFormat)
    {
      // TODO: Here comes a lot of code in the future: kerning etc...
      if (text == null)
        throw new ArgumentNullException("text");
      if (font == null)
        throw new ArgumentNullException("font");
      if (stringFormat == null)
        throw new ArgumentNullException("stringFormat");

#if GDI && !WPF
      return XSize.FromSizeF(this.gfx.MeasureString(text, font.RealizeGdiFont(), new PointF(0, 0), stringFormat.RealizeGdiStringFormat()));
#endif
#if WPF && !GDI
#if !SILVERLIGHT
      //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"),
      //  FlowDirection.LeftToRight, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
      FormattedText formattedText = FontHelper.CreateFormattedText(text, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
      return new XSize(formattedText.WidthIncludingTrailingWhitespace, formattedText.Height);
#else
      return dc.MeasureString(this, text, font, stringFormat);
#endif

#endif
#if WPF && GDI
      if (this.targetContext == XGraphicTargetContext.GDI)
      {
        XSize gdiSize = XSize.FromSizeF(this.gfx.MeasureString(text, font.RealizeGdiFont(), new PointF(0, 0), stringFormat.RealizeGdiStringFormat()));
#if DEBUG
        Debug.WriteLine(gdiSize);
#endif
        return gdiSize;
      }
      if (this.targetContext == XGraphicTargetContext.WPF)
      {
        //double h = font.Height;
        //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"),
        //  FlowDirection.LeftToRight, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
        FormattedText formattedText = FontHelper.CreateFormattedText(text, font.typeface, font.Size, System.Windows.Media.Brushes.Black);

        XSize wpfSize = new XSize(formattedText.WidthIncludingTrailingWhitespace, formattedText.Height);
#if DEBUG
        Debug.WriteLine(wpfSize);
#endif
        return wpfSize;
      }
      Debug.Assert(false);
      return XSize.Empty;
#endif
    }
예제 #3
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);
    }
예제 #4
0
    // ----- MeasureString ------------------------------------------------------------------------

    /// <summary>
    /// Measures the specified string when drawn with the specified font.
    /// </summary>
    public XSize MeasureString(string text, XFont font, XStringFormat stringFormat)
    {
      // TODO: Here comes a lot of code in the future: kerning etc...
      if (text == null)
        throw new ArgumentNullException("text");
      if (font == null)
        throw new ArgumentNullException("font");
      if (stringFormat == null)
        throw new ArgumentNullException("stringFormat");

      return XSize.FromSizeF(this.gfx.MeasureString(text, font.RealizeGdiFont(), new PointF(0, 0), stringFormat.RealizeGdiStringFormat()));
    }
예제 #5
0
    /// <summary>
    /// Draws the specified text string.
    /// </summary>
    public void DrawString(string s, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format)
    {
      if (s == null)
        throw new ArgumentNullException("s");
      if (font == null)
        throw new ArgumentNullException("font");
      if (brush == null)
        throw new ArgumentNullException("brush");

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

      if (s.Length == 0)
        return;

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

      if (this.drawGraphics)
      {
        RectangleF rect = layoutRectangle.ToRectangleF();
        if (format.LineAlignment == XLineAlignment.BaseLine)
        {
          // TODO optimze
          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(s, font.RealizeGdiFont(), brush.RealizeGdiBrush(), rect,
          format != null ? format.RealizeGdiStringFormat() : null);
      }

      if (this.renderer != null)
        this.renderer.DrawString(s, font, brush, layoutRectangle, format);
    }
    //internal TrueTypeDescriptor(FontSelector selector)
    //{
    //  throw new NotImplementedException("TrueTypeDescriptor(FontSelector selector)");
    //}

    internal TrueTypeDescriptor(XFont font)
      : this(font.RealizeGdiFont(), font.PdfOptions)
    { }
예제 #7
0
파일: FontData.cs 프로젝트: GNOME/pdfmod
    /// <summary>
    /// Create the font image using GDI+ functionality.
    /// </summary>
    void CreateGdiFontImage(XFont font, XPdfFontOptions options, XPrivateFontCollection privateFontCollection)
    {
      System.Drawing.Font gdiFont = font.RealizeGdiFont();
      NativeMethods.LOGFONT logFont;
#if DEBUG_
      logFont = new NativeMethods.LOGFONT();
      gdiFont.ToLogFont(logFont);
      Debug.WriteLine("FontData: " + logFont.lfFaceName);
#endif
      this.data = null;
      if (privateFontCollection != null)
      {
        //XPrivateFont privateFont = privateFontCollection.FindFont(logFont.lfFaceName, logFont.lfWeight >= 700, logFont.lfItalic > 0);
        XPrivateFont privateFont = privateFontCollection.FindFont(font.Name, font.Bold, font.Italic);
        if (privateFont != null)
        {
          int size = privateFont.GetFontData(ref this.data, 0);
          if (size > 0)
          {
            this.data = new byte[size];
            privateFont.GetFontData(ref this.data, size);
          }
        }
      }
      if (this.data == null)
      {
        int error;
        IntPtr hfont = gdiFont.ToHfont();
        IntPtr hdc = NativeMethods.GetDC(IntPtr.Zero);
        error = Marshal.GetLastWin32Error();
        IntPtr oldFont = NativeMethods.SelectObject(hdc, hfont);
        error = Marshal.GetLastWin32Error();
        // size is exactly the size of the font file.
        int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
        error = Marshal.GetLastWin32Error();
        if (size > 0)
        {
          this.data = new byte[size];
          int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
          Debug.Assert(size == effectiveSize);
          NativeMethods.SelectObject(hdc, oldFont);
          NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
          error.GetType();
        }
        else
        {
        // Sometimes size is -1 (GDI_ERROR), but I cannot determine why. It happens only with the font 'Symbol'.
        // The issue occurs the first time in early 2005, when I start writing PDFsharp. I could not fix it and after
        // some code refactoring the problem disappears.
        // There was never a report from anyone about this issue.
        // Now I get it again (while debugging QBX 2006). Maybe it is a problem with my PC at my home office.
        // As a work-around I create a new font handle with a different height value. This works. Maybe the
        // font file gets locked somewhere. Very very strange.

        // IF SOMEONE ELSE COMES HERE PLEASE LET ME KNOW!

        // Clean up old handles
        NativeMethods.SelectObject(hdc, oldFont);
        NativeMethods.ReleaseDC(IntPtr.Zero, hdc);

        // Try again with new font handle
        logFont = new NativeMethods.LOGFONT();
        gdiFont.ToLogFont(logFont);
        logFont.lfHeight += 1; // force new handle
        IntPtr hfont2 = NativeMethods.CreateFontIndirect(logFont);
        hdc = NativeMethods.GetDC(IntPtr.Zero);
        error = Marshal.GetLastWin32Error();
        oldFont = NativeMethods.SelectObject(hdc, hfont2);
        error = Marshal.GetLastWin32Error();
        // size is exactly the size of the font file.
        size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
        error = Marshal.GetLastWin32Error();
        if (size > 0)
        {
          this.data = new byte[size];
          int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
          Debug.Assert(size == effectiveSize);
        }
        NativeMethods.SelectObject(hdc, oldFont);
        NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
        NativeMethods.DeleteObject(hfont2);
        error.GetType();
        }
      }
      if (this.data == null)
        throw new InvalidOperationException("Internal error. Font data could not retrieved.");
    }
예제 #8
0
파일: FontData.cs 프로젝트: DavidS/MigraDoc
    /// <summary>
    /// Create the font image using GDI+ functionality.
    /// </summary>
    void CreateGdiFontImage(XFont font, XPdfFontOptions options/*, XPrivateFontCollection privateFontCollection*/)
    {
      System.Drawing.Font gdiFont = font.RealizeGdiFont();
#if DEBUG_
      logFont = new NativeMethods.LOGFONT();
      gdiFont.ToLogFont(logFont);
      Debug.WriteLine("FontData: " + logFont.lfFaceName);
#endif
      this.data = null;

      // PFC
      //if (privateFontCollection != null)
      //{
      //  //XPrivateFont privateFont = privateFontCollection.FindFont(logFont.lfFaceName, logFont.lfWeight >= 700, logFont.lfItalic > 0);
      //  XGlyphTypeface privateFont = privateFontCollection.FindFont(font.Name, font.Bold, font.Italic);
      //  if (privateFont != null)
      //  {
      //    //////int size = privateFont.GetData(ref this.data);
      //    //////if (size > 0)
      //    //////{
      //    //////  this.data = new byte[size];
      //    //////  privateFont.GetData(ref this.data, size);
      //    //////}
      //  }
      //}
      if (this.data == null)
      {
        var assembly = FontDataConfig.ResourceAssembly;
        var name = string.Format("{0}.FontHacks.{1}{2}{3}.fontdat",
            assembly != null ? assembly.GetName().Name : string.Empty,
            font.Name,
            font.Bold ? ".Bold" : string.Empty,
            font.Italic ? ".Italic" : string.Empty);
        if (assembly != null && new List<string>(assembly.GetManifestResourceNames()).Contains(name))
        {
          System.Diagnostics.Debug.WriteLine("*** Reading fontdata from Resource");
          using (var s = assembly.GetManifestResourceStream(name))
          {
            this.data = new byte[s.Length];
            s.Read(this.data, 0, (int)s.Length);
          }
        }
        else
        {
          System.Diagnostics.Debug.WriteLine("*** Reading fontdata from GDI+");
          int error;
          IntPtr hfont = gdiFont.ToHfont();
          using(var dcBmp = new Bitmap(100, 100))
          using (var dc = Graphics.FromImage(dcBmp))
          {
              IntPtr hdc = dc.GetHdc();
              error = Marshal.GetLastWin32Error();
              IntPtr oldFont = NativeMethods.SelectObject(hdc, hfont);
              error = Marshal.GetLastWin32Error();
              // size is exactly the size of the font file.
              int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
              error = Marshal.GetLastWin32Error();
              if (size > 0)
              {
                  this.data = new byte[size];
                  int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
                  Debug.Assert(size == effectiveSize);
                  if (FontDataConfig.SaveFont)
                  {
                      FileExtensions.WriteFileBytes(this.data, string.Format("..\\..\\FontHacks\\{0}{1}{2}.fontdat",
                          font.Name,
                          font.Bold ? ".Bold" : string.Empty,
                          font.Italic ? ".Italic" : string.Empty));
                  }
                  NativeMethods.SelectObject(hdc, oldFont);
                  NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
                  error.GetType();
              }
              else
              {
                  // Sometimes size is -1 (GDI_ERROR), but I cannot determine why. It happens only with the font 'Symbol'.
                  // The issue occurs the first time in early 2005, when I start writing PDFsharp. I could not fix it and after
                  // some code refactoring the problem disappears.
                  // There was never a report from anyone about this issue.
                  // Now I get it again (while debugging QBX 2006). Maybe it is a problem with my PC at my home office.
                  // As a work-around I create a new font handle with a different height value. This works. Maybe the
                  // font file gets locked somewhere. Very very strange.

                  // IF SOMEONE ELSE COMES HERE PLEASE LET ME KNOW!

                  // Clean up old handles
                  NativeMethods.SelectObject(hdc, oldFont);
                  NativeMethods.ReleaseDC(IntPtr.Zero, hdc);

                  // Try again with new font handle
                  var logFont = new NativeMethods.LOGFONT();
                  gdiFont.ToLogFont(logFont);
                  logFont.lfHeight += 1; // force new handle
                  IntPtr hfont2 = NativeMethods.CreateFontIndirect(logFont);
                  hdc = NativeMethods.GetDC(IntPtr.Zero);
                  error = Marshal.GetLastWin32Error();
                  oldFont = NativeMethods.SelectObject(hdc, hfont2);
                  error = Marshal.GetLastWin32Error();
                  // size is exactly the size of the font file.
                  size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
                  error = Marshal.GetLastWin32Error();
                  if (size > 0)
                  {
                      this.data = new byte[size];
                      int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
                      Debug.Assert(size == effectiveSize);
                  }
                  NativeMethods.SelectObject(hdc, oldFont);
                  NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
                  NativeMethods.DeleteObject(hfont2);
                  error.GetType();
              }
          }
        }
        if (this.data == null)
          throw new InvalidOperationException("Internal error. Font data could not retrieved.");
      }
    }