Example #1
0
        public static XGlyphTypeface GetOrCreateFromGdi(GdiFont gdiFont)
        {
            // $TODO THHO Lock???
            string typefaceKey = ComputeKey(gdiFont);

            if (GlyphTypefaceCache.TryGetGlyphTypeface(typefaceKey, out XGlyphTypeface glyphTypeface))
            {
                // We have the glyph typeface already in cache.
                return(glyphTypeface);
            }

            XFontFamily fontFamily = XFontFamily.GetOrCreateFromGdi(gdiFont);
            XFontSource fontSource = XFontSource.GetOrCreateFromGdi(typefaceKey, gdiFont);

            // Check if styles must be simulated.
            XStyleSimulations styleSimulations = XStyleSimulations.None;

            if (gdiFont.Bold && !fontSource.Fontface.os2.IsBold)
            {
                styleSimulations |= XStyleSimulations.BoldSimulation;
            }
            if (gdiFont.Italic && !fontSource.Fontface.os2.IsItalic)
            {
                styleSimulations |= XStyleSimulations.ItalicSimulation;
            }

            glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, styleSimulations, gdiFont);
            GlyphTypefaceCache.AddGlyphTypeface(glyphTypeface);

            return(glyphTypeface);
        }
Example #2
0
        /// <summary>
        /// A GDI+ font object is used to setup the internal font objects.
        /// </summary>
        void InitializeFromGdi()
        {
            try
            {
                Lock.EnterFontFactory();
                if (GdiFontFamily != null)
                {
                    // Create font based on its family.
                    GdiFont = new GdiFont(GdiFontFamily, (float)Size, (GdiFontStyle)Style, GraphicsUnit.World);
                }

                if (GdiFont != null)
                {
#if DEBUG_
                    string name1 = _gdiFont.Name;
                    string name2 = _gdiFont.OriginalFontName;
                    string name3 = _gdiFont.SystemFontName;
#endif
                    FamilyName = GdiFont.FontFamily.Name;
                    // TODO: _glyphTypeface = XGlyphTypeface.GetOrCreateFrom(_gdiFont);
                }
                else
                {
                    Debug.Assert(false);
                }

                if (GlyphTypeface == null)
                {
                    GlyphTypeface = XGlyphTypeface.GetOrCreateFromGdi(GdiFont);
                }

                CreateDescriptorAndInitializeFontMetrics();
            }
            finally { Lock.ExitFontFactory(); }
        }
Example #3
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);
        }
Example #4
0
        const string KeyPrefix = "tk:";  // "typeface key"

#if CORE || GDI
        XGlyphTypeface(string key, XFontFamily fontFamily, XFontSource fontSource, XStyleSimulations styleSimulations, GdiFont gdiFont)
        {
            Key        = key;
            FontFamily = fontFamily;
            FontSource = fontSource;

            Fontface = OpenTypeFontface.CetOrCreateFrom(fontSource);
            Debug.Assert(ReferenceEquals(FontSource.Fontface, Fontface));

            GdiFont = gdiFont;

            StyleSimulations = styleSimulations;
            Initialize();
        }
Example #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="XFont"/> class from a System.DrawingCore.Font.
 /// </summary>
 /// <param name="font">The System.DrawingCore.Font.</param>
 /// <param name="pdfOptions">Additional PDF options.</param>
 public XFont(GdiFont font, XPDFFontOptions pdfOptions)
 {
     if (font.Unit != GraphicsUnit.World)
     {
         throw new ArgumentException("Font must use GraphicsUnit.World.");
     }
     _gdiFont = font;
     Debug.Assert(font.Name == font.FontFamily.Name);
     _familyName = font.Name;
     _emSize     = font.Size;
     _style      = FontStyleFrom(font);
     _pdfOptions = pdfOptions;
     InitializeFromGdi();
 }
