Exemple #1
0
        internal static string ComputeKey(GdiFont gdiFont)
        {
            string name1 = gdiFont.Name;
            string name2 = gdiFont.OriginalFontName;
            string name3 = gdiFont.SystemFontName;

            string       name  = name1;
            GdiFontStyle style = gdiFont.Style;

            string key = KeyPrefix + name.ToLowerInvariant() + ((style & GdiFontStyle.Italic) == GdiFontStyle.Italic ? "/i" : "/n") + ((style & GdiFontStyle.Bold) == GdiFontStyle.Bold ? "/700" : "/400") + "/5"; // Stretch.Normal

            return(key);
        }
Exemple #2
0
        //internal static XGlyphTypeface TryGetXGlyphTypeface(string familyName, XFontStyle style)
        //{
        //    string name = MakeName(familyName, style);

        //    XGlyphTypeface typeface;
        //    _global._typefaces.TryGetValue(name, out typeface);
        //    return typeface;
        //}

#if GDI
        internal static GdiFont TryCreateFont(string name, double size, GdiFontStyle style, out XFontSource fontSource)
        {
            fontSource = null;
            try
            {
                GdiPrivateFontCollection pfc = Singleton._privateFontCollection;
                if (pfc == null)
                {
                    return(null);
                }
#if true
                string key = MakeKey(name, (XFontStyle)style);
                if (Singleton._fontSources.TryGetValue(key, out fontSource))
                {
                    GdiFont font = new GdiFont(name, (float)size, style, GraphicsUnit.World);
#if DEBUG_
                    Debug.Assert(StringComparer.OrdinalIgnoreCase.Compare(name, font.Name) == 0);
                    Debug.Assert(font.Bold == ((style & GdiFontStyle.Bold) != 0));
                    Debug.Assert(font.Italic == ((style & GdiFontStyle.Italic) != 0));
#endif
                    return(font);
                }
                return(null);
#else
                foreach (GdiFontFamily family in pfc.Families)
                {
                    if (string.Compare(family.Name, name, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        GdiFont font = new GdiFont(family, (float)size, style, GraphicsUnit.World);
                        if (string.Compare(font.Name, name, StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            // Style simulation is not implemented in GDI+.
                            // Use WPF build.
                        }
                        return(font);
                    }
                }
#endif
            }
            catch (Exception ex)
            {
                // Ignore exception and return null.
                Debug.WriteLine(ex.ToString());
            }
            return(null);
        }
Exemple #3
0
        public static GdiFont CreateFont(string familyName, double emSize, GdiFontStyle style, out XFontSource fontSource)
        {
            fontSource = null;
            // ReSharper disable once JoinDeclarationAndInitializer
            GdiFont font;

            // Use font resolver in CORE build. XPrivateFontCollection exists only in GDI and WPF build.
#if GDI
            // Try private font collection first.
            font = XPrivateFontCollection.TryCreateFont(familyName, emSize, style, out fontSource);
            if (font != null)
            {
                // Get font source is different for this font because Win32 does not know it.
                return(font);
            }
#endif
            // Create ordinary Win32 font.
            font = new GdiFont(familyName, (float)emSize, style, GraphicsUnit.World);
            return(font);
        }
Exemple #4
0
        private SizeF MeasureString(string s, StyleInfo si, Graphics g, out float descent)
        {
            Font         drawFont   = null;
            StringFormat drawFormat = null;
            SizeF        ms         = SizeF.Empty;

            descent = 0;
            if (s == null || s.Length == 0)
            {
                return(ms);
            }
            try
            {
                // STYLE
                System.DrawingCore.FontStyle fs = 0;
                if (si.FontStyle == FontStyleEnum.Italic)
                {
                    fs |= System.DrawingCore.FontStyle.Italic;
                }

                // WEIGHT
                switch (si.FontWeight)
                {
                case FontWeightEnum.Bold:
                case FontWeightEnum.Bolder:
                case FontWeightEnum.W500:
                case FontWeightEnum.W600:
                case FontWeightEnum.W700:
                case FontWeightEnum.W800:
                case FontWeightEnum.W900:
                    fs |= System.DrawingCore.FontStyle.Bold;
                    break;

                default:
                    break;
                }
                try
                {
                    FontFamily ff = si.GetFontFamily();
                    drawFont = new Font(ff, si.FontSize, fs);
                    // following algorithm comes from the C# Font Metrics documentation
                    float descentPixel = si.FontSize * ff.GetCellDescent(fs) / ff.GetEmHeight(fs);
                    descent = RSize.PointsFromPixels(g, descentPixel);
                }
                catch
                {
                    drawFont = new Font("Arial", si.FontSize, fs);                      // usually because font not found
                    descent  = 0;
                }
                drawFormat           = new StringFormat();
                drawFormat.Alignment = StringAlignment.Near;

                CharacterRange[] cr = { new CharacterRange(0, s.Length) };
                drawFormat.SetMeasurableCharacterRanges(cr);
                Region[] rs = new Region[1];
                rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0, 0, float.MaxValue, float.MaxValue),
                                              drawFormat);
                RectangleF mr = rs[0].GetBounds(g);

                ms.Height = RSize.PointsFromPixels(g, mr.Height);                       // convert to points from pixels
                ms.Width  = RSize.PointsFromPixels(g, mr.Width);                        // convert to points from pixels
                return(ms);
            }
            finally
            {
                if (drawFont != null)
                {
                    drawFont.Dispose();
                }
                if (drawFormat != null)
                {
                    drawFont.Dispose();
                }
            }
        }
