/// <summary> /// Paints target (entry body). /// </summary> private void doPaintTarget(Graphics g, Pen pnorm, Brush bnorm, StringFormat sf) { // Take index of hovered-over sense once - this is atomic, and we're prolly in different thread from mouse short hsix = hoverSenseIx; Brush bhover = null; try { // All the measured and positioned blocks in entry body short currSenseIx = -1; foreach (PositionedBlock pb in positionedBlocks) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; Block block = measuredBlocks[pb.BlockIdx]; if (block.FirstInCedictSense) { ++currSenseIx; } bool hoverSense = currSenseIx == hsix; // Sense ID if (block.SenseId) { float pad = lemmaLineHeight * 0.1F; if (hoverSense) { using (Brush bh = new SolidBrush(Magic.SenseHoverColor)) { g.FillEllipse(bh, pb.LocX + 1F, pb.LocY + scale * pad + 1F, ((float)block.Width) - 2.0F * pad - 2F, lemmaCharHeight - 2.0F * pad - 2F); } } g.DrawEllipse(pnorm, pb.LocX, pb.LocY + scale * pad, ((float)block.Width) - 2.0F * pad, lemmaCharHeight - 2.0F * pad); float idOfsV = -2.896F + scale * 4.396F; g.DrawString(textPool.GetString(block.TextPos), getFont(fntSenseId), bnorm, pb.LocX + 2.0F * pad, pb.LocY + idOfsV, sf); // TO-DO: vertical paddig of character will need more work. } // Text else { // Extra vertical offset on Hanzi blocks float vOfs = 0; bool isHanzi = false; if (block.FontIdx == fntMetaHanziSimp || block.FontIdx == fntMetaHanziTrad || block.FontIdx == fntSenseHanziSimp || block.FontIdx == fntSenseHanziTrad) { vOfs += getTargetHanziOfs(); isHanzi = true; } // No hover: draw with normal brush Brush brush = bnorm; // Hover: create hover brush on demand; draw with that if (hoverLink != null) { if (hoverLink.BlockIds.Contains(pb.BlockIdx)) { if (bhover == null) { bhover = new SolidBrush(Magic.LinkHoverColor); } brush = bhover; } } if (isHanzi) { g.TextRenderingHint = TextRenderingHint.AntiAlias; } else { g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; } // Not a hanzi range (by font ID) if (block.FontIdx == fntSenseLatin || block.FontIdx == fntMetaLatin) { g.DrawString(textPool.GetString(block.TextPos), getFont(block.FontIdx), brush, pb.LocX, pb.LocY, sf); } // Hanzi range else { IdeoScript script = block.FontIdx == fntMetaHanziSimp || block.FontIdx == fntSenseHanziSimp ? IdeoScript.Simp : IdeoScript.Trad; bool meta = block.FontIdx == fntMetaHanziSimp || block.FontIdx == fntMetaHanziTrad; FontStyle fntStyle = meta ? FontStyle.Italic : FontStyle.Regular; HanziRenderer.DrawString(g, textPool.GetString(block.TextPos), new PointF(pb.LocX, pb.LocY + vOfs), brush, Magic.ZhoContentFontFamily, script, Magic.LemmaHanziFontSize, fntStyle); } } } } finally { if (bhover != null) { bhover.Dispose(); } } }
/// <summary> /// Paints full control. Analyzes on demand, but meant to be called after analysis up front. /// </summary> public override void DoPaint(Graphics g) { // If size changed and we get a pain requested without having re-analized: // Analyze now. Not the best time here in paint, but must do. if (analyzedWidth != Width) { Analyze(g, Width); } // Background. Color bgcol = ZenParams.WindowColor; using (Brush b = new SolidBrush(bgcol)) { g.FillRectangle(b, 0, 0, Width, Height); } // Dotted line at bottom if (!last) { using (Pen p = new Pen(Magic.ResultsSeparator)) { float dp = (int)(1.3F * scale); int margin = (int)(8F * scale); p.DashPattern = new float[] { dp, dp }; p.Width = 1; g.SmoothingMode = SmoothingMode.None; g.DrawLine(p, margin, Height - 1, Width - margin, Height - 1); } } // Hanzi highlights. May draw on top, so must come before actual characters are drawn. doPaintHanziHilites(g, bgcol); // Target text highlights (characters will come on top). doPaintTargetHilites(g, bgcol); // This is how we draw text StringFormat sf = StringFormat.GenericTypographic; // Headword, pinyin, entry body using (Brush bnorm = new SolidBrush(Color.Black)) using (Brush bfade = new SolidBrush(Color.FromArgb(200, 200, 200))) using (Pen pnorm = new Pen(bnorm)) { // This works best for Hanzi g.TextRenderingHint = TextRenderingHint.AntiAlias; // Simplified and traditional - headword foreach (HeadBlock hb in headInfo.SimpBlocks) { PointF loc = new PointF(hb.Loc.X, hb.Loc.Y); HanziRenderer.DrawString(g, hb.Char.ToString(), loc, bnorm, Magic.ZhoContentFontFamily, IdeoScript.Simp, Magic.ZhoResultFontSize, FontStyle.Regular); } foreach (HeadBlock hb in headInfo.TradBlocks) { PointF loc = new PointF(hb.Loc.X, hb.Loc.Y); Brush b = hb.Faded ? bfade : bnorm; HanziRenderer.DrawString(g, hb.Char.ToString(), loc, b, Magic.ZhoContentFontFamily, IdeoScript.Trad, Magic.ZhoResultFontSize, FontStyle.Regular); } // Pinyin using (SolidBrush bhilite = new SolidBrush(Magic.HiliteColor)) using (SolidBrush bpinyin = new SolidBrush(Magic.PinyinColor)) { doPaintPinyin(g, bpinyin, bhilite, sf, bgcol); } // Target (body) doPaintTarget(g, pnorm, bnorm, sf); } }
/// <summary> /// Paints the control. /// </summary> public override void DoPaint(System.Drawing.Graphics g) { // Get character rectangles CharRect[] rects = getCharRects(); // Background using (Brush b = new SolidBrush(ZenParams.WindowColor)) { g.FillRectangle(b, 0, 0, Width, Height); } // Characters if (items != null) { StringFormat sf = StringFormat.GenericTypographic; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; using (Brush b = new SolidBrush(Color.Black)) { for (int i = 0; i != rects.Length; ++i) { RectangleF rect = rects[i].Rect; // Background using (Brush bgb = new SolidBrush(rects[i].BgColor)) { g.FillRectangle(bgb, rect); } // Draw character, if any if (i >= items.Length) { continue; } string str = ""; str += items[i]; HanziRenderer.DrawString(g, str, new PointF(rect.X + charOfsX, rect.Y + charOfsY), b, fontFam, fontScript, fontSize, FontStyle.Regular); } } } // Error message else { StringFormat sf = StringFormat.GenericDefault; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; string line1 = tprov.GetString("CharPickerError1"); string line2 = tprov.GetString("CharPickerError2"); float fontSize = Magic.CharPickerErrorFontSize; using (Font f1 = SystemFontProvider.Instance.GetSystemFont(FontStyle.Bold, fontSize)) using (Font f2 = SystemFontProvider.Instance.GetSystemFont(FontStyle.Regular, fontSize)) using (Brush b = new SolidBrush(Color.Black)) { float padL = 10F * Scale; float padR = 10F * Scale; SizeF sz1 = g.MeasureString(line1, f1, (int)(Width - padL - padR), sf); SizeF sz2 = g.MeasureString(line2, f2, (int)(Width - padL - padR), sf); float hblock = sz1.Height + sz2.Height; PointF pt1 = new PointF(padL, (((float)Height - 2) - hblock) / 2F); PointF pt2 = new PointF(pt1.X, pt1.Y + sz1.Height); g.DrawString(line1, f1, b, pt1); g.DrawString(line2, f2, b, new RectangleF(pt2.X, pt2.Y, Width - pt2.X - 1, Height - pt2.Y - 1)); } } // Border using (Pen p = new Pen(ZenParams.BorderColor)) { g.DrawLine(p, 0, 0, Width, 0); g.DrawLine(p, Width - 1, 0, Width - 1, Height); g.DrawLine(p, Width - 1, Height - 1, 0, Height - 1); g.DrawLine(p, 0, Height - 1, 0, 0); } }