Example #6
0
        private SizeF MeasureString(string s, Graphics g, System.DrawingCore.Font drawFont, StringFormat drawFormat)
        {
            if (s == null || s.Length == 0)
            {
                return(SizeF.Empty);
            }

            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);

            return(new SizeF(mr.Width, mr.Height));
        }
Example #7
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);
        }
Example #8
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);
        }
Example #9
0
        /// <summary>
        /// Measures the location of words within a string;  limited by .Net 1.1 to 32 words
        ///	 MEASUREMAX is a constant that defines that limit
        /// </summary>
        /// <param name="s"></param>
        /// <param name="g"></param>
        /// <param name="drawFont"></param>
        /// <param name="drawFormat"></param>
        /// <param name="cra"></param>
        /// <returns></returns>
        private WordStartFinish[] MeasureString32(string s, Graphics g, System.DrawingCore.Font drawFont, StringFormat drawFormat, CharacterRange[] cra)
        {
            if (s == null || s.Length == 0)
            {
                return(null);
            }

            drawFormat.SetMeasurableCharacterRanges(cra);
            Region[] rs = new Region[cra.Length];
            rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0, 0, float.MaxValue, float.MaxValue),
                                          drawFormat);
            WordStartFinish[] sz = new WordStartFinish[cra.Length];
            int isz = 0;

            foreach (Region r in rs)
            {
                RectangleF mr = r.GetBounds(g);
                sz[isz].start = Measurement.PointsFromPixels(mr.Left, g.DpiX);
                sz[isz].end   = Measurement.PointsFromPixels(mr.Right, g.DpiX);
                isz++;
            }
            return(sz);
        }
        /// <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);
        }
Example #11
0
 public PlatformFontResolverInfo(string faceName, bool mustSimulateBold, bool mustSimulateItalic, GdiFont gdiFont)
     : base(faceName, mustSimulateBold, mustSimulateItalic) => GdiFont = gdiFont;
Example #12
0
        /// <summary>
        /// Measures the location of an arbritrary # of words within a string
        /// </summary>
        private WordStartFinish[] MeasureString(string s, Graphics g, System.DrawingCore.Font drawFont, StringFormat drawFormat, CharacterRange[] cra)
        {
            if (cra.Length <= MEASUREMAX)               // handle the simple case of < MEASUREMAX words
            {
                return(MeasureString32(s, g, drawFont, drawFormat, cra));
            }

            // Need to compensate for SetMeasurableCharacterRanges limitation of 32 (MEASUREMAX)
            int mcra = (cra.Length / MEASUREMAX);                         // # of full 32 arrays we need
            int ip   = cra.Length % MEASUREMAX;                           // # of partial entries needed for last array (if any)

            WordStartFinish[] sz       = new WordStartFinish[cra.Length]; // this is the final result;
            float             startPos = 0;

            CharacterRange[] cra32 = new CharacterRange[MEASUREMAX];    // fill out
            int icra = 0;                                               // index thru the cra

            for (int i = 0; i < mcra; i++)
            {
                // fill out the new array
                int ticra = icra;
                for (int j = 0; j < cra32.Length; j++)
                {
                    cra32[j]        = cra[ticra++];
                    cra32[j].First -= cra[icra].First;  // adjust relative offsets of strings
                }

                // measure the word locations (in the new string)
                // ???? should I put a blank in front of it??
                string ts = s.Substring(cra[icra].First,
                                        cra[icra + cra32.Length - 1].First + cra[icra + cra32.Length - 1].Length - cra[icra].First);
                WordStartFinish[] pos = MeasureString32(ts, g, drawFont, drawFormat, cra32);

                // copy the values adding in the new starting positions
                for (int j = 0; j < pos.Length; j++)
                {
                    sz[icra].start = pos[j].start + startPos;
                    sz[icra++].end = pos[j].end + startPos;
                }
                startPos = sz[icra - 1].end;    // reset the start position for the next line
            }
            // handle the remaining character
            if (ip > 0)
            {
                // resize the range array
                cra32 = new CharacterRange[ip];
                // fill out the new array
                int ticra = icra;
                for (int j = 0; j < cra32.Length; j++)
                {
                    cra32[j]        = cra[ticra++];
                    cra32[j].First -= cra[icra].First;  // adjust relative offsets of strings
                }
                // measure the word locations (in the new string)
                // ???? should I put a blank in front of it??
                string ts = s.Substring(cra[icra].First,
                                        cra[icra + cra32.Length - 1].First + cra[icra + cra32.Length - 1].Length - cra[icra].First);
                WordStartFinish[] pos = MeasureString32(ts, g, drawFont, drawFormat, cra32);

                // copy the values adding in the new starting positions
                for (int j = 0; j < pos.Length; j++)
                {
                    sz[icra].start = pos[j].start + startPos;
                    sz[icra++].end = pos[j].end + startPos;
                }
            }
            return(sz);
        }
