示例#1
0
        private void ShrinkBondLinesPass2(Progress pb)
        {
            // so that they do not overlap label characters

            if (_atomLabelCharacters.Count > 1)
            {
                pb.Show();
            }
            pb.Message = "Clipping Bond Lines - Pass 2";
            pb.Value   = 0;
            pb.Maximum = _atomLabelCharacters.Count;

            foreach (AtomLabelCharacter alc in _atomLabelCharacters)
            {
                pb.Increment(1);

                double width  = OoXmlHelper.ScaleCsTtfToCml(alc.Character.Width);
                double height = OoXmlHelper.ScaleCsTtfToCml(alc.Character.Height);

                if (alc.IsSubScript)
                {
                    // Shrink bounding box
                    width  = width * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR;
                    height = height * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR;
                }

                // Create rectangle of the bounding box with a suitable clipping margin
                Rect cbb = new Rect(alc.Position.X - OoXmlHelper.CHARACTER_CLIPPING_MARGIN,
                                    alc.Position.Y - OoXmlHelper.CHARACTER_CLIPPING_MARGIN,
                                    width + (OoXmlHelper.CHARACTER_CLIPPING_MARGIN * 2),
                                    height + (OoXmlHelper.CHARACTER_CLIPPING_MARGIN * 2));

                //Debug.WriteLine("Character: " + alc.Ascii + " Rectangle: " + a);

                // Just in case we end up splitting a line into two
                List <BondLine> extraBondLines = new List <BondLine>();

                // Select Lines which may require trimming
                // By using LINQ to implement the following SQL
                // Where (L.Right Between Cbb.Left And Cbb.Right)
                //    Or (L.Left Between Cbb.Left And Cbb.Right)
                //    Or (L.Top Between Cbb.Top And Cbb.Botton)
                //    Or (L.Bottom Between Cbb.Top And Cbb.Botton)

                var targeted = from l in _bondLines
                               where (cbb.Left <= l.BoundingBox.Right & l.BoundingBox.Right <= cbb.Right)
                               | (cbb.Left <= l.BoundingBox.Left & l.BoundingBox.Left <= cbb.Right)
                               | (cbb.Top <= l.BoundingBox.Top & l.BoundingBox.Top <= cbb.Bottom)
                               | (cbb.Top <= l.BoundingBox.Bottom & l.BoundingBox.Bottom <= cbb.Bottom)
                               select l;

                foreach (BondLine bl in targeted)
                {
                    //pb.Increment(1);

                    Point start = new Point(bl.Start.X, bl.Start.Y);
                    Point end   = new Point(bl.End.X, bl.End.Y);

                    //Debug.WriteLine("  Line From: " + start + " To: " + end);

                    int attempts = 0;
                    if (CohenSutherland.ClipLine(cbb, ref start, ref end, out attempts))
                    {
                        //Debug.WriteLine("    Clipped Line Start Point: " + start);
                        //Debug.WriteLine("    Clipped Line   End Point: " + end);

                        bool bClipped = false;

                        if (Math.Abs(bl.Start.X - start.X) < EPSILON && Math.Abs(bl.Start.Y - start.Y) < EPSILON)
                        {
                            bl.Start = new Point(end.X, end.Y);
                            bClipped = true;
                        }
                        if (Math.Abs(bl.End.X - end.X) < EPSILON && Math.Abs(bl.End.Y - end.Y) < EPSILON)
                        {
                            bl.End   = new Point(start.X, start.Y);
                            bClipped = true;
                        }

                        if (!bClipped)
                        {
                            // Line was clipped at both ends;
                            // 1. Generate new line
                            BondLine extraLine = new BondLine(new Point(end.X, end.Y), new Point(bl.End.X, bl.End.Y), bl.Type, bl.ParentBond, bl.ParentMolecule, bl.StartAtomId, bl.EndAtomId);
                            extraBondLines.Add(extraLine);
                            // 2. Trim existing line
                            bl.End = new Point(start.X, start.Y);
                        }
                    }
                    if (attempts >= 15)
                    {
                        Debug.WriteLine("Clipping failed !");
                    }
                }

                // Add any extra lines generated by this character into the List of Bond Lines
                foreach (BondLine bl in extraBondLines)
                {
                    _bondLines.Add(bl);
                }
            }
        }