Exemple #5
0
        private string[] MeasureString(PageText pt, Graphics g, out float[] width)
        {
            StyleInfo si = pt.SI;
            string    s  = pt.Text;

            System.DrawingCore.Font drawFont   = null;
            StringFormat            drawFormat = null;
            SizeF ms;

            string[] sa = null;
            width = null;
            try
            {
                // STYLE
                System.DrawingCore.FontStyle fs = 0;
                if (si.FontStyle == FontStyleEnum.Italic)
                {
                    fs |= System.DrawingCore.FontStyle.Italic;
                }

                // WEIGHT
                switch (si.FontWeight)
                {
                case FontWeightEnum.Bold:
                case FontWeightEnum.Bolder:
                case FontWeightEnum.W500:
                case FontWeightEnum.W600:
                case FontWeightEnum.W700:
                case FontWeightEnum.W800:
                case FontWeightEnum.W900:
                    fs |= System.DrawingCore.FontStyle.Bold;
                    break;

                default:
                    break;
                }

                drawFont             = new System.DrawingCore.Font(StyleInfo.GetFontFamily(si.FontFamilyFull), si.FontSize, fs);
                drawFormat           = new StringFormat();
                drawFormat.Alignment = StringAlignment.Near;

                // Measure string
                //  pt.NoClip indicates that this was generated by PageTextHtml Build.  It has already word wrapped.
                if (pt.NoClip || pt.SI.WritingMode == WritingModeEnum.tb_rl)    // TODO: support multiple lines for vertical text
                {
                    ms       = MeasureString(s, g, drawFont, drawFormat);
                    width    = new float[1];
                    width[0] = Measurement.PointsFromPixels(ms.Width, g.DpiX);  // convert to points from pixels
                    sa       = new string[1];
                    sa[0]    = s;
                    return(sa);
                }

                // handle multiple lines;
                //  1) split the string into the forced line breaks (ie "\n and \r")
                //  2) foreach of the forced line breaks; break these into words and recombine
                s = s.Replace("\r\n", "\n");    // don't want this to result in double lines
                string[]      flines     = s.Split(LINEBREAK);
                List <string> lines      = new List <string>();
                List <float>  lineWidths = new List <float>();
                // remove the size reserved for left and right padding
                float ptWidth = pt.W - pt.SI.PaddingLeft - pt.SI.PaddingRight;
                if (ptWidth <= 0)
                {
                    ptWidth = 1;
                }
                foreach (string tfl in flines)
                {
                    string fl;
                    if (tfl.Length > 0 && tfl[tfl.Length - 1] == ' ')
                    {
                        fl = tfl.TrimEnd(' ');
                    }
                    else
                    {
                        fl = tfl;
                    }

                    // Check if entire string fits into a line
                    ms = MeasureString(fl, g, drawFont, drawFormat);
                    float tw = Measurement.PointsFromPixels(ms.Width, g.DpiX);
                    if (tw <= ptWidth)
                    {                                      // line fits don't need to break it down further
                        lines.Add(fl);
                        lineWidths.Add(tw);
                        continue;
                    }

                    // Line too long; need to break into multiple lines
                    // 1) break line into parts; then build up again keeping track of word positions
                    string[]         parts = fl.Split(WORDBREAK); // this is the maximum split of lines
                    StringBuilder    sb    = new StringBuilder(fl.Length);
                    CharacterRange[] cra   = new CharacterRange[parts.Length];
                    for (int i = 0; i < parts.Length; i++)
                    {
                        int sc = sb.Length;        // starting character
                        sb.Append(parts[i]);       // endding character
                        if (i != parts.Length - 1) // last item doesn't need blank
                        {
                            sb.Append(" ");
                        }
                        int            ec = sb.Length;
                        CharacterRange cr = new CharacterRange(sc, ec - sc);
                        cra[i] = cr;                    // add to character array
                    }

                    // 2) Measure the word locations within the line
                    string            wfl           = sb.ToString();
                    WordStartFinish[] wordLocations = MeasureString(wfl, g, drawFont, drawFormat, cra);
                    if (wordLocations == null)
                    {
                        continue;
                    }

                    // 3) Loop thru creating new lines as needed
                    int            startLoc = 0;
                    CharacterRange crs      = cra[startLoc];
                    CharacterRange cre      = cra[startLoc];
                    float          cwidth   = wordLocations[0].end;   // length of the first
                    float          bwidth   = wordLocations[0].start; // characters need a little extra on start
                    string         ts;
                    bool           bLine = true;
                    for (int i = 1; i < cra.Length; i++)
                    {
                        cwidth = wordLocations[i].end - wordLocations[startLoc].start + bwidth;
                        if (cwidth > ptWidth)
                        {       // time for a new line
                            cre = cra[i - 1];
                            ts  = wfl.Substring(crs.First, cre.First + cre.Length - crs.First);
                            lines.Add(ts);
                            lineWidths.Add(wordLocations[i - 1].end - wordLocations[startLoc].start + bwidth);

                            // Find the first non-blank character of the next line
                            while (i < cra.Length &&
                                   cra[i].Length == 1 &&
                                   fl[cra[i].First] == ' ')
                            {
                                i++;
                            }
                            if (i < cra.Length) // any lines left?
                            {                   // yes, continue on
                                startLoc = i;
                                crs      = cre = cra[startLoc];
                                cwidth   = wordLocations[i].end - wordLocations[startLoc].start + bwidth;
                            }
                            else  // no, we can stop
                            {
                                bLine = false;
                            }
                            //  bwidth = wordLocations[startLoc].start - wordLocations[startLoc - 1].end;
                        }
                        else
                        {
                            cre = cra[i];
                        }
                    }
                    if (bLine)
                    {
                        ts = fl.Substring(crs.First, cre.First + cre.Length - crs.First);
                        lines.Add(ts);
                        lineWidths.Add(cwidth);
                    }
                }
                // create the final array from the Lists
                string[] la = lines.ToArray();
                width = lineWidths.ToArray();
                return(la);
            }
            finally
            {
                if (drawFont != null)
                {
                    drawFont.Dispose();
                }
                if (drawFormat != null)
                {
                    drawFont.Dispose();
                }
            }
        }