Example #13
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();
                }
            }
        }
Example #14
0
        //drawstring justified with paragraph format
        public static void DrawStringJustified(System.DrawingCore.Graphics graphics, string s, System.DrawingCore.Font font, System.DrawingCore.Brush brush, System.DrawingCore.RectangleF layoutRectangle, char paragraphFormat)
        {
            try
            {
                //save the current state of the graphics handle
                GraphicsState graphicsState = graphics.Save();
                //obtain the font height to be used as line height
                double lineHeight = (double)Math.Round(font.GetHeight(graphics), 1);
                //string builder to format the text
                StringBuilder text         = new StringBuilder(s);
                var           originalFont = new System.DrawingCore.Font(font.FontFamily, font.Size, font.Style);

                //adjust the text string to ease detection of carriage returns
                text = text.Replace("\r\n", " <CR> ");
                text = text.Replace("\r", " <CR> ");
                text.Append(" <CR> ");

                //ensure measure string will bring the best measures possible (antialias)
                graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

                //create a string format object with the generic typographic to obtain the most accurate string measurements
                //strange, but the recommended for this case is to use a "cloned" stringformat
                var stringFormat = (System.DrawingCore.StringFormat)System.DrawingCore.StringFormat.GenericTypographic.Clone();

                //allow the correct measuring of spaces
                stringFormat.FormatFlags = System.DrawingCore.StringFormatFlags.MeasureTrailingSpaces;

                //create a stringformat for leftalignment
                System.DrawingCore.StringFormat leftAlignHandle = new System.DrawingCore.StringFormat();
                leftAlignHandle.LineAlignment = System.DrawingCore.StringAlignment.Near;

                //create a stringformat for rightalignment
                System.DrawingCore.StringFormat rightAlignHandle = new System.DrawingCore.StringFormat();
                rightAlignHandle.LineAlignment = System.DrawingCore.StringAlignment.Far;

                //measure space for the given font
                var    stringSize = graphics.MeasureString(" ", font, layoutRectangle.Size, stringFormat);
                double spaceWidth = stringSize.Width + 1;

                //measure paragraph format for the given font
                double paragraphFormatWidth = 0;
                if (paragraphFormat != ' ')
                {
                    var paragraphFormatSize = graphics.MeasureString(paragraphFormat.ToString(), new System.DrawingCore.Font(font.FontFamily, font.Size, System.DrawingCore.FontStyle.Regular), layoutRectangle.Size, stringFormat);
                    paragraphFormatWidth = paragraphFormatSize.Width;
                }

                //total word count
                int totalWords = Regex.Matches(text.ToString(), " ").Count;

                //array of words
                ArrayList words = new ArrayList();

                //measure each word
                int n = 0;
                while (true)
                {
                    //original word
                    string word = Regex.Split(text.ToString(), " ").GetValue(n).ToString();

                    //add to words array the word without tags
                    words.Add(new Word(word.Replace("<b>", "").Replace("</b>", "").Replace("<i>", "").Replace("</i>", "")));

                    //marque to start bolding or/and italic
                    if (word.ToLower().Contains("<b>") && word.ToLower().Contains("<i>"))
                    {
                        font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Bold & System.DrawingCore.FontStyle.Italic);
                    }
                    else if (word.ToLower().Contains("<b>"))
                    {
                        font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Bold);
                    }
                    else if (word.ToLower().Contains("<i>"))
                    {
                        font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Italic);
                    }

                    Word currentWord = (Word)words[n];
                    currentWord.StartBold   = word.ToLower().Contains("<b>");
                    currentWord.StopBold    = word.ToLower().Contains("</b>");
                    currentWord.StartItalic = word.ToLower().Contains("<i>");
                    currentWord.StopItalic  = word.ToLower().Contains("</i>");

                    //size of the word
                    var   wordSize  = graphics.MeasureString(currentWord.String, font, layoutRectangle.Size, stringFormat);
                    float wordWidth = wordSize.Width;

                    if (wordWidth > layoutRectangle.Width && currentWord.String != "<CR>")
                    {
                        int reduce = 1;
                        while (true)
                        {
                            int    lengthChars = (int)Math.Round(currentWord.String.Length / (wordWidth / layoutRectangle.Width), 0) - reduce;
                            string cutWord     = currentWord.String.Substring(0, lengthChars);

                            //the new size of the word
                            wordSize  = graphics.MeasureString(cutWord, font, layoutRectangle.Size, stringFormat);
                            wordWidth = wordSize.Width;

                            //update the word string
                            ((Word)words[n]).String = cutWord;

                            //add new word
                            if (wordWidth <= layoutRectangle.Width)
                            {
                                totalWords++;
                                words.Add(new Word("", 0,
                                                   currentWord.StartBold, currentWord.StopBold,
                                                   currentWord.StartItalic, currentWord.StopItalic));
                                text.Replace(currentWord.String, cutWord + " " + currentWord.String.Substring(lengthChars + 1), 0, 1);
                                break;
                            }

                            reduce++;
                        }
                    }

                    //update the word size
                    ((Word)words[n]).Length = wordWidth;

                    //marque to stop bolding or/and italic
                    if (word.ToLower().Contains("</b>") && font.Style == System.DrawingCore.FontStyle.Italic)
                    {
                        font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Italic);
                    }
                    else if (word.ToLower().Contains("</i>") && font.Style == System.DrawingCore.FontStyle.Bold)
                    {
                        font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Bold);
                    }
                    else if (word.ToLower().Contains("</b>") || word.ToLower().Contains("</i>"))
                    {
                        font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Regular);
                    }

                    n++;
                    if (n > totalWords - 1)
                    {
                        break;
                    }
                }

                //before we start drawing, its wise to restore ou graphics objecto to its original state
                graphics.Restore(graphicsState);

                //restore to font to the original values
                font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, originalFont.Style);

                //start drawing word by word
                int currentLine = 0;
                for (int i = 0; i < totalWords; i++)
                {
                    bool   endOfSentence = false;
                    double wordsWidth    = 0;
                    int    wordsInLine   = 0;

                    int j = i;
                    for (j = i; j < totalWords; j++)
                    {
                        if (((Word)words[j]).String == "<CR>")
                        {
                            endOfSentence = true;
                            break;
                        }

                        wordsWidth += ((Word)words[j]).Length + spaceWidth;
                        if (wordsWidth > layoutRectangle.Width && j > i)
                        {
                            wordsWidth = wordsWidth - ((Word)words[j]).Length - (spaceWidth * wordsInLine);
                            break;
                        }

                        wordsInLine++;
                    }

                    if (j > totalWords)
                    {
                        endOfSentence = true;
                    }

                    double widthOfBetween = 0;
                    if (endOfSentence)
                    {
                        widthOfBetween = spaceWidth;
                    }
                    else
                    {
                        widthOfBetween = (layoutRectangle.Width - wordsWidth) / (wordsInLine - 1);
                    }

                    double currentTop = layoutRectangle.Top + (int)(currentLine * lineHeight);

                    if (currentTop > (layoutRectangle.Height + layoutRectangle.Top))
                    {
                        i = totalWords;
                        break;
                    }

                    double currentLeft = layoutRectangle.Left;

                    bool lastWord = false;
                    for (int currentWord = 0; currentWord < wordsInLine; currentWord++)
                    {
                        bool loop = false;

                        if (((Word)words[i]).String == "<CR>")
                        {
                            i++;
                            loop = true;
                        }

                        if (!loop)
                        {
                            //last word in sentence
                            if (currentWord == wordsInLine && !endOfSentence)
                            {
                                lastWord = true;
                            }

                            if (wordsInLine == 1)
                            {
                                currentLeft = layoutRectangle.Left;
                                lastWord    = false;
                            }

                            System.DrawingCore.RectangleF   rectangleF;
                            System.DrawingCore.StringFormat stringFormatHandle;

                            if (lastWord)
                            {
                                rectangleF         = new System.DrawingCore.RectangleF(layoutRectangle.Left, (float)currentTop, layoutRectangle.Width, (float)(currentTop + lineHeight));
                                stringFormatHandle = rightAlignHandle;
                            }
                            else
                            {
                                //lets zero size for word to drawstring auto-size de word
                                rectangleF         = new System.DrawingCore.RectangleF((float)currentLeft, (float)currentTop, 0, 0);
                                stringFormatHandle = leftAlignHandle;
                            }

                            //start bolding and/or italic
                            if (((Word)words[i]).StartBold && ((Word)words[i]).StartItalic)
                            {
                                font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Bold & System.DrawingCore.FontStyle.Italic);
                            }
                            else if (((Word)words[i]).StartBold)
                            {
                                font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Bold);
                            }
                            else if (((Word)words[i]).StartItalic)
                            {
                                font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Italic);
                            }

                            //draw the word
                            graphics.DrawString(((Word)words[i]).String, font, brush, rectangleF, stringFormatHandle);

                            //stop bolding and/or italic
                            if (((Word)words[i]).StopBold && font.Style == System.DrawingCore.FontStyle.Italic)
                            {
                                font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Regular);
                            }
                            else if (((Word)words[i]).StopItalic && font.Style == System.DrawingCore.FontStyle.Bold)
                            {
                                font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Bold);
                            }
                            else if (((Word)words[i]).StopBold || ((Word)words[i]).StopItalic)
                            {
                                font = new System.DrawingCore.Font(originalFont.FontFamily, originalFont.Size, System.DrawingCore.FontStyle.Regular);
                            }

                            //paragraph formating
                            if (endOfSentence && currentWord == wordsInLine - 1 && paragraphFormat != ' ')
                            {
                                currentLeft += ((Word)words[i]).Length;
                                //draw until end of line
                                while (currentLeft + paragraphFormatWidth <= layoutRectangle.Left + layoutRectangle.Width)
                                {
                                    rectangleF = new System.DrawingCore.RectangleF((float)currentLeft, (float)currentTop, 0, 0);
                                    //draw the paragraph format
                                    graphics.DrawString(paragraphFormat.ToString(), font, brush, rectangleF, stringFormatHandle);
                                    currentLeft += paragraphFormatWidth;
                                }
                            }
                            else
                            {
                                currentLeft += ((Word)words[i]).Length + widthOfBetween;
                            }

                            //go to next word
                            i++;
                        }
                    }

                    currentLine++;

                    if (i >= totalWords)
                    {
                        break;
                    }

                    //compensate endfor
                    if (((Word)words[i]).String != "<CR>")
                    {
                        i--;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
Example #15
0
 //drawstring justified without paragraph format
 public static void DrawStringJustified(System.DrawingCore.Graphics graphics, string s, System.DrawingCore.Font font, System.DrawingCore.Brush brush, System.DrawingCore.RectangleF layoutRectangle)
 {
     DrawStringJustified(graphics, s, font, brush, layoutRectangle, ' ');
 }
        /// <summary>
        /// 创建验证码的图片
        /// </summary>
        /// <param name="validateCode">验证码</param>
        /// <param name="height">图片高度</param>
        /// <param name="rightOffsetWidth">文字的右边偏移量宽度</param>
        /// <returns></returns>
        public static byte[] CreateValidateGraphic(string validateCode, int height, int leftOffsetWidth, int rightOffsetWidth)
        {
            int      randAngle = 45;                           //随机转动角度
            int      mapwidth  = (int)(validateCode.Length * 24) + leftOffsetWidth + rightOffsetWidth;
            Bitmap   image     = new Bitmap(mapwidth, height); //创建图片背景
            Graphics graph     = Graphics.FromImage(image);

            try
            {
                graph.Clear(Color.AliceBlue);//清除画面,填充背景
                Random rand = new Random();



                //验证码旋转,防止机器识别
                char[] chars = validateCode.ToCharArray();//拆散字符串成单字符数组

                //文字距中
                StringFormat format = new StringFormat(StringFormatFlags.NoClip);
                format.Alignment     = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;

                //定义颜色
                Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
                //定义字体
                string[] font   = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
                int      cindex = rand.Next(7);

                for (int i = 0; i < chars.Length; i++)
                {
                    int findex = rand.Next(5);

                    Font  f = new System.DrawingCore.Font(font[findex], 20, System.DrawingCore.FontStyle.Bold);//字体样式(参数2为字体大小)
                    Brush b = new System.DrawingCore.SolidBrush(c[cindex]);

                    Point dot = new Point(20, 12);
                    //graph.DrawString(dot.X.ToString(),fontstyle,new SolidBrush(Color.Black),10,150);//测试X坐标显示间距的
                    float angle = rand.Next(-randAngle, randAngle); //转动的度数

                    graph.TranslateTransform(dot.X, dot.Y);         //移动光标到指定位置
                    graph.RotateTransform(angle);
                    graph.DrawString(chars[i].ToString(), f, b, 0, 5, format);
                    //graph.DrawString(chars[i].ToString(),fontstyle,new SolidBrush(Color.Blue),1,1,format);
                    graph.RotateTransform(-angle);        //转回去
                    graph.TranslateTransform(-2, -dot.Y); //移动光标到指定位置,每个字符紧凑显示,避免被软件识别
                }
                Brush lb = new System.DrawingCore.SolidBrush(c[cindex]);
                graph.TranslateTransform(-graph.Transform.OffsetX, -graph.Transform.OffsetY);
                // graph.DrawLine(new Pen(Color.DarkGray, 3), 0, image.Height / 2, image.Width, image.Height / 2);
                int x1 = 0;
                int x2 = 0;
                int y1 = 0;
                int y2 = 0;
                int lt = image.Width / 20;
                int dy = 2;
                //背景噪点生成
                for (int i = 0; i < 30; i++)
                {
                    x1 = i == 0 ? lt * i : x2;
                    y1 = i == 0 ? (image.Height / 2 + rand.Next(-dy, dy)) : y2;
                    x2 = x1 + lt;
                    y2 = image.Height / 2 + rand.Next(-dy, dy);
                    graph.DrawLine(new Pen(Color.DarkGray, 2), x1, y1, x2, y2);
                }

                //for (int i = 0; i < 0; i++)
                //{

                //    int x11 = rand.Next(image.Width);
                //    int x12 = rand.Next(image.Width);
                //    int y11 = rand.Next(image.Height);
                //    int y12 = rand.Next(image.Height);
                //    graph.DrawLine(new Pen(Color.DarkGray), x11, y11, x12, y12);
                //}

                //生成图片
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    image.Save(ms, System.DrawingCore.Imaging.ImageFormat.Gif);
                    return(ms.ToArray());
                }
            }
            finally
            {
                graph.Dispose();
                image.Dispose();
            }
        }
