Пример #1
0
 /// <summary>
 /// Ctor: initialize immutable instance.
 /// </summary>
 public FontCacheKey(IdeoFamily family, IdeoScript script, float size, FontStyle style)
 {
     this.family = family;
     this.script = script;
     this.size   = (int)(100F * size);
     this.style  = style;
 }
Пример #2
0
        /// <summary>
        /// Measures the display rectangle of a single character.
        /// </summary>
        public static SizeF MeasureChar(Graphics g, IdeoFamily fam, char c, float size)
        {
            // TO-DO: actually invoke g.MeasureString for non-Hanzi characters
            // I.e., regular and half-width alphabetical and digits

            FontTray ftray = getFont(fam, IdeoScript.Simp, size, FontStyle.Regular);

            return(new SizeF(ftray.DisplayWidth, ftray.DisplayHeight));
        }
Пример #3
0
        /// <summary>
        /// Gets the font with the desired parameters for measuring or drawing text. Works from cache.
        /// </summary>
        private static FontTray getFont(IdeoFamily fam, IdeoScript script, float size, FontStyle style)
        {
            // If font's already in cache, great: use that.
            FontCacheKey fck = new FontCacheKey(fam, script, size, style);

            if (fontCache.ContainsKey(fck))
            {
                return(fontCache[fck]);
            }

            // First time someone request a font like this. Instantiate and cache it.
            FontTray ftray = createFont(fam, script, size, style);

            fontCache[fck] = ftray;
            return(ftray);
        }
Пример #4
0
        /// <summary>
        /// <para>Gets the size of a Hanzi's display rectangle, if using the font with the provided parameters.</para>
        /// <para>Expensive (instantiates and destroys font).</para>
        /// </summary>
        public static SizeF GetCharSize(IdeoFamily fam, float size)
        {
            FontTray ftray = null;

            try
            {
                // Font family and script do not matter
                // Whole point of this class is to make sure the display rectangles
                //   for any family and script are standardized.
                ftray = createFont(fam, IdeoScript.Simp, size, FontStyle.Regular);
                return(new SizeF(ftray.DisplayWidth, ftray.DisplayHeight));
            }
            finally
            {
                ftray.Font.Dispose();
            }
        }
Пример #5
0
 /// <summary>
 /// Returns a coverage info provider for the specified font family.
 /// </summary>
 public static IFontCoverage GetFontCoverage(IdeoFamily fam)
 {
     if (fam == IdeoFamily.Noto)
     {
         return(new FontCoverageFull());
     }
     else if (fam == IdeoFamily.ArphicKai)
     {
         return(cvrArphic);
     }
     else if (fam == IdeoFamily.WinKai)
     {
         return(new CvrBinary(winCoverage));
     }
     else
     {
         throw new Exception("Forgotten family: " + fam.ToString());
     }
 }
Пример #6
0
 /// <summary>
 /// Ctor: initialize immutable instance.
 /// </summary>
 public FontCacheKey(IdeoFamily family, IdeoScript script, float size, FontStyle style)
 {
     this.family = family;
     this.script = script;
     this.size = (int)(100F * size);
     this.style = style;
 }
Пример #7
0
        /// <summary>
        /// Gets the font with the desired parameters for measuring or drawing text. Works from cache.
        /// </summary>
        private static FontTray getFont(IdeoFamily fam, IdeoScript script, float size, FontStyle style)
        {
            // If font's already in cache, great: use that.
            FontCacheKey fck = new FontCacheKey(fam, script, size, style);
            if (fontCache.ContainsKey(fck)) return fontCache[fck];

            // First time someone request a font like this. Instantiate and cache it.
            FontTray ftray = createFont(fam, script, size, style);
            fontCache[fck] = ftray;
            return ftray;
        }
