Exemple #1
0
 public linkLabelEx()
 {
     _urlEx        = new Regex(@"\[url=([^\]]+)\]([^\]]+)\[\/url\]");
     base.Text     = "LinkLabelEx";
     LinkArea      = new LinkArea(0, 0);
     autoOpenLinks = true;
 }
Exemple #2
0
 public void onCheckCompleted(object t)
 {
     this.btnCheckVersion.Visible = false;
     try
     {
         if (BaseForm.IsUpdate)
         {
             this.linkLabel1.Text = ResourceCulture.GetString("Find_NewVersion");
             LinkArea linkArea = new LinkArea(0, this.linkLabel1.Text.Length);
             this.linkLabel1.LinkBehavior = LinkBehavior.NeverUnderline;
             this.linkLabel1.LinkColor    = HuionConst.HuionBlue4;
             this.linkLabel1.LinkArea     = linkArea;
             this.linkLabel1.Click       += new EventHandler(this.LinkLabel1_Click);
         }
         else
         {
             this.linkLabel1.Text = ResourceCulture.GetString("Already_Updated");
         }
     }
     catch
     {
         int num = (int)MessageBox.Show(ResourceCulture.GetString("Net_Busy"),
                                        ResourceCulture.GetString("FormInfo_remindText"), MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
     }
 }
Exemple #3
0
        /// <summary>
        /// Updates state for hover behavior above links.
        /// </summary>
        /// <param name="p">Mouse coordinate.</param>
        /// <returns>True if control must request a repaint.</returns>
        private bool doCheckLinkHover(Point p)
        {
            // Are we over a link area?
            LinkArea overWhat = null;

            foreach (LinkArea link in targetLinks)
            {
                foreach (Rectangle rect in link.ActiveAreas)
                {
                    if (rect.Contains(p))
                    {
                        overWhat = link;
                        break;
                    }
                }
            }
            // We're over a link
            //if (overWhat != null) Cursor = Cursors.Hand;
            if (overWhat != null)
            {
                Cursor = CustomCursor.GetHand(Scale);
            }
            // Nop, not over a link
            else
            {
                Cursor = Cursors.Arrow;
            }
            // Hover state changed: request a repaint
            if (overWhat != hoverLink)
            {
                hoverLink = overWhat;
                return(true);
            }
            return(false);
        }
Exemple #4
0
        public void LinkArea_Ctor_Int_Int(int start, int length, bool expectedIsEmpty)
        {
            var area = new LinkArea(start, length);

            Assert.Equal(start, area.Start);
            Assert.Equal(length, area.Length);
            Assert.Equal(expectedIsEmpty, area.IsEmpty);
        }
Exemple #5
0
        public void LinkArea_Ctor_Default()
        {
            var area = new LinkArea();

            Assert.Equal(0, area.Start);
            Assert.Equal(0, area.Length);
            Assert.True(area.IsEmpty);
        }
        public void Inequality()
        {
            LinkArea l1 = new LinkArea(2, 4);
            LinkArea l2 = new LinkArea(4, 6);
            LinkArea l3 = new LinkArea(2, 4);

            Assert.IsFalse(l1 != l3, "A1");
            Assert.IsTrue(l1 != l2, "A2");
            Assert.IsTrue(l2 != l3, "A3");
        }
Exemple #7
0
        private void btnCheckVersion_Click(object sender, EventArgs e)
        {
            new Thread(new ThreadStart(BaseForm.myThread)).Start();
            LinkArea linkArea = new LinkArea(0, 0);

            this.linkLabel1.Text         = ResourceCulture.GetString("Checking_Update");
            this.linkLabel1.Visible      = true;
            this.linkLabel1.LinkArea     = linkArea;
            this.btnCheckVersion.Visible = false;
            HuionDelayRun.delayRun(new Runnable(this.onCheck), 2000, (object)null);
        }
Exemple #8
0
        public void LinkArea_RoundTripAndExchangeWithNet()
        {
            var linkArea = new LinkArea(5, 7);
            var coreBlob = BinarySerialization.ToBase64String(linkArea);

            Assert.Equal(ClassicLinkArea, coreBlob);

            var result = BinarySerialization.EnsureDeserialize <LinkArea>(coreBlob);

            Assert.Equal(linkArea, result);
        }
Exemple #9
0
        public void LinkArea_Equals_Invoke_ReturnsExpected(LinkArea area, object other, bool expected)
        {
            if (other is LinkArea otherArea)
            {
                Assert.Equal(expected, area == otherArea);
                Assert.Equal(!expected, area != otherArea);
                Assert.Equal(expected, area.GetHashCode().Equals(otherArea.GetHashCode()));
            }

            Assert.Equal(expected, area.Equals(other));
        }
Exemple #10
0
 // Determine if two objects are equal.
 public override bool Equals(Object o)
 {
     if (o is LinkArea)
     {
         LinkArea link = (LinkArea)o;
         return(start == link.start && length == link.length);
     }
     else
     {
         return(false);
     }
 }
Exemple #11
0
        public void LinkAreaConverter_CreateInstance_ValidPropertyValues_ReturnsExpected()
        {
            var      converter = new LinkArea.LinkAreaConverter();
            LinkArea area      = Assert.IsType <LinkArea>(converter.CreateInstance(
                                                              null, new Dictionary <string, object>
            {
                { nameof(LinkArea.Start), 1 },
                { nameof(LinkArea.Length), 2 }
            }));

            Assert.Equal(new LinkArea(1, 2), area);
        }
        public void LinkAreaToString()
        {
            LinkArea la = new LinkArea();

            Assert.AreEqual("{Start=0, Length=0}", la.ToString(), "A1");

            la = new LinkArea(0, 0);
            Assert.AreEqual("{Start=0, Length=0}", la.ToString(), "A2");

            la = new LinkArea(4, 75);
            Assert.AreEqual("{Start=4, Length=75}", la.ToString(), "A3");
        }
 private void UpdateSelection()
 {
     if (value is LinkArea)
     {
         LinkArea pt = (LinkArea)value;
         try {
             sampleEdit.SelectionStart  = pt.Start;
             sampleEdit.SelectionLength = pt.Length;
         }
         catch (Exception) {
         }
     }
 }
Exemple #14
0
        public void LinkArea_Length_Set_GetReturnsExpected(int value)
        {
            var area = new LinkArea
            {
                Length = value
            };

            Assert.Equal(value, area.Length);

            // Set same.
            area.Length = value;
            Assert.Equal(value, area.Length);
        }
Exemple #15
0
        public void LinkArea_Start_Set_GetReturnsExpected(int value)
        {
            var area = new LinkArea
            {
                Start = value
            };

            Assert.Equal(value, area.Start);

            // Set same.
            area.Start = value;
            Assert.Equal(value, area.Start);
        }
Exemple #16
0
        void IView.SetLastUpdateCheckInfo(string breif, string details)
        {
            var text     = new StringBuilder(breif);
            var linkArea = new LinkArea();

            if (!string.IsNullOrEmpty(details))
            {
                text.Append(" ");
                int linkBegin = text.Length;
                text.Append("Details.");
                linkArea = new LinkArea(linkBegin, text.Length - linkBegin);
            }
            updateStatusValueLabel.Text     = text.ToString();
            updateStatusValueLabel.LinkArea = linkArea;
            updateStatusValueLabel.Tag      = details;
        }
        public void LinkArea_RoundTripAndExchangeWithNet()
        {
            var linkArea = new LinkArea(5, 7);
            var netBlob  = BinarySerialization.ToBase64String(linkArea);

            // ensure we can deserialise NET serialised data and continue to match the payload
            ValidateResult(netBlob);
            // ensure we can deserialise NET Fx serialised data and continue to match the payload
            ValidateResult(ClassicLinkArea);

            void ValidateResult(string blob)
            {
                LinkArea result = BinarySerialization.EnsureDeserialize <LinkArea>(blob);

                Assert.Equal(linkArea, result);
            }
        }
Exemple #18
0
 public override void DoMouseLeave()
 {
     if (Parent == null)
     {
         return;
     }
     Cursor = Cursors.Arrow;
     // Cursor hovered over a link, or a sense: request a repaint
     if (hoverLink != null || hoverSenseIx != -1)
     {
         hoverLink    = null;
         hoverSenseIx = -1;
         // Cannot request paint for myself directly: entire results control must be repainted in one
         // - Cropping when I'm outside parent's rectangle
         // - Stuff in overlays on top of me
         parentPaint();
     }
 }
Exemple #19
0
        public void AdjustModInfoText(string txt, string linkText = "")
        {
            if (txt == "")
            {
                AdjustModInfoText("Drop a .pak or .zip file onto this window to install a mod.\n\nOnce you're ready to use your enabled mods, press the \"Play\" button below to apply your mods and start playing.");
                return;
            }

            string newTextFull = txt + linkText;
            var    newLinkArea = new LinkArea(txt.Length, linkText.Length);

            if (this.modInfo.Text == newTextFull && this.modInfo.LinkArea.Start == newLinkArea.Start && this.modInfo.LinkArea.Length == newLinkArea.Length)
            {
                return;                                                                                                                                             // Partial fix for winforms rendering issue
            }
            this.modInfo.Text     = newTextFull;
            this.modInfo.LinkArea = newLinkArea;
        }
 private void UpdateSelection()
 {
     if (this.value is LinkArea)
     {
         LinkArea area = (LinkArea)this.value;
         try
         {
             this.sampleEdit.SelectionStart  = area.Start;
             this.sampleEdit.SelectionLength = area.Length;
         }
         catch (Exception exception)
         {
             if (System.Windows.Forms.ClientUtils.IsCriticalException(exception))
             {
                 throw;
             }
         }
     }
 }
            private void UpdateSelection()
            {
                if (!(Value is LinkArea))
                {
                    return;
                }

                LinkArea pt = (LinkArea)Value;

                try
                {
                    _sampleEdit.SelectionStart  = pt.Start;
                    _sampleEdit.SelectionLength = pt.Length;
                }
                catch (Exception ex)
                {
                    if (ClientUtils.IsCriticalException(ex))
                    {
                        throw;
                    }
                }
            }
Exemple #22
0
        public override bool DoMouseClick(Point p, MouseButtons button)
        {
            // Right-click? Show context menu.
            if (button == MouseButtons.Right)
            {
                short              senseIx = getSenseIxFromPoint(p);
                CedictEntry        entry   = getEntry(res.EntryId);
                ResultsCtxtControl ctxt    = new ResultsCtxtControl(onCtxtMenuCommand, tprov, entry, senseIx, analyzedScript);
                ShowContextMenu(p, ctxt);
                return(true);
            }

            // So, it's a left-click.
            // Are we over a link area?
            if (targetLinks == null)
            {
                return(true);
            }
            LinkArea overWhat = null;

            foreach (LinkArea link in targetLinks)
            {
                foreach (Rectangle rect in link.ActiveAreas)
                {
                    if (rect.Contains(p))
                    {
                        overWhat = link;
                        break;
                    }
                }
            }
            // Yes: trigger lookup
            if (overWhat != null)
            {
                lookupThroughLink(overWhat.QueryString);
            }
            return(true);
        }
Exemple #23
0
        private static void PaintLinkLabel(Graphics g, string text, LinkArea linkArea, Font font, Color foreColor, Color backColor, Color linkColor, Rectangle bounds)
        {
            Rectangle textBounds = bounds;

            Brush bgBr = new SolidBrush(backColor);
            Brush frBr = new SolidBrush(foreColor);
            Brush lkBr = new SolidBrush(linkColor);

            StringFormat format = new StringFormat(StringFormatFlags.NoFontFallback);

            format.Alignment     = StringAlignment.Near;
            format.LineAlignment = StringAlignment.Center;
            g.FillRectangle(bgBr, bounds);

            string text1 = text.Substring(0, linkArea.Start);
            string text2 = text.Substring(linkArea.Start, linkArea.Length);
            string text3 = text.Substring(linkArea.Start + linkArea.Length);

            g.DrawString(text1, font, frBr, textBounds, format);
            textBounds.X += MeasureDisplayStringWidth(g, text1, font);
            //SizeF size = g.MeasureString(text1, font, 0, format);
            //textBounds.X += (int)size.Width;

            Font lkFont = new Font(font, FontStyle.Underline);

            g.DrawString(text2, lkFont, lkBr, textBounds, format);
            textBounds.X += MeasureDisplayStringWidth(g, text2, lkFont);
            //size = g.MeasureString(text2, lkFont, 1000, format);
            //textBounds.X += (int)size.Width;

            g.DrawString(text3, font, frBr, textBounds, format);

            lkFont.Dispose();
            bgBr.Dispose();
            frBr.Dispose();
            lkBr.Dispose();
        }
Exemple #24
0
        public void LinkArea_TypeConverter_Get_ReturnsLinkAreaConverter()
        {
            var area = new LinkArea(1, 2);

            Assert.IsType <LinkArea.LinkAreaConverter>(TypeDescriptor.GetConverter(area));
        }
        private async Task selectModpack(Modpack modpack)
        {
            // Timestamp Format: yyyy-MM-dd'T'HH:mm:ss.fff'Z'

            // Browser first, because it takes the longest
            browser.LoadHtml("<style>" + Memory.markdownStyle + "</style>" + CommonMarkConverter.Convert(modpack.Description));

            pnlInstalledVersion.Visible = false;

            pnlDetails.Visible       = true;
            lblName.Text             = modpack.Name;
            lblCreator.Text          = modpack.Creator;
            lblLastChanged.Text      = DateTime.Parse(modpack.LastChanged).ToString("MM'/'dd'/'yyyy");
            lblLastPlayed.Text       = "Never";
            lblMinecraftVersion.Text = modpack.McVersion;
            //rtbDescription.Text = modpack.Description;

            llblSourceFile.Text = Path.GetFileName(modpack.ModpackDownload).truncateString(100, "...");
            llblSourceFile.Tag  = modpack.ModpackDownload;

            lblModpackVersion.Text = modpack.Version;

            if (Memory.forgeSources.ContainsKey(modpack.McVersion))
            {
                llblForgeSource.Text = Path.GetFileName(Memory.forgeSources[modpack.McVersion][0]).truncateString(50, "...");
                llblForgeSource.Tag  = Memory.forgeSources[modpack.McVersion][0];
            }
            else
            {
                llblForgeSource.Text = "N/A";
                llblForgeSource.Tag  = null;
            }

            btnInstallMopack.Width = pnlInstall.Width - 6;
            btnUpdate.Visible      = false;
            btnUninstall.Visible   = false;
            btnUninstall.Tag       = modpack;
            btnInstallMopack.Tag   = modpack;
            btnUpdate.Tag          = modpack;



            this.Text = "Matix's Mod Installer - " + modpack.Name + " (" + modpack.McVersion + ") by " + modpack.Creator;

            string profileLocation = Path.Combine(Memory.minecraftLocation, "launcher_profiles.json");
            string profileString   = "";

            using (StreamReader r = new StreamReader(profileLocation))
            {
                profileString = await r.ReadToEndAsync();
            }


            try
            {
                if (installing == true && installingUID == modpack.UID)
                {
                    pnlInstall.Height          = 103;
                    pgbInstallProgress.Visible = true;
                    lblInstallStatus.Visible   = true;
                    btnInstallMopack.Text      = "Installing...";
                    btnInstallMopack.Enabled   = false;
                }
                else
                {
                    pnlInstall.Height          = 56;
                    pgbInstallProgress.Visible = false;
                    lblInstallStatus.Visible   = false;


                    string modpackDirectory = Path.Combine(Memory.modpacksLocation, Utils.convertIllegalPath(modpack.UID));
                    if (Directory.Exists(modpackDirectory))
                    {
                        btnInstallMopack.Text = "Start Minecraft";
                        if (Memory.launcherFound)
                        {
                            btnInstallMopack.Enabled = true;
                        }
                        else
                        {
                            btnInstallMopack.Enabled = false;
                        }

                        btnUninstall.Visible = true;

                        if (File.Exists(Path.Combine(modpackDirectory, "mmi_mpi.json")))
                        {
                            using (StreamReader r = new StreamReader(Path.Combine(modpackDirectory, "mmi_mpi.json")))
                            {
                                ModpackInfo modpackInfo = JsonConvert.DeserializeObject <ModpackInfo>(await r.ReadToEndAsync());
                                lblForgeInstallation.Text = modpackInfo.VersionId;

                                lblInstalledVersion.Text    = modpackInfo.Version;
                                pnlInstalledVersion.Visible = true;

                                if (modpackInfo.Version != modpack.Version)
                                {
                                    btnInstallMopack.Width = pnlInstall.Width - btnUpdate.Width - btnUninstall.Width - 29;
                                    btnUpdate.Visible      = true;
                                }
                                else
                                {
                                    btnInstallMopack.Width = pnlInstall.Width - btnUninstall.Width - 16;
                                    btnUpdate.Visible      = false;
                                }
                            }
                        }
                        else
                        {
                            _log.Warn("Local Modpack Information is missing.");
                            MessageBox.Show("Seems like some of the local Modpack informations are missing. Updating the Modpack to fix this issue.", "Information Missing", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            await installModpack(modpack);

                            return;
                        }


                        try
                        {
                            dynamic  profiles   = JsonConvert.DeserializeObject(profileString);
                            DateTime lastPlayed = profiles.profiles[modpack.UID].lastUsed;
                            lblLastPlayed.Text = PrettyTime.GetPrettyElapsedTime(lastPlayed);
                        } catch (Exception e)
                        {
                            _log.Info("Launcher profiles not containing selected modpack (\"" + modpack.UID + "\")");
                            _log.Debug(e);
                        }
                    }
                    else
                    {
                        if (installing == false)
                        {
                            btnInstallMopack.Text    = "Download and Install";
                            btnInstallMopack.Width   = pnlInstall.Width - 6;
                            btnInstallMopack.Enabled = true;
                        }
                        else
                        {
                            if (installingUID != modpack.UID)
                            {
                                btnInstallMopack.Text    = "Installing other Modpack";
                                btnInstallMopack.Enabled = false;
                            }
                        }
                    }
                }


                pcbIcon.Image = Properties.Resources.loading;
                if (Utils.validateURL(modpack.Icon))
                {
                    pcbIcon.Image = await Utils.loadBitmapFromUrl(modpack.Icon);
                }
                else
                {
                    pcbIcon.Image = Utils.emptyBitmap();
                }
            } catch (Exception e)
            {
                _log.Error("Error: Could not load Modpack details.");
                if (Directory.Exists(Path.Combine(Memory.modpacksLocation, Utils.convertIllegalPath(modpack.UID))))
                {
                    _log.Info(e, "Error: Uninstalling Modpack to fix bug.");
                    DialogResult uninstall = MessageBox.Show("Could not load Modpack details. Should the Modpack be uninstalled to fix this issue?", "Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
                    if (uninstall == DialogResult.OK)
                    {
                        await uninstallModpack(modpack);

                        return;
                    }
                    else
                    {
                        pnlDetails.Visible = false;
                    }
                }
            }

            modsTable = Utils.createDataTable(modpack.Mods);

            modsTable.Columns.Add("WebsiteShort");
            modsTable.Columns.Add("WebsiteShortArea", typeof(LinkArea));

            foreach (DataRow row in modsTable.Rows)
            {
                row.SetField("WebsiteShort", row.Field <string>("Website").truncateString(50, "..."));
                LinkArea linkArea = new LinkArea(0, row.Field <string>("Website").truncateString(50, "...").Length);
                row.SetField("WebsiteShortArea", linkArea);
            }

            modName.DataBindings.Clear();
            modWebsite.DataBindings.Clear();
            modVersion.DataBindings.Clear();

            modName.DataBindings.Add("Text", modsTable, "Name");
            modVersion.DataBindings.Add("Text", modsTable, "Version");
            modWebsite.DataBindings.Add("Text", modsTable, "WebsiteShort");
            modWebsite.DataBindings.Add("Tag", modsTable, "Website");
            modWebsite.DataBindings.Add("LinkArea", modsTable, "WebsiteShortArea");

            drMods.DataSource = modsTable;
        }
 public void SetText(string text, int startUnderlingIndex, int endUnderlineIndex)
 {
     base.Text = text;
     LinkArea  = new LinkArea(startUnderlingIndex, endUnderlineIndex);
 }
Exemple #27
0
        public void LinkArea_ToString_Invoke_ReturnsExpected()
        {
            var area = new LinkArea(1, 2);

            Assert.Equal("{Start=1, Length=2}", area.ToString());
        }
 public ToolTipLinkLabel()
 {
     LinkArea = new LinkArea(0, 0);
 }
        /// <summary>
        /// <para>Produces unmeasured display blocks from a single hybrid text. Marks highlights, if any.</para>
        /// <para>Does not fill in blocks' size, but fills in everything else.</para>
        /// </summary>
        /// <param name="htxt">Hybrid text to break down into blocks and measure.</param>
        /// <param name="isMeta">True if this is a domain or note (displayed in italics).</param>
        /// <param name="hl">Highlight to show in hybrid text, or null.</param>
        /// <param name="blocks">List of blocks to append to.</param>
        /// <param name="links">List to gather links (appending to list).</param>
        private void makeBlocks(HybridText htxt, bool isMeta, CedictTargetHighlight hl,
                                List <Block> blocks, List <LinkArea> links)
        {
            byte fntIdxLatin   = isMeta ? fntMetaLatin : fntSenseLatin;
            byte fntIdxZhoSimp = isMeta ? fntMetaHanziSimp : fntSenseHanziSimp;
            byte fntIdxZhoTrad = isMeta ? fntMetaHanziTrad : fntSenseHanziTrad;

            // Go run by run
            for (int runIX = 0; runIX != htxt.RunCount; ++runIX)
            {
                TextRun run = htxt.GetRunAt(runIX);
                // Latin run: split by spaces first
                if (run is TextRunLatin)
                {
                    string[] bySpaces = run.GetPlainText().Split(new char[] { ' ' });
                    // Each word: also by dash
                    int latnPos = 0;
                    foreach (string str in bySpaces)
                    {
                        string[] byDashes = splitByDash(str);
                        // Add block for each
                        int ofsPos = 0;
                        foreach (string blockStr in byDashes)
                        {
                            Block tb = new Block
                            {
                                TextPos    = textPool.PoolString(blockStr),
                                FontIdx    = fntIdxLatin,
                                SpaceAfter = false, // will set this true for last block in "byDashes"
                            };
                            // Does block's text intersect with highlight?
                            if (hl != null && hl.RunIx == runIX)
                            {
                                int blockStart = latnPos + ofsPos;
                                int blockEnd   = blockStart + blockStr.Length;
                                if (blockStart >= hl.HiliteStart && blockStart < hl.HiliteStart + hl.HiliteLength)
                                {
                                    tb.Hilite = true;
                                }
                                else if (blockEnd > hl.HiliteStart && blockEnd <= hl.HiliteStart + hl.HiliteLength)
                                {
                                    tb.Hilite = true;
                                }
                                else if (blockStart < hl.HiliteStart && blockEnd >= hl.HiliteStart + hl.HiliteLength)
                                {
                                    tb.Hilite = true;
                                }
                            }
                            blocks.Add(tb);
                            // Keep track of position for highlight
                            ofsPos += blockStr.Length;
                        }
                        // Make sure last one is followed by space
                        Block xb = blocks[blocks.Count - 1];
                        xb.SpaceAfter            = true;
                        blocks[blocks.Count - 1] = xb;
                        // Keep track of position in text - for highlights
                        latnPos += str.Length + 1;
                    }
                }
                // Chinese: depends on T/S/Both display mode, and on available info
                else
                {
                    TextRunZho zhoRun = run as TextRunZho;
                    // Chinese range is made up of:
                    // Simplified (empty string if only traditional requested)
                    // Separator (if both simplified and traditional are requested)
                    // Traditional (empty string if only simplified requested)
                    // Pinyin with accents as tone marks, in brackets (if present)
                    string strSimp = string.Empty;
                    if (analyzedScript != SearchScript.Traditional && zhoRun.Simp != null)
                    {
                        strSimp = zhoRun.Simp;
                    }
                    string strTrad = string.Empty;
                    if (analyzedScript != SearchScript.Simplified && zhoRun.Trad != null)
                    {
                        strTrad = zhoRun.Trad;
                    }
                    string strPy = string.Empty;
                    // Convert pinyin to display format (tone marks as diacritics; r5 glued)
                    if (zhoRun.Pinyin != null)
                    {
                        strPy = "[" + zhoRun.GetPinyinInOne(true) + "]";
                    }

                    // Create link area, with query string
                    string strPyNumbers = string.Empty; // Pinyin with numbers as tone marks
                    if (zhoRun.Pinyin != null)
                    {
                        strPyNumbers = zhoRun.GetPinyinRaw();
                    }
                    LinkArea linkArea = new LinkArea(strSimp, strTrad, strPyNumbers, analyzedScript);

                    // Block for simplified, if present
                    if (strSimp != string.Empty)
                    {
                        Block tb = new Block
                        {
                            TextPos    = textPool.PoolString(strSimp),
                            FontIdx    = fntIdxZhoSimp,
                            SpaceAfter = true,
                        };
                        blocks.Add(tb);
                        linkArea.BlockIds.Add(blocks.Count - 1);
                    }
                    // Separator if both simplified and traditional are there
                    // AND they are different...
                    if (strSimp != string.Empty && strTrad != string.Empty && strSimp != strTrad)
                    {
                        Block xb = blocks[blocks.Count - 1];
                        xb.StickRight            = true;
                        blocks[blocks.Count - 1] = xb;
                        Block tb = new Block
                        {
                            TextPos    = textPool.PoolString("•"),
                            FontIdx    = fntIdxLatin,
                            SpaceAfter = true,
                        };
                        blocks.Add(tb);
                        linkArea.BlockIds.Add(blocks.Count - 1);
                    }
                    // Traditional, if present
                    if (strTrad != string.Empty && strTrad != strSimp)
                    {
                        Block tb = new Block
                        {
                            TextPos    = textPool.PoolString(strTrad),
                            FontIdx    = fntIdxZhoTrad,
                            SpaceAfter = true,
                        };
                        blocks.Add(tb);
                        linkArea.BlockIds.Add(blocks.Count - 1);
                    }
                    // Pinyin, if present
                    if (strPy != string.Empty)
                    {
                        // Split by spaces
                        string[] pyParts = strPy.Split(new char[] { ' ' });
                        foreach (string pyPart in pyParts)
                        {
                            Block tb = new Block
                            {
                                TextPos    = textPool.PoolString(pyPart),
                                FontIdx    = fntIdxLatin,
                                SpaceAfter = true,
                            };
                            blocks.Add(tb);
                            linkArea.BlockIds.Add(blocks.Count - 1);
                        }
                    }
                    // Last part will have requested a space after.
                    // Look ahead and if next text run is Latin and starts with punctuation, make it stick
                    TextRunLatin nextLatinRun = null;
                    if (runIX + 1 < htxt.RunCount)
                    {
                        nextLatinRun = htxt.GetRunAt(runIX + 1) as TextRunLatin;
                    }
                    if (nextLatinRun != null && char.IsPunctuation(nextLatinRun.GetPlainText()[0]))
                    {
                        Block xb = blocks[blocks.Count - 1];
                        xb.SpaceAfter            = false;
                        blocks[blocks.Count - 1] = xb;
                    }
                    // Collect link area
                    links.Add(linkArea);
                }
            }
        }
	public static bool op_Equality(LinkArea linkArea1, LinkArea linkArea2) {}
 public static bool op_Inequality(LinkArea linkArea1, LinkArea linkArea2)
 {
 }