示例#1
0
        public static GlyphUtils.GlyphInfo GetGlyphsAndInfo(string symbolText, float pixelsPerDip, out GlyphRun hydrogenGlyphRun, Point point, GlyphTypeface glyphTypeFace, double symbolSize)
        {
            //measure the H atom first
            var glyphInfo = GlyphUtils.GetGlyphs(symbolText, glyphTypeFace, symbolSize);

            hydrogenGlyphRun = GlyphUtils.GetGlyphRun(glyphInfo, glyphTypeFace,
                                                      symbolSize, pixelsPerDip, point);
            //work out exactly how much we should offset from the center to get to the bottom left
            return(glyphInfo);
        }
示例#2
0
 public void MeasureAtBottomLeft(Point bottomLeft, float PixelsPerDip)
 {
     GlyphInfo   = GlyphUtils.GetGlyphsAndInfo(Text, PixelsPerDip, out GlyphRun groupGlyphRun, bottomLeft, _glyphTypeface, TypeSize);
     TextRun     = groupGlyphRun;
     TextMetrics = new AtomTextMetrics
     {
         BoundingBox      = groupGlyphRun.GetBoundingBox(bottomLeft),
         Geocenter        = bottomLeft,
         TotalBoundingBox = groupGlyphRun.GetBoundingBox(bottomLeft),
         FlattenedPath    = GlyphUtils.GetOutline(TextRun),
         OffsetVector     = new Vector(0.0d, 0.0d)
     };
 }