Exemple #6
0
        private void DrawString(PageText pt, Graphics g, RectangleF r)
        {
            StyleInfo si = pt.SI;
            string    s  = pt.Text;

            Font         drawFont   = null;
            StringFormat drawFormat = null;
            Brush        drawBrush  = null;

            try
            {
                // STYLE
                System.DrawingCore.FontStyle fs = 0;
                if (si.FontStyle == FontStyleEnum.Italic)
                {
                    fs |= System.DrawingCore.FontStyle.Italic;
                }

                switch (si.TextDecoration)
                {
                case TextDecorationEnum.Underline:
                    fs |= System.DrawingCore.FontStyle.Underline;
                    break;

                case TextDecorationEnum.LineThrough:
                    fs |= System.DrawingCore.FontStyle.Strikeout;
                    break;

                case TextDecorationEnum.Overline:
                case TextDecorationEnum.None:
                    break;
                }

                // WEIGHT
                switch (si.FontWeight)
                {
                case FontWeightEnum.Bold:
                case FontWeightEnum.Bolder:
                case FontWeightEnum.W500:
                case FontWeightEnum.W600:
                case FontWeightEnum.W700:
                case FontWeightEnum.W800:
                case FontWeightEnum.W900:
                    fs |= System.DrawingCore.FontStyle.Bold;
                    break;

                default:
                    break;
                }
                try
                {
                    drawFont = new Font(si.GetFontFamily(), si.FontSize, fs);   // si.FontSize already in points
                }
                catch (ArgumentException)
                {
                    drawFont = new Font("Arial", si.FontSize, fs);   // if this fails we'll let the error pass thru
                }
                // ALIGNMENT
                drawFormat = new StringFormat();
                switch (si.TextAlign)
                {
                case TextAlignEnum.Right:
                    drawFormat.Alignment = StringAlignment.Far;
                    break;

                case TextAlignEnum.Center:
                    drawFormat.Alignment = StringAlignment.Center;
                    break;

                case TextAlignEnum.Left:
                default:
                    drawFormat.Alignment = StringAlignment.Near;
                    break;
                }
                if (pt.SI.WritingMode == WritingModeEnum.tb_rl)
                {
                    drawFormat.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
                    drawFormat.FormatFlags |= StringFormatFlags.DirectionVertical;
                }
                switch (si.VerticalAlign)
                {
                case VerticalAlignEnum.Bottom:
                    drawFormat.LineAlignment = StringAlignment.Far;
                    break;

                case VerticalAlignEnum.Middle:
                    drawFormat.LineAlignment = StringAlignment.Center;
                    break;

                case VerticalAlignEnum.Top:
                default:
                    drawFormat.LineAlignment = StringAlignment.Near;
                    break;
                }
                // draw the background
                DrawBackground(g, r, si);

                // adjust drawing rectangle based on padding
                RectangleF r2 = new RectangleF(r.Left + si.PaddingLeft,
                                               r.Top + si.PaddingTop,
                                               r.Width - si.PaddingLeft - si.PaddingRight,
                                               r.Height - si.PaddingTop - si.PaddingBottom);

                drawBrush = new SolidBrush(si.Color);
                if (pt.NoClip)   // request not to clip text
                {
                    g.DrawString(pt.Text, drawFont, drawBrush, new PointF(r.Left, r.Top), drawFormat);
                    //HighlightString(g, pt, new RectangleF(r.Left, r.Top, float.MaxValue, float.MaxValue),drawFont, drawFormat);
                }
                else
                {
                    g.DrawString(pt.Text, drawFont, drawBrush, r2, drawFormat);
                    //HighlightString(g, pt, r2, drawFont, drawFormat);
                }
            }
            finally
            {
                if (drawFont != null)
                {
                    drawFont.Dispose();
                }
                if (drawFormat != null)
                {
                    drawFont.Dispose();
                }
                if (drawBrush != null)
                {
                    drawBrush.Dispose();
                }
            }
        }
