Пример #1
0
        /// <summary>
        /// <para>Finds the right font size to fit characters (2x5 with default size, but it varies).</para>
        /// <para>Finds right vertical area based on font's actual display properties.</para>
        /// </summary>
        private void calibrateFont()
        {
            float width = Width;

            fontSize = 10.0F;

            // Measuring artefacts
            using (Bitmap bmp = new Bitmap(1, 1))
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    StringFormat sf = StringFormat.GenericTypographic;
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

                    // Keep growing font until we reach a comfortable width
                    while (true)
                    {
                        //var xsi = HanziMeasure.Instance.GetMeasures(fontFace, fontSize);
                        //charSize = xsi.RealRect.Size;
                        charSize = HanziRenderer.GetCharSize(Magic.ZhoContentFontFamily, fontSize);
                        if (charSize.Width * 5.0F >= width * 0.9F)
                        {
                            break;
                        }
                        fontSize += 0.5F;
                    }
                }

            // Width of rectangle: using my space equally
            float rectWidth = (width - 2.0F) / 5.0F;
            // Height of rectange: depends on font's actual drawing behavior!
            float rectHeight = charSize.Height;
            // Horizontal padding is rectangle width minus measured char width, over two
            float hPad = (rectWidth - charSize.Width) / 2.0F;

            // Add twice horizontal padding to rectangle height; offset chars from top by padding
            rectHeight += 2.0F * hPad;

            lock (animLO)
            {
                for (int i = 0; i != 5; ++i)
                {
                    float      x    = ((float)i) * rectWidth + 1.0F;
                    RectangleF rtop = new RectangleF(x, 1.0F, rectWidth, rectHeight);
                    RectangleF rbot = new RectangleF(x, rectHeight + 1.0F, rectWidth, rectHeight);
                    charRects[i].Rect     = rtop;
                    charRects[i + 5].Rect = rbot;
                }
            }
            charOfsX = (rectWidth - charSize.Width) / 2.0F;
            charOfsY = (rectHeight - charSize.Height) / 2.0F;
            Height   = (int)Math.Round((rectHeight) * 2.0F + 0.5F);
            MakeMePaint(false, RenderMode.Invalidate);
        }
Пример #2
0
        /// <summary>
        /// Analyzes layout of headword.
        /// </summary>
        /// <param name="g">A Graphics object used for measurements.</param>
        private void doAnalyzeHeadword(Graphics g)
        {
            // If already analyzed, nothing to do
            if (headInfo != null)
            {
                return;
            }

            // This is how we measure
            StringFormat sf = StringFormat.GenericTypographic;

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

            // On-demand: measure a single ideograph's dimensions
            // We only measure simplified. Assume simplified and traditional fonts come in matching pairs -> same size.
            if (ideoSize.Width == 0)
            {
                ideoSize = HanziRenderer.GetCharSize(Magic.ZhoContentFontFamily, Magic.ZhoResultFontSize);
                float hanziLinePad = 6.0F;
                hanziLinePad  *= scale;
                ideoLineHeight = ideoSize.Height + hanziLinePad;
            }

            headInfo = new HeadInfo();
            if (analyzedScript == SearchScript.Simplified)
            {
                headInfo.HeadMode = HeadMode.OnlySimp;
            }
            else if (analyzedScript == SearchScript.Traditional)
            {
                headInfo.HeadMode = HeadMode.OnlyTrad;
            }
            else
            {
                headInfo.HeadMode = HeadMode.BothSingleLine;
            }
            //// For width of headword, use padLeft from border, plus 4 to 6 ideographs' worth of space
            //// Depending on longest headword in entire list
            //int hwChars = maxHeadLength;
            //if (hwChars < 4) hwChars = 4;
            //if (hwChars > 6) hwChars = 6;
            //float hwidth = ((float)hwChars) * ideoSize.Width;
            // Revised
            // For width of headword, always take 5 characters' width of space
            float hwidth = 5.0F * ideoSize.Width;

            headInfo.HeadwordRight = padLeft + hwidth;
            // Measure simplified chars from start; break when needed
            PointF loc  = new PointF(((float)padLeft) + ideoSize.Width, padTop);
            bool   lbrk = false;

            if (analyzedScript == SearchScript.Simplified || analyzedScript == SearchScript.Both)
            {
                lbrk |= doAnalyzeHanzi(g, entry.ChSimpl, true, sf, headInfo.SimpBlocks, ref loc, headInfo.HeadwordRight);
            }
            if (analyzedScript == SearchScript.Traditional || analyzedScript == SearchScript.Both)
            {
                //loc.X = padLeft;
                loc.X = ((float)padLeft) + ideoSize.Width;
                if (analyzedScript == SearchScript.Both)
                {
                    loc.Y += ideoLineHeight;
                }
                lbrk |= doAnalyzeHanzi(g, entry.ChTrad, false, sf, headInfo.TradBlocks, ref loc, headInfo.HeadwordRight);
            }
            // If we're displaying both simplified and traditional, fade out
            // traditional chars that are same as simplified, right above them
            if (analyzedScript == SearchScript.Both)
            {
                for (int i = 0; i != headInfo.SimpBlocks.Count; ++i)
                {
                    if (headInfo.SimpBlocks[i].Char == headInfo.TradBlocks[i].Char)
                    {
                        headInfo.TradBlocks[i].Faded = true;
                    }
                }
            }
            // Bottom of headword area
            headInfo.HeadwordBottom = loc.Y + ideoLineHeight;
            // If we had a line break and we're showing both scripts, update info
            if (analyzedScript == SearchScript.Both && lbrk)
            {
                headInfo.HeadMode = HeadMode.BothMultiLine;
            }
        }