private void Switch(Rules.SwitchInfo info)
 {
     for (int i = 0; i < info.pops; i++)
     {
         stack.Pop();
     }
     if (info.next != null)
     {
         stack.Add(info.next);
     }
 }
Exemple #2
0
        public void CalcCutOffs(int wwSizeX)
        {
            this.wwSizeX = wwSizeX;
            cutOffs.Clear();
            int count = charsCount;

            if (count > 4)
            {
                int  i;
                int  left              = GetFirstSpaceSize(out i);
                int  pos               = left;
                int  lastSeparator     = 0;
                int  prevLastSeparator = 0;
                int  lastPos           = 0;
                char prev              = '\0';
                while (i < count)
                {
                    char c = chars[i].c;
                    if (!char.IsWhiteSpace(c) && (char.IsWhiteSpace(prev) || !char.IsLetterOrDigit(c)))
                    {
                        prevLastSeparator = lastSeparator;
                        lastSeparator     = i;
                        lastPos           = pos;
                    }
                    if (pos >= wwSizeX)
                    {
                        if (lastSeparator > prevLastSeparator)
                        {
                            i = lastSeparator;
                        }
                        else
                        {
                            if (left > 0 && cutOffs.count > 0)
                            {
                                int    index      = cutOffs.count - 1;
                                CutOff prevCutOff = cutOffs.buffer[index];
                                cutOffs.buffer[index] = new CutOff(prevCutOff.iChar, 0, prevCutOff.sizeX);
                                pos -= left;
                                left = 0;

                                prev = c;
                                pos  = c == '\t' ? ((pos + tabSize) / tabSize) * tabSize : pos + 1;
                                ++i;
                                continue;
                            }
                            else
                            {
                                lastSeparator = i;
                                lastPos       = pos;
                            }
                        }
                        cutOffs.Add(new CutOff(lastSeparator, left, lastPos));
                        pos = left;
                        prevLastSeparator = lastSeparator;
                        prev = '\0';
                    }
                    else
                    {
                        prev = c;
                        pos  = c == '\t' ? ((pos + tabSize) / tabSize) * tabSize : pos + 1;
                        ++i;
                    }
                }
                lastSublineSizeX = pos;
            }
            else
            {
                lastSublineSizeX = Size;
            }
        }