示例#3
0
        public void MeasureAtCenter(Point center)
        {
            GlyphInfo = GlyphUtils.GetGlyphsAndInfo(Text, PixelsPerDip, out GlyphRun groupGlyphRun, center, _glyphTypeface, TypeSize);
            //compensate the main offset vector for any descenders

            Vector mainOffset = GlyphUtils.GetOffsetVector(groupGlyphRun, TypeSize) +
                                new Vector(0.0, -MaxBaselineOffset);
            var    bb = groupGlyphRun.GetBoundingBox(center + mainOffset);
            Vector textFormatterOffset = new Vector(mainOffset.X, -FirstBearing(groupGlyphRun) - bb.Height / 2);

            TextRun     = groupGlyphRun;
            TextMetrics = new AtomTextMetrics
            {
                BoundingBox         = bb,
                Geocenter           = center,
                TotalBoundingBox    = groupGlyphRun.GetBoundingBox(center + mainOffset),
                OffsetVector        = mainOffset,
                TextFormatterOffset = textFormatterOffset
            };
        }
        private void Render(Point location, string colour)
        {
            int  textStorePosition = 0;
            bool flipped;

            Position = location;
            if (ParentAtom == null)
            {
                flipped = false;
            }
            else
            {
                flipped = Flipped;
            }

            var textStore = new FunctionalGroupTextSource(ParentGroup, colour, flipped);

            //main textformatter - this does the writing of the visual
            using (TextFormatter textFormatter = TextFormatter.Create())
            {
                //set up the default paragraph properties
                var paraprops = new FunctionalGroupTextSource.GenericTextParagraphProperties(
                    FlowDirection.LeftToRight,
                    TextAlignment.Left,
                    true,
                    false,
                    new LabelTextRunProperties(colour),
                    TextWrapping.NoWrap,
                    GlyphText.SymbolSize,
                    0d);

                var    anchorRuns   = textStore.Runs.Where(f => f.IsAnchor);
                string anchorString = string.Empty;
                foreach (var run in anchorRuns)
                {
                    anchorString += run.Text;
                }

                using (TextLine myTextLine =
                           textFormatter.FormatLine(textStore, textStorePosition, 999, paraprops, null))
                {
                    IList <TextBounds> textBounds;
                    Rect firstRect = Rect.Empty;
                    if (!Flipped) //isolate them at the beginning
                    {
                        textBounds = myTextLine.GetTextBounds(0, anchorString.Length);
                    }
                    else
                    {
                        //isolate them at the end
                        var start = myTextLine.Length - 1 - anchorString.Length;
                        textBounds = myTextLine.GetTextBounds(start, anchorString.Length);
                    }

                    //add all the bounds together
                    foreach (TextBounds anchorBound in textBounds)
                    {
                        firstRect.Union(anchorBound.Rectangle);
                    }

                    //center will be position close to the origin 0,0
                    Point center = new Point((firstRect.Left + firstRect.Right) / 2,
                                             (firstRect.Top + firstRect.Bottom) / 2);

                    //the displacement vector will be added to each relative coordinate for the glyph run
                    var displacementVector = location - center;

                    //locus is where the text line is drawn
                    var locus = new Point(0, 0) + displacementVector;

                    textBounds = myTextLine.GetTextBounds(0, 999);
                    var obb = textBounds[0].Rectangle;

                    //draw the line of text
                    using (DrawingContext dc = RenderOpen())
                    {
                        myTextLine.Draw(dc, locus, InvertAxes.None);
#if DEBUG
#if SHOWBOUNDS
                        obb.Offset(new Vector(locus.X, locus.Y));
                        dc.DrawRectangle(null, new Pen(new SolidColorBrush(Colors.BlueViolet), 1.0), obb);
#endif
#endif
                        var          glyphRuns     = myTextLine.GetIndexedGlyphRuns();
                        List <Point> outline       = new List <Point>();
                        double       advanceWidths = 0d;

                        //build up the convex hull from each glyph
                        //you need to add in the advance widths for each
                        //glyph run as they are traversed,
                        //to the outline
                        foreach (IndexedGlyphRun igr in glyphRuns)
                        {
                            var originalRun = textStore.GetTextRun(igr.TextSourceCharacterIndex);
                            var currentRun  = igr.GlyphRun;
                            //need to work out how much the current run has been offset from the baseline
                            var runBounds =
                                myTextLine.GetTextBounds(igr.TextSourceCharacterIndex, igr.TextSourceLength);
                            //get the bounding rect
                            var rect = runBounds[0].TextRunBounds[0].Rectangle;

                            //it's relative to the baseline
                            //adjust it
                            rect.Offset(new Vector(locus.X, locus.Y));
                            var rectCopy = rect;
#if DEBUG
#if SHOWBOUNDS
                            dc.DrawRectangle(null, new Pen(new SolidColorBrush(Colors.DarkOrange), 1.0), rect);
#endif
#endif
                            var runOutline = GlyphUtils.GetOutline(currentRun);
                            //need to see if the run has been super or sub-scripted
                            var variants = originalRun.Properties.TypographyProperties.Variants;

                            if (variants == FontVariants.Subscript || variants == FontVariants.Superscript)
                            {
                                //simply union in the rect -it's easier!
                                outline.AddRange(new[]
                                {
                                    rectCopy.BottomLeft, rectCopy.BottomRight, rectCopy.TopLeft,
                                    rectCopy.TopRight
                                });
                            }
                            else
                            {
                                //add in the points from the convex hull
                                for (int i = 0; i < runOutline.Count; i++)
                                {
                                    var point = runOutline[i] + displacementVector +
                                                new Vector(0.0, myTextLine.Baseline);
                                    point.X      += advanceWidths;
                                    runOutline[i] = point;
                                }

                                outline.AddRange(runOutline);
                            }

                            advanceWidths += currentRun.AdvanceWidths.Sum();
                        }

                        _sortedOutline = (from Point p in outline
                                          orderby p.X ascending, p.Y descending
                                          select p).ToList();

                        Hull = Geometry <Point> .GetHull(_sortedOutline, p => p);

                        // Diag: Show Hulls or Atom centres
#if DEBUG
#if SHOWHULLS
                        dc.DrawGeometry(null, new Pen(Brushes.GreenYellow, thickness: 1), HullGeometry);
#endif
#if SHOWATOMCENTRES
                        dc.DrawEllipse(Brushes.Red, null, ParentAtom.Position, 5, 5);
#endif
#endif
                        // End Diag
                        dc.Close();
                    }
                }
            }
        }
示例#5
0
 public void DrawAtBottomLeft(Point bottomLeft, DrawingContext dc)
 {
     GlyphInfo = GlyphUtils.GetGlyphsAndInfo(Text, PixelsPerDip, out GlyphRun groupGlyphRun, bottomLeft, _glyphTypeface, TypeSize);
     dc.DrawGlyphRun(Fill, groupGlyphRun);
     TextRun = groupGlyphRun;
 }