Exemple #7
0
        private void DrawString(PageText pt, Graphics g, RectangleF r)
        {
            StyleInfo si = pt.SI;
            string    s  = pt.Text;

            Font         drawFont   = null;
            StringFormat drawFormat = null;
            Brush        drawBrush  = null;

            try
            {
                // STYLE
                System.DrawingCore.FontStyle fs = 0;
                if (si.FontStyle == FontStyleEnum.Italic)
                {
                    fs |= System.DrawingCore.FontStyle.Italic;
                }

                switch (si.TextDecoration)
                {
                case TextDecorationEnum.Underline:
                    fs |= System.DrawingCore.FontStyle.Underline;
                    break;

                case TextDecorationEnum.LineThrough:
                    fs |= System.DrawingCore.FontStyle.Strikeout;
                    break;

                case TextDecorationEnum.Overline:
                case TextDecorationEnum.None:
                    break;
                }

                // WEIGHT
                switch (si.FontWeight)
                {
                case FontWeightEnum.Bold:
                case FontWeightEnum.Bolder:
                case FontWeightEnum.W500:
                case FontWeightEnum.W600:
                case FontWeightEnum.W700:
                case FontWeightEnum.W800:
                case FontWeightEnum.W900:
                    fs |= System.DrawingCore.FontStyle.Bold;
                    break;

                default:
                    break;
                }
                try
                {
                    drawFont = new Font(si.GetFontFamily(), si.FontSize, fs);   // si.FontSize already in points
                }
                catch (ArgumentException)
                {
                    drawFont = new Font("Arial", si.FontSize, fs);      // if this fails we'll let the error pass thru
                }
                // ALIGNMENT
                drawFormat = new StringFormat();
                switch (si.TextAlign)
                {
                case TextAlignEnum.Right:
                    drawFormat.Alignment = StringAlignment.Far;
                    break;

                case TextAlignEnum.Center:
                    drawFormat.Alignment = StringAlignment.Center;
                    break;

                case TextAlignEnum.Left:
                default:
                    drawFormat.Alignment = StringAlignment.Near;
                    break;
                }
                if (pt.SI.WritingMode == WritingModeEnum.tb_rl)
                {
                    drawFormat.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
                    drawFormat.FormatFlags |= StringFormatFlags.DirectionVertical;
                }
                switch (si.VerticalAlign)
                {
                case VerticalAlignEnum.Bottom:
                    drawFormat.LineAlignment = StringAlignment.Far;
                    break;

                case VerticalAlignEnum.Middle:
                    drawFormat.LineAlignment = StringAlignment.Center;
                    break;

                case VerticalAlignEnum.Top:
                default:
                    drawFormat.LineAlignment = StringAlignment.Near;
                    break;
                }
                // draw the background
                DrawBackground(g, r, si);

                // adjust drawing rectangle based on padding
                // http://www.fyireporting.com/forum/viewtopic.php?t=892
                //A.S.> convert pt to px if needed(when printing we need px, when draw preview - pt)
                RectangleF r2;
                if (g.PageUnit == GraphicsUnit.Pixel)
                {
                    r2 = new RectangleF(r.Left + (si.PaddingLeft * g.DpiX) / 72,
                                        r.Top + (si.PaddingTop * g.DpiX) / 72,
                                        r.Width - ((si.PaddingLeft + si.PaddingRight) * g.DpiX) / 72,
                                        r.Height - ((si.PaddingTop + si.PaddingBottom) * g.DpiX) / 72);
                }
                else
                {
                    // adjust drawing rectangle based on padding
                    r2 = new RectangleF(r.Left + si.PaddingLeft,
                                        r.Top + si.PaddingTop,
                                        r.Width - si.PaddingLeft - si.PaddingRight,
                                        r.Height - si.PaddingTop - si.PaddingBottom);
                }

                drawBrush = new SolidBrush(si.Color);
                if (si.TextAlign == TextAlignEnum.Justified)
                {
                    //todo: .net core port
                    //System.Drawing.GraphicsExtended.DrawStringJustified((System.Drawing.Graphics)g, pt.Text, drawFont, drawBrush, r2);
                }
                else if (pt.NoClip)     // request not to clip text
                {
                    g.DrawString(pt.Text, drawFont, drawBrush, new PointF(r.Left, r.Top), drawFormat);
                    //HighlightString(g, pt, new RectangleF(r.Left, r.Top, float.MaxValue, float.MaxValue),
                    //    drawFont, drawFormat);
                }
                else
                {
                    g.DrawString(pt.Text, drawFont, drawBrush, r2, drawFormat);
                    //HighlightString(g, pt, r2, drawFont, drawFormat);
                }
                //if (SelectTool)
                //{
                //    if (pt.AllowSelect && _SelectList.Contains(pt))
                //        g.FillRectangle(new SolidBrush(Color.FromArgb(50, _SelectItemColor)), r2);
                //}
            }
            finally
            {
                if (drawFont != null)
                {
                    drawFont.Dispose();
                }
                if (drawFormat != null)
                {
                    drawFont.Dispose();
                }
                if (drawBrush != null)
                {
                    drawBrush.Dispose();
                }
            }
        }
        /// <summary>
        /// Create a GDI+ font and use its handle to retrieve font data using native calls.
        /// </summary>
        internal static XFontSource CreateFontSource(string familyName, FontResolvingOptions fontResolvingOptions, out GdiFont font, string typefaceKey)
        {
            if (String.IsNullOrEmpty(typefaceKey))
            {
                typefaceKey = XGlyphTypeface.ComputeKey(familyName, fontResolvingOptions);
            }
#if true_
            if (familyName == "Cambria")
            {
                Debug - Break.Break();
            }
#endif
            GdiFontStyle gdiStyle = (GdiFontStyle)(fontResolvingOptions.FontStyle & XFontStyle.BoldItalic);

            // Create a 10 point GDI+ font as an exemplar.
            font = FontHelper.CreateFont(familyName, 10, gdiStyle, out XFontSource fontSource);

            if (fontSource != null)
            {
                Debug.Assert(font != null);

                // Case: Font was created by a GDI+ private font collection.
#if true
#if DEBUG
                Debug.Assert(FontFactory.TryGetFontSourceByTypefaceKey(typefaceKey, out XFontSource existingFontSource) &&
                             ReferenceEquals(fontSource, existingFontSource));
#endif
#else
                // Win32 API cannot get font data from fonts created by private font collection,
                // because this is handled internally in GDI+.
                // Therefore the font source was created when the private font is added to the private font collection.
                if (!FontFactory.TryGetFontSourceByTypefaceKey(typefaceKey, out fontSource))
                {
                    // Simplify styles.
                    // (The code is written for clarity - do not rearrange for optimization)
                    if (font.Bold && font.Italic)
                    {
                        if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, true, false), out fontSource))
                        {
                            // Use bold font.
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                        else if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, true), out fontSource))
                        {
                            // Use italic font.
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                        else if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, false), out fontSource))
                        {
                            // Use regular font.
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                    }
                    else if (font.Bold || font.Italic)
                    {
                        // Use regular font.
                        if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, false), out fontSource))
                        {
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                    }
                    else
                    {
                        if (FontFactory.TryGetFontSourceByTypefaceKey(XGlyphTypeface.ComputeKey(font.Name, false, false), out fontSource))
                        {
                            // Should never come here...
                            FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
                        }
                    }
                }
#endif
            }
            else
            {
                // Get or create the font source and cache it under the specified typeface key.
                fontSource = XFontSource.GetOrCreateFromGdi(typefaceKey, font);
            }
            return(fontSource);
        }