Exemple #3
0
        protected void InsertValuesRange(int index, T[] values)
        {
            if (index > this.valuesCount || index < 0)
            {
                throw new IndexOutOfRangeException("index=" + index + " is out of [0, " + this.valuesCount + "]");
            }
            int valuesCount = values.Length;
            int i;

            if (this.valuesCount == 0)
            {
                AllocateBlocks(1);
                blocksCount = 1;
                blocks[0]   = NewBlock();
                i           = 0;
            }
            else if (index == this.valuesCount)
            {
                i = blocksCount - 1;
            }
            else
            {
                i = GetBlockIndex(index);
            }
            TBlock target = blocks[i];
            int    j      = index - target.offset;

            if (j == 0 && i > 0 && blockSize - blocks[i - 1].count >= valuesCount)
            {
                i--;
                target = blocks[i];
                j      = index - target.offset;
            }
            if (valuesCount <= blockSize - target.count)
            {
                Array.Copy(target.array, j, target.array, j + valuesCount, target.count - j);
                Array.Copy(values, 0, target.array, j, valuesCount);
                target.count  += valuesCount;
                target.valid   = 0;
                target.wwSizeX = 0;
                UpdateIndices(i);
                return;
            }
            blocksBuffer.Clear();
            TBlock first;
            int    firstJ;

            if (i > 0)
            {
                TBlock left = blocks[i - 1];
                if (j <= blockSize - left.count)
                {
                    int leftCount = left.count;
                    first  = left;
                    firstJ = leftCount + j;
                    Array.Copy(target.array, 0, left.array, leftCount, j);
                    first.count += j;
                }
                else
                {
                    int leftCount = left.count;
                    first  = NewBlock();
                    firstJ = j - (blockSize - leftCount);
                    blocksBuffer.Add(first);

                    Array.Copy(target.array, 0, left.array, leftCount, blockSize - leftCount);
                    left.count   = blockSize;
                    left.valid   = 0;
                    left.wwSizeX = 0;

                    Array.Copy(target.array, blockSize - leftCount, first.array, 0, j - (blockSize - leftCount));
                    first.count = j - (blockSize - leftCount);
                }
                first.valid   = 0;
                first.wwSizeX = 0;
            }
            else
            {
                first  = NewBlock();
                firstJ = j;
                blocksBuffer.Add(first);
                Array.Copy(target.array, 0, first.array, 0, j);
                first.count = j;
            }
            int targetRightCount = target.count - j;

            if (first.count + valuesCount + targetRightCount <= blockSize)            //!!!! NOT COVERED !!!!!!
            {
                // first: [--------|-values-|-targetRight-|---]
                Array.Copy(values, 0, first.array, first.count, valuesCount);
                first.count += valuesCount;
                Array.Copy(target.array, j, first.array, first.count, targetRightCount);
                first.count += targetRightCount;
            }
            else if (first.count + valuesCount <= blockSize)
            {
                // first: [--------|-values-|-targetRight-----]
                // last:  [-targetRight-|---------------------]
                int targetRightCount0 = blockSize - (first.count + valuesCount);
                Array.Copy(values, 0, first.array, first.count, valuesCount);
                Array.Copy(target.array, j, first.array, first.count + valuesCount, targetRightCount0);
                TBlock last = NewBlock();
                blocksBuffer.Add(last);
                Array.Copy(target.array, j + targetRightCount0, last.array, 0, targetRightCount - targetRightCount0);
                first.count = blockSize;
                last.count  = targetRightCount - targetRightCount0;
            }
            else
            {
                int valuesFirstCount = blockSize - first.count;
                Array.Copy(values, 0, first.array, first.count, valuesFirstCount);
                first.count = blockSize;
                int n = (valuesCount - valuesFirstCount) / blockSize;
                int valuesLastCount = (valuesCount - valuesFirstCount) - n * blockSize;
                for (int ii = 0; ii < n; ii++)
                {
                    TBlock block = NewBlock();
                    blocksBuffer.Add(block);
                    Array.Copy(values, valuesFirstCount + ii * blockSize, block.array, 0, blockSize);
                    block.count = blockSize;
                }
                if (valuesLastCount + targetRightCount > 0)
                {
                    TBlock last = NewBlock();
                    blocksBuffer.Add(last);
                    Array.Copy(values, valuesCount - valuesLastCount, last.array, 0, valuesLastCount);
                    if (valuesLastCount + targetRightCount <= blockSize)
                    {
                        Array.Copy(target.array, j, last.array, valuesLastCount, targetRightCount);
                        last.count = valuesLastCount + targetRightCount;
                    }
                    else
                    {
                        Array.Copy(target.array, j, last.array, valuesLastCount, blockSize - valuesLastCount);
                        TBlock last2 = NewBlock();
                        blocksBuffer.Add(last2);
                        Array.Copy(target.array, j + (blockSize - valuesLastCount), last2.array, 0, targetRightCount - (blockSize - valuesLastCount));
                        last.count  = blockSize;
                        last2.count = targetRightCount - (blockSize - valuesLastCount);
                    }
                }
            }
            if (blocksBuffer.count == 0)            //!!!! NOT COVERED !!!!!!
            {
                RemoveBlocks(i, i + 1);
            }
            else if (blocksBuffer.count == 1)
            {
                blocks[i] = blocksBuffer.buffer[0];
            }
            else
            {
                int oldBlocksCount = blocksCount;
                AllocateBlocks(blocksCount - 1 + blocksBuffer.count);
                Array.Copy(blocks, i + 1, blocks, i + blocksBuffer.count, oldBlocksCount - i - 1);
                int blocksBufferCount = blocksBuffer.count;
                for (int ii = 0; ii < blocksBufferCount; ii++)
                {
                    blocks[ii + i] = blocksBuffer.buffer[ii];
                }
            }
            blocksBuffer.Clear();
            UpdateIndices(i);
        }