Example #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="XFont"/> class from a System.DrawingCore.Font.
 /// </summary>
 /// <param name="font">The System.DrawingCore.Font.</param>
 public XFont(GdiFont font)
     : this(font, new XPDFFontOptions(GlobalFontSettings.DefaultFontEncoding))
 {
 }
Example #18
0
        public static XGlyphTypeface GetOrCreateFrom(string familyName, FontResolvingOptions fontResolvingOptions)
        {
            // Check cache for requested type face.
            string         typefaceKey = ComputeKey(familyName, fontResolvingOptions);
            XGlyphTypeface glyphTypeface;

            try
            {
                // Lock around TryGetGlyphTypeface and AddGlyphTypeface.
                Lock.EnterFontFactory();
                if (GlyphTypefaceCache.TryGetGlyphTypeface(typefaceKey, out glyphTypeface))
                {
                    // Just return existing one.
                    return(glyphTypeface);
                }

                // Resolve typeface by FontFactory.
                FontResolverInfo fontResolverInfo = FontFactory.ResolveTypeface(familyName, fontResolvingOptions, typefaceKey);
                if (fontResolverInfo == null)
                {
                    // No fallback - just stop.
                    throw new InvalidOperationException("No appropriate font found.");
                }

#if CORE || GDI
                GdiFont gdiFont = null;
#endif
#if WPF
                WpfFontFamily    wpfFontFamily    = null;
                WpfTypeface      wpfTypeface      = null;
                WpfGlyphTypeface wpfGlyphTypeface = null;
#endif
#if UWP
                // Nothing to do.
#endif
                // Now create the font family at the first.
                XFontFamily fontFamily;
                if (fontResolverInfo is PlatformFontResolverInfo platformFontResolverInfo)
                {
                    // Case: fontResolverInfo was created by platform font resolver
                    // and contains platform specific objects that are reused.
#if CORE || GDI
                    // Reuse GDI+ font from platform font resolver.
                    gdiFont    = platformFontResolverInfo.GdiFont;
                    fontFamily = XFontFamily.GetOrCreateFromGdi(gdiFont);
#endif
#if WPF
#if !SILVERLIGHT
                    // Reuse WPF font family created from platform font resolver.
                    wpfFontFamily    = platformFontResolverInfo.WpfFontFamily;
                    wpfTypeface      = platformFontResolverInfo.WpfTypeface;
                    wpfGlyphTypeface = platformFontResolverInfo.WpfGlyphTypeface;
                    fontFamily       = XFontFamily.GetOrCreateFromWpf(wpfFontFamily);
#else
                    fontFamily = XFontFamily.GetOrCreateFromWpf(new WpfFontFamily(familyName));
#endif
#endif
#if NETFX_CORE || UWP
                    fontFamily = null;
#endif
                }
                else
                {
                    // Case: fontResolverInfo was created by custom font resolver.

                    // Get or create font family for custom font resolver retrieved font source.
                    fontFamily = XFontFamily.GetOrCreateFontFamily(familyName);
                }

                // We have a valid font resolver info. That means we also have an XFontSource object loaded in the cache.
                XFontSource fontSource = FontFactory.GetFontSourceByFontName(fontResolverInfo.FaceName);
                Debug.Assert(fontSource != null);

                // Each font source already contains its OpenTypeFontface.
#if CORE || GDI
                glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, fontResolverInfo.StyleSimulations, gdiFont);
#endif
#if WPF
                glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, fontResolverInfo.StyleSimulations, wpfTypeface, wpfGlyphTypeface);
#endif
#if NETFX_CORE || UWP
                glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, fontResolverInfo.StyleSimulations);
#endif
                GlyphTypefaceCache.AddGlyphTypeface(glyphTypeface);
            }
            finally { Lock.ExitFontFactory(); }
            return(glyphTypeface);
        }