Пример #8
0
        /// <summary>
        /// Actually instantiates a specific font (based on family, script, size and style).
        /// </summary>
        private static FontTray createFont(IdeoFamily fam, IdeoScript script, float size, FontStyle style)
        {
            FontTray ftray = null;
            float height = size * 4F / 3F;
            height *= scale;

            // If a system font is requested, instantiate
            if (fam == IdeoFamily.WinKai)
            {
                if (script == IdeoScript.Simp)
                {
                    ftray = new FontTray(
                        new Font(winFontNameSimp, size, style), 0, -0.05F,
                        height * 0.9F, height);
                    if (ftray.Font.Name != winFontNameSimp)
                        throw new Exception("Requested font not available: " + winFontNameSimp);
                }
                else
                {
                    ftray = new FontTray(
                         new Font(winFontNameTrad, size, style), 0, -0.05F,
                         height * 0.9F, height);
                    if (ftray.Font.Name != winFontNameTrad)
                        throw new Exception("Requested font not available: " + winFontNameTrad);
                }
                return ftray;
            }

            // If a private font is requested, find font face in private collection and instantiate
            foreach (FontFamily ff in fonts.Families)
            {
                if (fam == IdeoFamily.ArphicKai && script == IdeoScript.Trad && ff.Name == "AR PL UKai TW")
                    ftray = new FontTray(
                        new Font(ff, size, style), -0.08798828125F * height, -0.05F,
                        height * 0.9F, height);
                // Alternative names below for name of HDZB_75: First shows up on Win8, second on Win7.
                else if (fam == IdeoFamily.ArphicKai && script == IdeoScript.Simp && (ff.Name == "䡡湄楮札䍓ⵆ潮瑳" || ff.Name == "汉鼎简中楷"))
                    ftray = new FontTray(
                        new Font(ff, size, style), 0, -0.05F,
                        height * 0.9F, height);
                else if (fam == IdeoFamily.Noto && script == IdeoScript.Trad && ff.Name == "Noto Sans T Chinese Light")
                    ftray = new FontTray(
                        new Font(ff, size * 0.85F, style), height * 0.075F, height * 0.025F,
                        height * 0.9F, height);
                else if (fam == IdeoFamily.Noto && script == IdeoScript.Simp && ff.Name == "Noto Sans S Chinese Light")
                    ftray = new FontTray(
                        new Font(ff, size * 0.85F, style), height * 0.075F, height * 0.025F,
                        height * 0.9F, height);
                if (ftray != null) break;
            }
            if (ftray == null) throw new Exception("Requested font not available.");
            return ftray;
        }
Пример #9
0
        /// <summary>
        /// Measures the display rectangle of a string.
        /// </summary>
        public static SizeF MeasureString(Graphics g, IdeoFamily fam, string text, float size)
        {
            // TO-DO: actually invoke g.MeasureString for non-Hanzi characters
            // I.e., regular and half-width alphabetical and digits

            FontTray ftray = getFont(fam, IdeoScript.Simp, size, FontStyle.Regular);
            float width = ((float)text.Length) * ftray.DisplayWidth;
            return new SizeF(width, ftray.DisplayHeight);
        }
Пример #10
0
 /// <summary>
 /// Returns a coverage info provider for the specified font family.
 /// </summary>
 public static IFontCoverage GetFontCoverage(IdeoFamily fam)
 {
     if (fam == IdeoFamily.Noto) return new FontCoverageFull();
     else if (fam == IdeoFamily.ArphicKai) return cvrArphic;
     else if (fam == IdeoFamily.WinKai) return new CvrBinary(winCoverage);
     else throw new Exception("Forgotten family: " + fam.ToString());
 }
Пример #11
0
 /// <summary>
 /// <para>Gets the size of a Hanzi's display rectangle, if using the font with the provided parameters.</para>
 /// <para>Expensive (instantiates and destroys font).</para>
 /// </summary>
 public static SizeF GetCharSize(IdeoFamily fam, float size)
 {
     FontTray ftray = null;
     try
     {
         // Font family and script do not matter
         // Whole point of this class is to make sure the display rectangles
         //   for any family and script are standardized.
         ftray = createFont(fam, IdeoScript.Simp, size, FontStyle.Regular);
         return new SizeF(ftray.DisplayWidth, ftray.DisplayHeight);
     }
     finally
     {
         ftray.Font.Dispose();
     }
 }