Exemple #4
0
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g       = e.Graphics;
            int      width   = Width;
            int      x       = charWidth;
            int      indent  = charWidth;
            int      yOffset = 3;

            g.FillRectangle(scheme.tabsBg.brush, 0, 0, width - charWidth, charHeight);

            leftIndent = charWidth;
            if (text != null)
            {
                Brush fg = scheme.tabsFg.brush;
                for (int j = 0; j < text.Length; j++)
                {
                    g.DrawString(text[j] + "", font, fg, 10 - charWidth / 3 + j * charWidth, yOffset, stringFormat);
                }
                leftIndent += (charWidth + 1) * text.Length;
            }

            rects.Clear();
            if (list != null)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    T         value   = list[i];
                    string    tabText = stringOf(value);
                    Rectangle rect    = new Rectangle(x - indent, 0, tabText.Length * charWidth + indent * 2, charHeight);
                    x += tabText.Length * charWidth + indent * 2;
                    rects.Add(rect);
                }
            }
            string text2 = list != null && list.Selected != null && text2Of != null?
                           text2Of(list.Selected) :
                               text2 = this.text2;

            rightIndent = charHeight * 5 / 4 + (text2 != null ? text2.Length * charWidth : 0);
            if (x > width - leftIndent - rightIndent && list.Count > 1)
            {
                rightIndent += charHeight * 5 / 4;
                leftRect     = new Rectangle(width - rightIndent, 0, charWidth * 3 / 2, charHeight);
                rightRect    = new Rectangle(width - rightIndent + charWidth * 3 / 2, 0, charWidth * 3 / 2, charHeight);
                ScrollToSelectedIfNeed();
                if (offsetIndex < 0)
                {
                    offsetIndex = 0;
                }
                else if (offsetIndex > rects.count - 1)
                {
                    offsetIndex = rects.count - 1;
                }
                if (offsetIndex > 0)
                {
                    for (int i = offsetIndex; i-- > 0;)
                    {
                        if (rects.buffer[rects.count - 1].Right + GetOffsetX(i) > width - rightIndent - 1)
                        {
                            break;
                        }
                        offsetIndex = i;
                    }
                }
            }
            else
            {
                leftRect    = null;
                rightRect   = null;
                offsetIndex = 0;
            }
            int selectedX0 = 0;
            int selectedX1 = 0;

            if (list != null)
            {
                int  offsetX       = GetOffsetX(offsetIndex);
                int  selectedIndex = list.IndexOf(list.Selected);
                bool prevSelected  = false;
                for (int i = Math.Max(0, offsetIndex - 1); i < list.Count; i++)
                {
                    T         value     = list[i];
                    string    tabText   = stringOf(value);
                    bool      isCurrent = !buttonMode && object.Equals(list.Selected, value);
                    Rectangle rect      = rects.buffer[i];
                    rect.X += offsetX;
                    if (rect.X > width)
                    {
                        break;
                    }

                    if (isCurrent)
                    {
                        tempPoints4[0] = new Point(rect.X + 1, rect.Y + 1);
                        tempPoints4[1] = new Point(rect.X + rect.Width - rect.Height / 2, rect.Y + 1);
                        tempPoints4[2] = new Point(rect.X + rect.Width + rect.Height / 2, rect.Y + rect.Height);
                        tempPoints4[3] = new Point(rect.X + 1, rect.Y + rect.Height);
                        g.FillPolygon(scheme.tabsSelectedBg.brush, tempPoints4);
                        selectedX0 = rect.X;
                        selectedX1 = rect.X + rect.Width;
                    }
                    if (!isCurrent)
                    {
                        if (buttonMode)
                        {
                            g.FillRectangle(scheme.buttonBgBrush,
                                            rect.X + 1, rect.Y + 2, rect.Width - 2, rect.Height - 4);
                        }
                        else if (i < selectedIndex)
                        {
                            g.FillRectangle(scheme.tabsUnselectedBg.brush,
                                            rect.X + 1, rect.Y + 1, rect.Width - 1, rect.Height - 2);
                        }
                        else
                        {
                            tempPoints4[0] = new Point(rect.X - rect.Height / 2 + 1, rect.Y + 1);
                            tempPoints4[1] = new Point(rect.X + rect.Width - rect.Height / 2, rect.Y + 1);
                            tempPoints4[2] = new Point(rect.X + rect.Width + rect.Height / 2 - 1, rect.Y + rect.Height - 1);
                            tempPoints4[3] = new Point(rect.X + rect.Height / 2, rect.Y + rect.Height - 1);
                            g.FillPolygon(scheme.tabsUnselectedBg.brush, tempPoints4);
                        }
                    }
                    Brush currentFg = isCurrent ? scheme.tabsSelectedFg.brush : scheme.tabsUnselectedFg.brush;
                    if (buttonMode)
                    {
                        currentFg = scheme.buttonFgBrush;
                    }
                    for (int j = 0; j < tabText.Length; j++)
                    {
                        int charX = rect.X - charWidth / 3 + j * charWidth + indent;
                        if (charX > 0 && charX < width - rightIndent - charWidth * 2)
                        {
                            g.DrawString(tabText[j] + "", font, currentFg, charX, yOffset, stringFormat);
                        }
                    }
                    rects.Add(rect);
                    prevSelected = isCurrent;
                }
            }

            int fictiveIndent = rightIndent - charHeight / 4;
            {
                tempPoints5[0] = new Point(width - fictiveIndent - charHeight / 2, charHeight / 2);
                tempPoints5[1] = new Point(width - fictiveIndent, 0);
                tempPoints5[2] = new Point(width, 0);
                tempPoints5[3] = new Point(width, charHeight);
                tempPoints5[4] = new Point(width - fictiveIndent + (charHeight % 2), charHeight);
                g.FillPolygon(_selected ? scheme.tabsInfoBg.brush : scheme.tabsBg.brush, tempPoints5);
                Pen pen = _selected ? scheme.tabsBg.pen : scheme.tabsInfoBg.pen;
                g.DrawLine(pen,
                           new Point(width - fictiveIndent, 0),
                           new Point(width - fictiveIndent - charHeight / 2, charHeight / 2));
                g.DrawLine(pen,
                           new Point(width - fictiveIndent - charHeight / 2, charHeight / 2),
                           new Point(width - fictiveIndent + (charHeight % 2), charHeight));
            }

            int closeWidth = charHeight * 12 / 10;

            closeRect = new Rectangle(width - closeWidth, 0, closeWidth, charHeight);
            DrawCross(g);
            if (leftRect != null)
            {
                DrawArrow(g, true);
            }
            if (rightRect != null)
            {
                DrawArrow(g, false);
            }
            if (text2 != null)
            {
                Brush infoBrush = _selected ? scheme.tabsInfoFg.brush : scheme.tabsFg.brush;
                int   left      = width - text2.Length * charWidth - charHeight * 3 / 2;
                for (int j = 0; j < text2.Length; j++)
                {
                    g.DrawString(
                        text2[j] + "", font, infoBrush,
                        left + charWidth * 2 / 3 + j * charWidth, yOffset - 2, stringFormat);
                }
            }

            base.OnPaint(e);
        }
        public bool Parse(LineArray lines, int maxMilliseconds)
        {
#if HIGHLIGHTER_DEBUG
            if (_debugStopwatch == null)
            {
                _debugStopwatch = new System.Diagnostics.Stopwatch();
                _debugStopwatch.Start();
                Console.WriteLine("HIGHLIGHTER START");
            }
#endif
            DateTime startTime = DateTime.Now;
            int      changesBeforeTimeCheck = 0;
            bool     timeElapsed            = false;
            bool     changed = false;
            stack = new PredictableList <Rules.Context>(8);
            stack.Add(contexts[0]);
            Rules.Context[] state           = stack.ToArray();
            bool            needSetStack    = false;
            bool            lastLineChanged = false;
            for (int i = 0; i < lines.blocksCount; i++)
            {
                LineBlock block = lines.blocks[i];
                if (timeElapsed && lastLineChanged)
                {
                    while (block.count == 0)
                    {
                        i++;
                        if (i >= lines.blocksCount)
                        {
                            block = null;
                            break;
                        }
                        block = lines.blocks[i];
                    }
                    if (block != null)
                    {
                        block.valid &= ~LineBlock.ColorValid;
                        Line line = block.array[0];
                        line.startState = state;
                        line.endState   = null;
                    }
                    stack = null;
                    return(changed);
                }
                {
                    bool noChangesInBlock = (block.valid & LineBlock.ColorValid) != 0 && !lastLineChanged;
                    if (noChangesInBlock && block.count > 0)
                    {
                        Rules.Context[] nextState = block.array[block.count - 1].endState;
                        if (nextState == null)
                        {
                            noChangesInBlock = false;
                        }
                        else
                        {
                            state = nextState;
                        }
                    }
                    if (noChangesInBlock)
                    {
                        needSetStack = true;
                        continue;
                    }
                }
                block.valid |= LineBlock.ColorValid;
                for (int j = 0; j < block.count; j++)
                {
                    Line line = block.array[j];
                    if (AreEquals(line.startState, state) && line.endState != null)
                    {
                        state           = line.endState;
                        needSetStack    = true;
                        lastLineChanged = false;
                        continue;
                    }
                    if (needSetStack)
                    {
                        needSetStack = false;
                        stack.Resize(state.Length);
                        Array.Copy(state, stack.buffer, stack.count);
                    }
                    line.startState = state;
                    string text = line.Text;
                    Array.Clear(awakePositions, 0, awakePositions.Length);
                    int        position    = 0;
                    int        count       = line.charsCount;
                    Rules.Rule lastMatched = null;
                    while (position < count)
                    {
                        Rules.Context context = stack.count > 0 ? stack.Peek() : contexts[0];
                        lastMatched = null;
                        foreach (Rules.Rule rule in context.childs)
                        {
                            int nextPosition;
                            if ((rule.column == -1 || position == rule.column) && rule.Match(text, position, out nextPosition))
                            {
                                if (!rule.lookAhead)
                                {
                                    for (; position < nextPosition; position++)
                                    {
                                        line.chars[position].style = rule.attribute.index;
                                    }
                                }
                                if (rule.childs != null && position < count)
                                {
                                    foreach (Rules.Rule childRule in rule.childs)
                                    {
                                        int childNextPosition;
                                        if (childRule.Match(text, nextPosition, out childNextPosition))
                                        {
                                            for (; position < childNextPosition; position++)
                                            {
                                                line.chars[position].style = childRule.attribute.index;
                                            }
                                            Switch(rule.context);
                                        }
                                    }
                                }
                                Switch(rule.context);
                                lastMatched = rule;
                                break;
                            }
                        }
                        if (lastMatched == null)
                        {
                            if (context.fallthrough)
                            {
                                Switch(context.fallthroughContext);
                            }
                            else
                            {
                                line.chars[position].style = context.attribute.index;
                                position++;
                            }
                        }
                    }
                    if (lastMatched == null || !lastMatched.isLineContinue)
                    {
                        while (stack.count > 0)
                        {
                            Rules.Context contextI = stack.Peek();
                            if (contextI.lineEndContext.next == null && contextI.lineEndContext.pops == 0)
                            {
                                break;
                            }
                            Switch(contextI.lineEndContext);
                        }
                    }
                    if (AreEquals(stack, state))
                    {
                        line.endState = state;
                    }
                    else
                    {
                        state         = stack.ToArray();
                        line.endState = state;
                    }
                    changesBeforeTimeCheck++;
                    lastLineChanged = true;
                    changed         = true;
                }
                if (changesBeforeTimeCheck > 50)
                {
                    changesBeforeTimeCheck = 0;
                    DateTime nextTime = DateTime.Now;
                    timeElapsed = (nextTime - startTime).TotalMilliseconds > maxMilliseconds;
                    if (timeElapsed)
                    {
                        startTime = nextTime;
                    }
                }
            }
            stack = null;
            lastParsingChanged = changed;
            if (!changed && lines.ranges != null)
            {
                foreach (StyleRange range in lines.ranges)
                {
                    lines.SetStyleRange(range);
                }
            }
#if HIGHLIGHTER_DEBUG
            if (!changed)
            {
                _debugStopwatch.Stop();
                Console.WriteLine("HIGHLIGHTER TIME: " + (_debugStopwatch.Elapsed.TotalMilliseconds / 1000).ToString("0.00"));
            }
#endif
            return(changed);
        }