예제 #1
0
        /// <summary>
        /// Calculates pinyin layout.
        /// </summary>
        private void doAnalyzePinyin(Graphics g)
        {
            // If already measured, nothing to do
            if (pinyinInfo != null)
            {
                return;
            }

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

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

            pinyinInfo = new PinyinInfo();
            // Measure each pinyin syllable
            bool diacritics = true;
            var  pcoll      = entry.GetPinyinForDisplay(diacritics,
                                                        res.PinyinHiliteStart, res.PinyinHiliteLength,
                                                        out pinyinInfo.HiliteStart, out pinyinInfo.HiliteLength);
            float cx   = headInfo.HeadwordRight + (float)padMid;
            float ctop = padTop;

            for (int i = 0; i != pcoll.Count; ++i)
            {
                PinyinSyllable ps = pcoll[i];
                // New pinyin block
                PinyinBlock pb = new PinyinBlock();
                // Text: syllable's display text
                string text = ps.GetDisplayString(true);
                pb.TextPos = textPool.PoolString(text);
                // If text is punctuation, glue it to previous syllable
                if (text.Length == 1 && CedictFormatter.SticksLeft(text) && i > 0)
                {
                    cx -= pinyinSpaceWidth;
                }
                // Block's size and relative location
                SizeF sz = g.MeasureString(text, getFont(fntPinyinHead), 65535, sf);
                pb.Rect = new RectangleF(cx, ctop, sz.Width, sz.Height);
                cx     += sz.Width + pinyinSpaceWidth;
                // Add block
                pinyinInfo.Blocks.Add(pb);
            }
            // Height of whole pinyin area
            pinyinInfo.PinyinHeight = pinyinInfo.Blocks[0].Rect.Height;
        }
예제 #2
0
        /// <summary>
        /// Calculates pinyin layout.
        /// </summary>
        private void doAnalyzePinyin(Graphics g)
        {
            // If already measured, nothing to do
            if (pinyinInfo != null) return;

            // This is how we measure
            StringFormat sf = StringFormat.GenericTypographic;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            pinyinInfo = new PinyinInfo();
            // Measure each pinyin syllable
            bool diacritics = true;
            var pcoll = entry.GetPinyinForDisplay(diacritics,
                res.PinyinHiliteStart, res.PinyinHiliteLength,
                out pinyinInfo.HiliteStart, out pinyinInfo.HiliteLength);
            float cx = headInfo.HeadwordRight + (float)padMid;
            float ctop = padTop;
            for (int i = 0; i != pcoll.Count; ++i)
            {
                PinyinSyllable ps = pcoll[i];
                // New pinyin block
                PinyinBlock pb = new PinyinBlock();
                // Text: syllable's display text
                string text = ps.GetDisplayString(true);
                pb.TextPos = textPool.PoolString(text);
                // If text is punctuation, glue it to previous syllable
                if (text.Length == 1 && CedictFormatter.SticksLeft(text) && i > 0) cx -= pinyinSpaceWidth;
                // Block's size and relative location
                SizeF sz = g.MeasureString(text, getFont(fntPinyinHead), 65535, sf);
                pb.Rect = new RectangleF(cx, ctop, sz.Width, sz.Height);
                cx += sz.Width + pinyinSpaceWidth;
                // Add block
                pinyinInfo.Blocks.Add(pb);
            }
            // Height of whole pinyin area
            pinyinInfo.PinyinHeight = pinyinInfo.Blocks[0].Rect.Height;
        }