Пример #12
0
        /// <summary>
        /// Draws a Hanzi string in the desired font.
        /// </summary>
        public static void DrawString(Graphics g, string text, PointF loc, Brush b,
            IdeoFamily fam, IdeoScript script, float size, FontStyle style)
        {
            // Font tray for requested font
            FontTray ftray = getFont(fam, script, size, style);
            // Substitute font - only for Arphic simplified
            FontTray ftraySubst = null;
            if (fam == IdeoFamily.ArphicKai && script == IdeoScript.Simp)
                ftraySubst = getFont(fam, IdeoScript.Trad, size, style);
            // Where to draw - font-specific adjustment
            float x = loc.X;
            float y = loc.Y;

            // TO-DO: actually invoke g.MeasureString for non-Hanzi characters
            // I.e., regular and half-width alphabetical and digits

            StringFormat sf = StringFormat.GenericTypographic;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            for (int i = 0; i != text.Length; ++i)
            {
                string chr = text.Substring(i, 1);
                // Get coverage info about character
                ArphicSimpCoverage asp = ArphicSimpCoverage.SimpCovers;
                char c = chr[0];
                bool tofu = false;
                if (fam == IdeoFamily.ArphicKai) tofu =
                    (script == IdeoScript.Trad && !cvrArphic.GetCoverage(c).HasFlag(FontCoverageFlags.Trad)) ||
                    (script == IdeoScript.Simp && (asp = getArphicCoverageSimp(c)) == ArphicSimpCoverage.None);
                // Draw tofu is must be
                if (tofu)
                {
                    using (Pen p = new Pen(Color.Gray))
                    {
                        p.DashStyle = DashStyle.Dot;
                        g.SmoothingMode = SmoothingMode.None;
                        g.DrawRectangle(p, x, y, ftray.DisplayWidth, ftray.DisplayHeight);
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.DrawLine(p, x, y, x + ftray.DisplayWidth, y + ftray.DisplayHeight);
                        g.DrawLine(p, x + ftray.DisplayWidth, y, x, y + ftray.DisplayHeight);
                    }
                }
                // Draw with substitute string
                else if (asp == ArphicSimpCoverage.CanSubstitute)
                    g.DrawString(chr, ftraySubst.Font, b, new PointF(x + ftraySubst.HorizOfs, y + ftraySubst.VertOfs), sf);
                // Draw with requested string
                else g.DrawString(chr, ftray.Font, b, new PointF(x + ftray.HorizOfs, y + ftray.VertOfs), sf);
                x += ftray.DisplayWidth;
            }
        }
Пример #13
0
        /// <summary>
        /// Actually instantiates a specific font (based on family, script, size and style).
        /// </summary>
        private static FontTray createFont(IdeoFamily fam, IdeoScript script, float size, FontStyle style)
        {
            FontTray ftray  = null;
            float    height = size * 4F / 3F;

            height *= scale;

            // If a system font is requested, instantiate
            if (fam == IdeoFamily.WinKai)
            {
                if (script == IdeoScript.Simp)
                {
                    ftray = new FontTray(
                        new Font(winFontNameSimp, size, style), 0, -0.05F,
                        height * 0.9F, height);
                    if (ftray.Font.Name != winFontNameSimp)
                    {
                        throw new Exception("Requested font not available: " + winFontNameSimp);
                    }
                }
                else
                {
                    ftray = new FontTray(
                        new Font(winFontNameTrad, size, style), 0, -0.05F,
                        height * 0.9F, height);
                    if (ftray.Font.Name != winFontNameTrad)
                    {
                        throw new Exception("Requested font not available: " + winFontNameTrad);
                    }
                }
                return(ftray);
            }

            // If a private font is requested, find font face in private collection and instantiate
            foreach (FontFamily ff in fonts.Families)
            {
                if (fam == IdeoFamily.ArphicKai && script == IdeoScript.Trad && ff.Name == "AR PL UKai TW")
                {
                    ftray = new FontTray(
                        new Font(ff, size, style), -0.08798828125F * height, -0.05F,
                        height * 0.9F, height);
                }
                // Alternative names below for name of HDZB_75: First shows up on Win8, second on Win7.
                else if (fam == IdeoFamily.ArphicKai && script == IdeoScript.Simp && (ff.Name == "䡡湄楮札䍓ⵆ潮瑳" || ff.Name == "汉鼎简中楷"))
                {
                    ftray = new FontTray(
                        new Font(ff, size, style), 0, -0.05F,
                        height * 0.9F, height);
                }
                else if (fam == IdeoFamily.Noto && script == IdeoScript.Trad && ff.Name == "Noto Sans T Chinese Light")
                {
                    ftray = new FontTray(
                        new Font(ff, size * 0.85F, style), height * 0.075F, height * 0.025F,
                        height * 0.9F, height);
                }
                else if (fam == IdeoFamily.Noto && script == IdeoScript.Simp && ff.Name == "Noto Sans S Chinese Light")
                {
                    ftray = new FontTray(
                        new Font(ff, size * 0.85F, style), height * 0.075F, height * 0.025F,
                        height * 0.9F, height);
                }
                if (ftray != null)
                {
                    break;
                }
            }
            if (ftray == null)
            {
                throw new Exception("Requested font not available.");
            }
            return(ftray);
        }
Пример #14
0
        /// <summary>
        /// Draws a Hanzi string in the desired font.
        /// </summary>
        public static void DrawString(Graphics g, string text, PointF loc, Brush b,
                                      IdeoFamily fam, IdeoScript script, float size, FontStyle style)
        {
            // Font tray for requested font
            FontTray ftray = getFont(fam, script, size, style);
            // Substitute font - only for Arphic simplified
            FontTray ftraySubst = null;

            if (fam == IdeoFamily.ArphicKai && script == IdeoScript.Simp)
            {
                ftraySubst = getFont(fam, IdeoScript.Trad, size, style);
            }
            // Where to draw - font-specific adjustment
            float x = loc.X;
            float y = loc.Y;

            // TO-DO: actually invoke g.MeasureString for non-Hanzi characters
            // I.e., regular and half-width alphabetical and digits

            StringFormat sf = StringFormat.GenericTypographic;

            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            for (int i = 0; i != text.Length; ++i)
            {
                string chr = text.Substring(i, 1);
                // Get coverage info about character
                ArphicSimpCoverage asp = ArphicSimpCoverage.SimpCovers;
                char c    = chr[0];
                bool tofu = false;
                if (fam == IdeoFamily.ArphicKai)
                {
                    tofu =
                        (script == IdeoScript.Trad && !cvrArphic.GetCoverage(c).HasFlag(FontCoverageFlags.Trad)) ||
                        (script == IdeoScript.Simp && (asp = getArphicCoverageSimp(c)) == ArphicSimpCoverage.None);
                }
                // Draw tofu is must be
                if (tofu)
                {
                    using (Pen p = new Pen(Color.Gray))
                    {
                        p.DashStyle     = DashStyle.Dot;
                        g.SmoothingMode = SmoothingMode.None;
                        g.DrawRectangle(p, x, y, ftray.DisplayWidth, ftray.DisplayHeight);
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.DrawLine(p, x, y, x + ftray.DisplayWidth, y + ftray.DisplayHeight);
                        g.DrawLine(p, x + ftray.DisplayWidth, y, x, y + ftray.DisplayHeight);
                    }
                }
                // Draw with substitute string
                else if (asp == ArphicSimpCoverage.CanSubstitute)
                {
                    g.DrawString(chr, ftraySubst.Font, b, new PointF(x + ftraySubst.HorizOfs, y + ftraySubst.VertOfs), sf);
                }
                // Draw with requested string
                else
                {
                    g.DrawString(chr, ftray.Font, b, new PointF(x + ftray.HorizOfs, y + ftray.VertOfs), sf);
                }
                x += ftray.DisplayWidth;
            }
        }
Пример #15
0
 /// <summary>
 /// Sets the font family for Hanzi characters in lookup results and char picker.
 /// </summary>
 public static void SetZhoContentFontFamily(IdeoFamily fam)
 {
     zhoContentFontFamily = fam;
 }
Пример #16
0
 /// <summary>
 /// Sets the font family for Hanzi characters in lookup results and char picker.
 /// </summary>
 public static void SetZhoContentFontFamily(IdeoFamily fam)
 {
     zhoContentFontFamily = fam;
 }