예제 #3
0
        /// <summary>
        /// Paint headword's pinyin, with highlights.
        /// </summary>
        private void doPaintPinyin(Graphics g, Brush bfont, SolidBrush bhilite, StringFormat sf, Color bgcol)
        {
            if (pinyinInfo == null || pinyinInfo.Blocks.Count == 0)
            {
                return;
            }

            // We do have highlights
            if (pinyinInfo.HiliteStart != -1)
            {
                // We offset highlight vertically for more pleasing aesthetics (lots of empty space at top in text)
                float topOfs = pinyinInfo.Blocks[0].Rect.Height / 15.0F; // TO-DO: This will need more work; depends on font size & Scale
                // We make highlight exten a bit farther down
                float hFactor = 1.1F;

                // Needed to make gradient work
                g.SmoothingMode = SmoothingMode.None;
                float edgeLeft  = 0;
                float edgeRight = 0;
                for (int i = 0; i != pinyinInfo.Blocks.Count; ++i)
                {
                    // Not in highlight now
                    if (i < pinyinInfo.HiliteStart || i >= pinyinInfo.HiliteStart + pinyinInfo.HiliteLength)
                    {
                        continue;
                    }
                    // Get block
                    PinyinBlock pb = pinyinInfo.Blocks[i];
                    // Where?
                    PointF loc = pb.Rect.Location;
                    loc.Y += topOfs;
                    // Remember edges
                    if (i == pinyinInfo.HiliteStart)
                    {
                        edgeLeft = pb.Rect.Left;
                    }
                    if (i + 1 == pinyinInfo.HiliteStart + pinyinInfo.HiliteLength)
                    {
                        edgeRight = pb.Rect.Right;
                    }
                    // Hilight syllable itself
                    RectangleF hlr = new RectangleF(loc, pb.Rect.Size);
                    hlr.Height *= hFactor;
                    g.FillRectangle(bhilite, hlr);
                    // For middle and last: hilight space before
                    if (i > pinyinInfo.HiliteStart)
                    {
                        float xprev = pinyinInfo.Blocks[i - 1].Rect.Right;
                        hlr.X     = xprev;
                        hlr.Width = loc.X - xprev;
                        g.FillRectangle(bhilite, hlr);
                    }
                }
                // Left and right edges: gradient
                // Extends one space's width beyond edge
                // Reach max color two spaces' width within syllable, OR
                // by midpoint, if edgeRight - edgeLeft < 4 spaces
                float y = pinyinInfo.Blocks[0].Rect.Top + topOfs;
                float w = pinyinSpaceWidth;
                if (edgeLeft != 0 && edgeRight != 0)
                {
                    float      midPoint = (edgeLeft + edgeRight) / 2.0F;
                    float      whalf    = (edgeRight - edgeLeft) / 2.0F;
                    RectangleF rleft;
                    if (whalf < 2.0F * w)
                    {
                        rleft = new RectangleF(edgeLeft - w, y, w + whalf, pinyinInfo.PinyinHeight * hFactor);
                    }
                    else
                    {
                        rleft = new RectangleF(edgeLeft - w, y, w * 3.0F, pinyinInfo.PinyinHeight * hFactor);
                    }
                    using (LinearGradientBrush lbr = new LinearGradientBrush(rleft, bgcol, Magic.HiliteColor, LinearGradientMode.Horizontal))
                    {
                        g.FillRectangle(lbr, rleft);
                    }
                    RectangleF rright;
                    if (whalf < 2.0F * w)
                    {
                        rright = new RectangleF(midPoint, y, w + whalf, pinyinInfo.PinyinHeight * hFactor);
                    }
                    else
                    {
                        rright = new RectangleF(edgeRight - 2.0F * w, y, w * 3.0F, pinyinInfo.PinyinHeight * hFactor);
                    }
                    using (LinearGradientBrush lbr = new LinearGradientBrush(rright, Magic.HiliteColor, bgcol, LinearGradientMode.Horizontal))
                    {
                        g.FillRectangle(lbr, rright);
                    }
                }
            }

            // Now, write each syllable - so it goes on top of hilites
            foreach (PinyinBlock pb in pinyinInfo.Blocks)
            {
                PointF loc = pb.Rect.Location;
                g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                // Draw string
                g.DrawString(textPool.GetString(pb.TextPos), getFont(fntPinyinHead), bfont, loc, sf);
            }
        }