Ejemplo n.º 1
0
        protected override void AddLayoutLine(LayoutLine line, VisualElementType elementType, LineExportConfig lineConfig)
        {
            switch (elementType)
            {
            case VisualElementType.Fret:
                AddDxfLine("Frets", line, lineConfig);
                break;

            case VisualElementType.String:
                AddDxfLine("Strings", line, lineConfig);
                break;

            case VisualElementType.FingerboardEdge:
            case VisualElementType.FingerboardMargin:
            case VisualElementType.FingerboardContinuation:
                AddDxfLine("Fingerboard", line, lineConfig);
                break;

            case VisualElementType.CenterLine:
            case VisualElementType.GuideLine:
            case VisualElementType.StringMidline:
                AddDxfLine("Layout", line, lineConfig);
                break;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Moves the position to the end of wrapped line.
        /// </summary>
        /// <param name="displayContext">The display context.</param>
        public static TextPosition ToEndOfWrappedLine(
            this TextPosition bufferPosition,
            IDisplayContext displayContext)
        {
            // Get the wrapped line and layout.
            Layout     layout;
            int        wrappedLineIndex;
            LayoutLine wrappedLine = bufferPosition.GetWrappedLine(
                displayContext, out layout, out wrappedLineIndex);

            // Move to the end of the wrapped line. If this isn't the last, we
            // need to shift back one character.
            int unicodeIndex = wrappedLine.StartIndex + wrappedLine.Length;

            if (wrappedLineIndex != layout.LineCount - 1)
            {
                unicodeIndex--;
            }

            // Because the wrappedLine works with UTF-8 encoding, we need to
            // convert it back to a C# string.
            string lineText =
                displayContext.LineBuffer.GetLineText(bufferPosition.LinePosition);
            int characterIndex = PangoUtility.TranslatePangoToStringIndex(
                lineText, unicodeIndex);

            // Create a new buffer position from the elements and return it.
            return(new TextPosition(bufferPosition.LinePosition, characterIndex));
        }
Ejemplo n.º 3
0
 private SvgLine CreateSvgLine(SvgElement owner, LayoutLine line, LineExportConfig lineConfig)
 {
     return CreateSvgLine(owner, line.P1, line.P2, 
         GetLineThickness(lineConfig), 
         lineConfig.Color, 
         lineConfig.IsDashed ? LineDashPattern : null);
 }
Ejemplo n.º 4
0
        public SkiaTextLayout(
            string value,
            RectangleF rect,
            ITextAttributes textAttributes,
            LayoutLine callback,
            TextFlow textFlow = TextFlow.ClipBounds,
            SKPaint paint     = null)
        {
            _value          = value;
            _textAttributes = textAttributes;
            _rect           = rect;
            _callback       = callback;
            _textFlow       = textFlow;
            _paint          = paint;

            if (paint == null)
            {
                _paint = new SKPaint()
                {
                    Typeface = SkiaDelegatingFontService.Instance.GetTypeface(_textAttributes.FontName),
                    TextSize = _textAttributes.FontSize
                };

                _disposePaint = true;
            }

            var metrics = _paint.FontMetrics;

            _descent    = metrics.Descent;
            _lineHeight = _paint.FontSpacing;
        }
Ejemplo n.º 5
0
        public static void PageUp(EditorViewController controller)
        {
            // Extract a number of useful variable for this method.
            IDisplayContext displayContext = controller.DisplayContext;
            TextPosition    position       = displayContext.Caret.Position;

            // Figure out the layout and wrapped line we are currently on.
            Layout     layout;
            int        wrappedLineIndex;
            LayoutLine wrappedLine = position.GetWrappedLine(
                displayContext, out layout, out wrappedLineIndex);

            // Figure out where in the buffer we're located.
            int lineHeight;

            PointD point = position.ToScreenCoordinates(displayContext, out lineHeight);

            // Shift down the buffer a full page size and clamp it to the actual
            // buffer size.
            double bufferY =
                Math.Max(point.Y - displayContext.VerticalAdjustment.PageSize, 0);

            // Figure out the X coordinate of the line. If there is an action context,
            // use that. Otherwise, calculate it from the character index of the position.
            int pixels = Units.ToPixels(GetLineX(controller, wrappedLine, position));
            int lineX  = pixels;

            // Move to the calculated point.
            var newPoint = new PointD(lineX, bufferY - displayContext.BufferOffsetY);

            Point(controller, newPoint);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets the line X coordinates from either the state if we have one
        /// or calculate it from the buffer position's X coordinate.
        /// </summary>
        /// <param name="controller">The action context.</param>
        /// <param name="wrappedLine">The wrapped line.</param>
        /// <param name="position">The position.</param>
        /// <returns></returns>
        private static int GetLineX(
            EditorViewController controller,
            LayoutLine wrappedLine,
            TextPosition position)
        {
            int lineX;
            var state = controller.States.Get <VerticalMovementActionState>();

            if (state == null)
            {
                // Calculate the line state from the caret position. The cursor
                // is always to the left of the character unless we're at the
                // end, and then it's considered trailing of the previous
                // character.
                LineBuffer lineBuffer     = controller.DisplayContext.LineBuffer;
                int        lineIndex      = position.LinePosition.GetLineIndex(lineBuffer.LineCount);
                string     lineText       = lineBuffer.GetLineText(lineIndex);
                int        characterIndex = position.CharacterPosition.GetCharacterIndex(lineText);
                bool       trailing       = false;

                if (characterIndex == lineText.Length &&
                    lineText.Length > 0)
                {
                    characterIndex--;
                    trailing = true;
                }

                // Because Pango works with UTF-8-based indexes, we need to
                // convert the C# character index into that index to properly
                // identify the character.
                characterIndex = NormalizeEmptyStrings(lineText, characterIndex);
                int unicodeIndex = PangoUtility.TranslateStringToPangoIndex(
                    lineText, characterIndex);
                lineX = wrappedLine.IndexToX(unicodeIndex, trailing);

                // We need the line's style since it may have left passing
                // which will change our columns.
                LineBlockStyle style =
                    controller.DisplayContext.Renderer.GetLineStyle(
                        lineIndex, LineContexts.CurrentLine);

                var pixelPadding = (int)style.Padding.Left.GetValueOrDefault(0);
                lineX += Units.FromPixels(pixelPadding);

                // Save a new state into the states.
                state = new VerticalMovementActionState(lineX);
                controller.States.Add(state);
            }
            else
            {
                // Get the line coordinate from the state.
                lineX = state.LayoutLineX;
            }

            return(lineX);
        }
        /// <summary>
        /// Gets the string index for an X coordinate.
        /// </summary>
        /// <param name="layoutLine">The layout line.</param>
        /// <param name="stringIndex">Index of the string.</param>
        /// <param name="trailing">if set to <c>true</c> [trailing].</param>
        /// <returns></returns>
        public static int TranslatedIndexToX(
            this LayoutLine layoutLine,
            int stringIndex,
            bool trailing)
        {
            int pangoIndex =
                PangoUtility.TranslateStringToPangoIndex(
                    layoutLine.Layout.Text, stringIndex);

            return(layoutLine.IndexToX(pangoIndex, trailing));
        }
        /// <summary>
        /// Gets the string index for a given X coordinate (in Pango units).
        /// </summary>
        /// <param name="layoutLine">The layout line.</param>
        /// <param name="x">The x.</param>
        /// <param name="stringIndex">Index of the string.</param>
        /// <param name="trailing">The trailing.</param>
        /// <returns></returns>
        public static bool XToTranslatedIndex(
            this LayoutLine layoutLine,
            int x,
            out int stringIndex,
            out int trailing)
        {
            int  pangoIndex;
            bool results = layoutLine.XToIndex(x, out pangoIndex, out trailing);

            stringIndex = PangoUtility.TranslatePangoToStringIndex(
                layoutLine.Layout.Text, pangoIndex);
            return(results);
        }
        /// <summary>
        /// Gets the X ranges from the given string indexes.
        /// </summary>
        /// <param name="layoutLine">The layout line.</param>
        /// <param name="startStringIndex">Start index of the string.</param>
        /// <param name="endStringIndex">End index of the string.</param>
        /// <param name="ranges">The ranges.</param>
        public static void GetTranslatedXRanges(
            this LayoutLine layoutLine,
            int startStringIndex,
            int endStringIndex,
            out int[][] ranges)
        {
            int startPangoIndex =
                PangoUtility.TranslateStringToPangoIndex(
                    layoutLine.Layout.Text, startStringIndex);
            int endPangoIndex =
                PangoUtility.TranslateStringToPangoIndex(
                    layoutLine.Layout.Text, endStringIndex);

            layoutLine.GetXRanges(startPangoIndex, endPangoIndex, out ranges);
        }
Ejemplo n.º 10
0
        private Line AddDxfLine(string layerName, LayoutLine line, LineExportConfig lineConfig)
        {
            var dxfLine = new Line(PointToVector(line.P1), PointToVector(line.P2))
            {
                Layer = GetLayer(layerName),
                Color = GetColor(lineConfig.Color)
            };

            if (lineConfig.IsDashed)
            {
                dxfLine.Linetype = Linetype.Dashed;
            }

            Document.AddEntity(dxfLine);
            return(dxfLine);
        }
        /// <summary>
        /// Gets the index of the layout line inside the layout.
        /// </summary>
        /// <param name="layoutLine">The layout line.</param>
        /// <returns></returns>
        public static int GetLayoutLineIndex(this LayoutLine layoutLine)
        {
            // Go through all the lines in the layout and find the index.
            for (int index = 0;
                 index < layoutLine.Layout.LineCount;
                 index++)
            {
                if (layoutLine.Layout.Lines[index].StartIndex == layoutLine.StartIndex)
                {
                    return(index);
                }
            }

            // We can't find this layout line inside the layout.
            throw new Exception("Cannot find layout line inside layout");
        }
Ejemplo n.º 12
0
        protected override void AddLayoutLine(LayoutLine line, VisualElementType elementType, LineExportConfig lineConfig)
        {
            switch (elementType)
            {
                case VisualElementType.Fret:
                    {
                        var svgLine = CreateSvgLine(GetLayer("Frets"), line, lineConfig);

                        if (line.Tag is FretLine fretLine)
                        {
                            if (fretLine.IsNut)
                                svgLine.CustomAttributes.Add("Fret", "Nut");
                            else
                                svgLine.CustomAttributes.Add("Fret", fretLine.FretIndex.ToString());
                        }
                        break;
                    }
                
                case VisualElementType.FingerboardEdge:
                case VisualElementType.FingerboardMargin:
                case VisualElementType.FingerboardContinuation:
                    CreateSvgLine(GetLayer("Fingerboard"), line, lineConfig);
                    break;

                case VisualElementType.CenterLine:
                case VisualElementType.StringMidline:
                case VisualElementType.GuideLine:
                    CreateSvgLine(GetLayer("Layout"), line, lineConfig);
                    break;

                case VisualElementType.String:
                    {
                        var stringInfo = line as StringLine;
                        SvgLine svgLine;
                        if (Options.UseStringGauge && !stringInfo.String.Gauge.IsEmpty)
                        {
                            var lineThickness = GetRelativeUnit(stringInfo.String.Gauge);
                            svgLine = CreateSvgLine(GetLayer("Strings"), line, lineThickness, Options.Strings.Color);
                        }
                        else
                            svgLine = CreateSvgLine(GetLayer("Strings"), line, lineConfig);

                        svgLine.CustomAttributes.Add("Index", stringInfo.Index.ToString());
                        break;
                    }
            }
        }
Ejemplo n.º 13
0
        private void GenerateFingerboard()
        {
            foreach (var fingerboardEdge in Layout.VisualElements.OfType <FingerboardSideEdge>())
            {
                AddLayoutLine(fingerboardEdge, VisualElementType.FingerboardEdge, Options.FingerboardEdges);
            }

            foreach (var fingerboardEdge in Layout.VisualElements.OfType <FingerboardEdge>())
            {
                if (fingerboardEdge.Points.Count == 2)
                {
                    var layoutLine = new LayoutLine(fingerboardEdge.Points.First(), fingerboardEdge.Points.Last());
                    AddLayoutLine(layoutLine, VisualElementType.FingerboardEdge, Options.FingerboardEdges);
                }
                else if (fingerboardEdge.Spline != null)
                {
                    AddLayoutSpline(fingerboardEdge, VisualElementType.FingerboardEdge, Options.FingerboardEdges);
                }
                else
                {
                    AddLayoutPolyLine(fingerboardEdge, VisualElementType.FingerboardEdge, Options.FingerboardEdges);
                }
            }

            if (!Options.ExportFrets)
            {
                var nutLines = Layout.GetElements <FretLine>(x => x.IsNut);

                foreach (var line in nutLines)
                {
                    if (line.IsStraight)
                    {
                        var layoutLine = new LayoutLine(line.Points.First(), line.Points.Last());
                        AddLayoutLine(layoutLine, VisualElementType.FingerboardEdge, Options.FingerboardEdges);
                    }
                    else if (line.Spline != null)
                    {
                        AddLayoutSpline(line, VisualElementType.FingerboardEdge, Options.FingerboardEdges);
                    }
                    else
                    {
                        AddLayoutPolyLine(line, VisualElementType.FingerboardEdge, Options.FingerboardEdges);
                    }
                }
            }
        }
Ejemplo n.º 14
0
        internal LayoutLine GetStringBoundaryLine(SIString str, FingerboardSide dir)
        {
            LayoutLine boundary = null;

            if (dir == FingerboardSide.Bass)
            {
                boundary = VisualElements.OfType <StringCenter>().FirstOrDefault(c => c.Right.Index == str.Index);
            }
            else
            {
                boundary = VisualElements.OfType <StringCenter>().FirstOrDefault(c => c.Left.Index == str.Index);
            }

            if (boundary == null)
            {
                return(VisualElements.OfType <FingerboardSideEdge>().First(e => e.Side == dir));
            }

            return(boundary);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Moves the position to the beginning of wrapped line.
        /// </summary>
        /// <param name="displayContext">The display context.</param>
        public static TextPosition ToBeginningOfWrappedLine(
            this TextPosition bufferPosition,
            IDisplayContext displayContext)
        {
            // Wrapped lines (via Pango) work with UTF-8 encoding, not the
            // normal C# string indexes. We need to get the index and convert
            // it to a character string since that is what this library uses.
            LayoutLine wrappedLine  = bufferPosition.GetWrappedLine(displayContext);
            int        unicodeIndex = wrappedLine.StartIndex;

            // Because the wrappedLine works with UTF-8 encoding, we need to
            // convert it back to a C# string.
            string lineText =
                displayContext.LineBuffer.GetLineText(bufferPosition.LinePosition);
            int characterIndex = PangoUtility.TranslatePangoToStringIndex(
                lineText, unicodeIndex);

            // Create a new buffer position from the elements and return it.
            return(new TextPosition(bufferPosition.LinePosition, characterIndex));
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Determines whether the position is at the end of a wrapped line.
        /// </summary>
        /// <param name="displayContext">The display context.</param>
        /// <returns>
        ///     <c>true</c> if [is end of wrapped line] [the specified display context]; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsEndOfWrappedLine(
            this TextPosition bufferPosition,
            IDisplayContext displayContext)
        {
            // Get the wrapped line and layout.
            Layout     layout;
            int        wrappedLineIndex;
            LayoutLine wrappedLine = bufferPosition.GetWrappedLine(
                displayContext, out layout, out wrappedLineIndex);

            // Move to the end of the wrapped line. If this isn't the last, we
            // need to shift back one character.
            int wrappedCharacterIndex = wrappedLine.StartIndex + wrappedLine.Length;

            if (wrappedLineIndex != layout.LineCount - 1)
            {
                wrappedCharacterIndex--;
            }

            // Return if these are equal.
            return(bufferPosition.CharacterPosition == wrappedCharacterIndex);
        }
        /// <summary>
        /// Gets the size of the wrapped line in pixels and relative to the layout.
        /// </summary>
        /// <param name="layoutLine">The layout line.</param>
        /// <param name="size">The size.</param>
        public static void GetPixelExtents(
            this LayoutLine layoutLine,
            out Rectangle size)
        {
            // Go through and populate the size regions.
            size       = new Rectangle();
            size.X     = 0;
            size.Width = layoutLine.Layout.Width;

            // Build up the Y coordinates of all the lines before it.
            int layoutLineIndex = layoutLine.GetLayoutLineIndex();
            int y = 0;

            for (int index = 0;
                 index < layoutLineIndex;
                 index++)
            {
                LayoutLine preceedingLayoutLine = layoutLine.Layout.Lines[index];
                var        ink     = new Rectangle();
                var        logical = new Rectangle();

                preceedingLayoutLine.GetPixelExtents(ref ink, ref logical);

                y += logical.Height;
            }

            size.Y = y;

            // Figure out the height of the given wrapped line.
            var ink2     = new Rectangle();
            var logical2 = new Rectangle();

            layoutLine.GetPixelExtents(ref ink2, ref logical2);

            size.Height = logical2.Height;
        }
Ejemplo n.º 18
0
 private void DrawLine(Graphics g, LayoutLine line, Pen pen)
 {
     DrawLine(g, pen, line.P1, line.P2);
 }
Ejemplo n.º 19
0
        private void CreateFingerboardEdges()
        {
            //apply margin perpendicularly to the treble string
            var trebleLine   = FirstString.LayoutLine;
            var trebleOffset = Measure.Zero;

            if (Margins.CompensateStringGauge && !FirstString.Gauge.IsEmpty)
            {
                trebleOffset += FirstString.Gauge / 2;
            }
            var trebleFretboardEdge = AddVisualElement(new FingerboardSideEdge(
                                                           trebleLine.GetPerpendicularPoint(trebleLine.P1, Margins.TrebleMargins[FingerboardEnd.Nut] + trebleOffset),
                                                           trebleLine.GetPerpendicularPoint(trebleLine.P2, Margins.TrebleMargins[FingerboardEnd.Bridge] + trebleOffset),
                                                           FingerboardSide.Treble));

            //apply margin perpendicularly to the bass string
            var bassLine   = LastString.LayoutLine;
            var bassOffset = Measure.Zero;

            if (Margins.CompensateStringGauge && !LastString.Gauge.IsEmpty)
            {
                bassOffset += LastString.Gauge / 2;
            }
            var bassFretboardEdge = AddVisualElement(new FingerboardSideEdge(
                                                         bassLine.GetPerpendicularPoint(bassLine.P1, (Margins.BassMargins[FingerboardEnd.Nut] + bassOffset) * -1), //*-1 to offset towards left
                                                         bassLine.GetPerpendicularPoint(bassLine.P2, (Margins.BassMargins[FingerboardEnd.Bridge] + bassOffset) * -1),
                                                         FingerboardSide.Bass));

            //adjust the end points of each edges so that they are "inline" with the strings
            if (NumberOfStrings >= 2)
            {
                var trebOpp     = GetStringBoundaryLine(FirstString, FingerboardSide.Bass) as StringCenter;
                var tp          = trebOpp.GetRelativePoint(trebleLine, trebleLine.P1);
                var trebNutLine = new LayoutLine(tp, trebleLine.P1);
                var trebBriLine = new LayoutLine(trebOpp.P2, trebleLine.P2);
                trebleFretboardEdge.P1 = trebleFretboardEdge.GetIntersection(trebNutLine);
                trebleFretboardEdge.P2 = trebleFretboardEdge.GetIntersection(trebBriLine);

                var bassOpp     = GetStringBoundaryLine(LastString, FingerboardSide.Treble) as StringCenter;
                var bp          = bassOpp.GetRelativePoint(bassLine, bassLine.P1);
                var bassNutLine = new LayoutLine(bp, bassLine.P1);
                var bassBriLine = new LayoutLine(bassOpp.P2, bassLine.P2);
                bassFretboardEdge.P1 = bassFretboardEdge.GetIntersection(bassNutLine);
                bassFretboardEdge.P2 = bassFretboardEdge.GetIntersection(bassBriLine);
            }
            //else if(/*ScaleLengthMode != ScaleLengthType.Individual && */NumberOfStrings > 1)
            //{
            //    var nutLine = new LayoutLine(trebleLine.FretZero, bassLine.FretZero);
            //    var bridgeLine = new LayoutLine(trebleLine.P2, bassLine.P2);

            //    if (FirstString.StartingFret == 0)
            //        trebleFretboardEdge.P1 = nutLine.GetIntersection(trebleFretboardEdge);
            //    else
            //        trebleFretboardEdge.P1 = trebleFretboardEdge.SnapToLine(trebleLine.P1, true);

            //    if (LastString.StartingFret == 0)
            //        bassFretboardEdge.P1 = nutLine.GetIntersection(bassFretboardEdge);
            //    else
            //        bassFretboardEdge.P1 = bassFretboardEdge.SnapToLine(bassLine.P1, true);

            //    trebleFretboardEdge.P2 = bridgeLine.GetIntersection(trebleFretboardEdge);
            //    bassFretboardEdge.P2 = bridgeLine.GetIntersection(bassFretboardEdge);
            //}
            else
            {
                trebleFretboardEdge.P1 = trebleFretboardEdge.SnapToLine(trebleLine.P1, LineSnapDirection.Horizontal);
                trebleFretboardEdge.P2 = trebleFretboardEdge.SnapToLine(trebleLine.P2, LineSnapDirection.Horizontal);
                bassFretboardEdge.P1   = bassFretboardEdge.SnapToLine(bassLine.P1, LineSnapDirection.Horizontal);
                bassFretboardEdge.P2   = bassFretboardEdge.SnapToLine(bassLine.P2, LineSnapDirection.Horizontal);
            }
        }
Ejemplo n.º 20
0
 private SvgLine CreateSvgLine(SvgElement owner, LayoutLine line, SvgUnit stroke, Color color)
 {
     return CreateSvgLine(owner, line.P1, line.P2, stroke, color, null);
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Called when the widget is exposed or drawn.
        /// </summary>
        /// <param name="e">The e.</param>
        /// <returns></returns>
        protected override bool OnExposeEvent(EventExpose e)
        {
            // Figure out the area we are rendering into.
            Gdk.Rectangle area      = e.Region.Clipbox;
            var           cairoArea = new Rectangle(area.X, area.Y, area.Width, area.Height);

            using (Context cairoContext = CairoHelper.Create(e.Window))
            {
                // Create a render context.
                var renderContext = new RenderContext(cairoContext);
                renderContext.RenderRegion = cairoArea;

                // If we don't have a buffer at this point, don't render anything.
                if (Renderer == null ||
                    LineBuffer == null)
                {
                    return(true);
                }

                // Paint the background color of the window.
                RegionBlockStyle backgroundStyle =
                    Theme.RegionStyles[Theme.BackgroundRegionStyleName];
                DrawingUtility.DrawLayout(this, renderContext, cairoArea, backgroundStyle);

                // Reset the layout and its properties.
                Renderer.Width = area.Width - margins.Width;

                // Figure out the viewport area we'll be drawing.
                int offsetY = 0;

                if (verticalAdjustment != null)
                {
                    offsetY += (int)verticalAdjustment.Value;
                }

                var viewArea = new Rectangle(
                    area.X, area.Y + offsetY, area.Width, area.Height);

                // Determine the line range visible in the given area.
                int startLine,
                    endLine;
                Renderer.GetLineLayoutRange(viewArea, out startLine, out endLine);

                // Determine where the first line actually starts.
                int startLineY = 0;

                if (startLine > 0)
                {
                    startLineY = Renderer.GetLineLayoutHeight(0, startLine - 1);
                }

                // Go through the lines and draw each one in the correct position.
                double currentY = startLineY - offsetY;

                for (int lineIndex = startLine;
                     lineIndex <= endLine;
                     lineIndex++)
                {
                    // Figure out if we are on the current line.
                    var  lineContexts = LineContexts.None;
                    bool currentLine  = false;

                    if (lineIndex == caret.Position.LinePosition)
                    {
                        // Add the curent line to the context.
                        lineContexts |= LineContexts.CurrentLine;
                        currentLine   = true;
                    }

                    // Pull out the layout and style since we'll use it.
                    Layout         layout = Renderer.GetLineLayout(lineIndex, lineContexts);
                    LineBlockStyle style  = Renderer.GetLineStyle(lineIndex, lineContexts);

                    // Get the extents for that line.
                    int layoutWidth,
                        layoutHeight;
                    layout.GetPixelSize(out layoutWidth, out layoutHeight);

                    // Figure out the height of the line including padding.
                    double height = layoutHeight + style.Height;

                    if (currentLine)
                    {
                        // If we have a full-line background color, display it.
                        RegionBlockStyle currentLineStyle =
                            Theme.RegionStyles[Theme.CurrentLineRegionStyleName];

                        if (currentLineStyle != null)
                        {
                            var lineArea = new Rectangle(TextX, currentY, TextWidth, height);

                            DrawingUtility.DrawLayout(
                                this, renderContext, lineArea, currentLineStyle);
                        }

                        // If we have a wrapped line background color, draw it.
                        RegionBlockStyle currentWrappedLineStyle =
                            Theme.RegionStyles[Theme.CurrentWrappedLineRegionStyleName];

                        if (currentWrappedLineStyle != null)
                        {
                            // Get the wrapped line for the caret's position.
                            LayoutLine      wrappedLine = caret.Position.GetWrappedLine(this);
                            Pango.Rectangle wrappedLineExtents;

                            wrappedLine.GetPixelExtents(out wrappedLineExtents);

                            // Draw the current wrapped line index.
                            var wrappedLineArea = new Rectangle(
                                TextX,
                                currentY + wrappedLineExtents.Y + style.Top,
                                TextWidth,
                                wrappedLineExtents.Height);

                            DrawingUtility.DrawLayout(
                                this, renderContext, wrappedLineArea, currentWrappedLineStyle);
                        }
                    }

                    // Draw the current line along with wrapping and padding.
                    DrawingUtility.DrawLayout(
                        this,
                        renderContext,
                        new Rectangle(TextX, currentY, TextWidth, height),
                        layout,
                        style);

                    // Render out the margin renderers.
                    margins.Draw(
                        this, renderContext, lineIndex, new PointD(0, currentY), height, style);

                    // Move down a line.
                    currentY += height;
                }

                // Draw the caret on the screen, but only if we have focus.
                if (IsFocus)
                {
                    caret.Draw(renderContext);
                }

                // Show the scroll region, if requested.
                if (editorViewSettings.ShowScrollPadding)
                {
                    cairoContext.Color = new Color(1, 0.5, 0.5);
                    cairoContext.Rectangle(scrollPaddingRegion);
                    cairoContext.Stroke();
                }
            }

            return(true);
        }
        /// <summary>
        /// Determines whether this layout line is the last line in the layout.
        /// </summary>
        /// <param name="layoutLine">The layout line.</param>
        /// <returns>
        ///     <c>true</c> if [is last line] [the specified layout line]; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsLastLineInLayout(this LayoutLine layoutLine)
        {
            Layout layout = layoutLine.Layout;

            return(layout.Lines[layout.LineCount - 1].StartIndex == layoutLine.StartIndex);
        }
Ejemplo n.º 23
0
        private void measureChildren()
        {
            if (!invalidSizes)
            {
                return;
            }
            invalidSizes = false;

            float width = 0, height = 0;

            // Prepare preferred lengths

            var innerSizeWidth = flowWidth - padding.Horizontal;

            lines = new List <LayoutLine>();
            {
                LayoutLine line = null;
                foreach (var child in Children)
                {
                    if (child.AnchorTarget != null)
                    {
                        continue;
                    }

                    var preferredSize = child.PreferredSize;
                    var minSize       = child.MinSize;
                    var maxSize       = child.MaxSize;
                    var itemWidth     = preferredSize.X;

                    if (line == null || (flowWidth != 0 && innerSizeWidth < line.GetTotalWidth(spacing) + itemWidth + (line.Items.Count > 0 ? lineSpacing : 0)))
                    {
                        lines.Add(line = new LayoutLine());
                    }

                    line.Items.Add(new LayoutItem()
                    {
                        Widget        = child,
                        PreferredSize = preferredSize,
                        MinSize       = minSize,
                        MaxSize       = maxSize,
                        Width         = itemWidth,
                        Scalable      = true,
                    });
                    line.Width += itemWidth;
                    line.Height = Math.Max(line.Height, preferredSize.Y);
                }
            }

            // Distribute the remaining/missing space

            var firstLine = true;

            foreach (var line in lines)
            {
                var scalableItems = line.Items.Count;
                while (scalableItems > 0 && Math.Abs(innerSizeWidth - line.Width) > 0.001f)
                {
                    var remainingWidth = innerSizeWidth - line.Width;
                    if (!fill && remainingWidth > 0)
                    {
                        break;
                    }

                    var adjustment = remainingWidth / scalableItems;
                    line.Width    = line.GetTotalSpacing(spacing);
                    scalableItems = 0;

                    foreach (var item in line.Items)
                    {
                        if (!item.Widget.CanGrow && adjustment > 0)
                        {
                            item.Scalable = false;
                        }

                        if (item.Scalable)
                        {
                            item.Width += adjustment;
                            if (item.Width < item.MinSize.Y)
                            {
                                item.Width    = item.MinSize.Y;
                                item.Scalable = false;
                            }
                            else if (item.MaxSize.Y > 0 && item.Width >= item.MaxSize.Y)
                            {
                                item.Width    = item.MaxSize.Y;
                                item.Scalable = false;
                            }
                            else
                            {
                                scalableItems++;
                            }
                        }
                        line.Width += item.Width;
                    }
                }

                width     = Math.Max(width, line.Width);
                height   += firstLine ? line.Height : line.Height + lineSpacing;
                firstLine = false;
            }
            flowWidth     = Math.Max(flowWidth, width + padding.Horizontal);
            preferredSize = new Vector2(flowWidth, height + padding.Vertical);
        }
Ejemplo n.º 24
0
        private void PaintLine(LayoutLine line, Graphics g)
        {
            foreach (var span in line.Spans)
            {
                var text = span.Text;

                var font = GetFont(span.Style);
                var fg = GetForeground(span.Style);
                var bg = GetBackground(span.Style);
                g.FillRectangle(bg, span.Extent);
                g.DrawString(text, font, fg, span.Extent, stringFormat);
            }
        }
Ejemplo n.º 25
0
 private LayoutSpan FindSpan(Point ptMouse, LayoutLine line)
 {
     foreach (var span in line.Spans)
     {
         if (span.Extent.Contains(ptMouse))
             return span;
     }
     return null;
 }
Ejemplo n.º 26
0
        private void GenerateFrets()
        {
            foreach (var fretLine in Layout.VisualElements.OfType <FretLine>())
            {
                if (Options.ExtendFretSlots && !fretLine.IsNut)
                {
                    var extendedFretLine = fretLine.GetExtendedFretLine(Options.Frets.ExtensionAmount);
                    if (extendedFretLine is LayoutLine line)
                    {
                        line.Tag = fretLine;
                        AddLayoutLine(line, VisualElementType.Fret, Options.Frets);
                        continue;
                    }
                    else if (extendedFretLine is LayoutPolyLine polyline)
                    {
                        polyline.Tag = fretLine;
                        if (polyline.Spline != null)
                        {
                            AddLayoutSpline(polyline, VisualElementType.Fret, Options.Frets);
                        }
                        else
                        {
                            AddLayoutPolyLine(polyline, VisualElementType.Fret, Options.Frets);
                        }
                        continue;
                    }
                }

                if (fretLine.IsStraight)
                {
                    var layoutLine = new LayoutLine(fretLine.Points.First(), fretLine.Points.Last());
                    layoutLine.Tag = fretLine;
                    AddLayoutLine(layoutLine, VisualElementType.Fret, Options.Frets);
                }
                else
                {
                    fretLine.RebuildSpline();

                    if (fretLine.Spline != null)
                    {
                        AddLayoutSpline(fretLine, VisualElementType.Fret, Options.Frets);
                    }
                    else
                    {
                        AddLayoutPolyLine(fretLine, VisualElementType.Fret, Options.Frets);
                    }
                }
            }

            if (Options.ExportBridgeLine)
            {
                var bridgeLine = Layout.GetElement <LayoutPolyLine>(x => x.ElementType == VisualElementType.BridgeLine);
                if (bridgeLine != null)
                {
                    var tmpConfig = new LineExportConfig()
                    {
                        Color         = System.Drawing.Color.Black,
                        LineThickness = 1d,
                        LineUnit      = LineUnit.Points
                    };
                    AddLayoutPolyLine(bridgeLine, VisualElementType.BridgeLine, tmpConfig);
                }
            }
        }
Ejemplo n.º 27
0
        private void GenerateLayoutLines()
        {
            if (Options.ExportCenterLine)
            {
                bool centerExist = false;
                var  centerLine  = Layout.VisualElements.OfType <LayoutLine>().First(x => x.ElementType == VisualElementType.CenterLine);

                if (Options.ExportMidlines && Layout.NumberOfStrings % 2 == 0)//even number of strings
                {
                    var stringCenter = Layout.GetStringsCenter(Layout.Strings[(Layout.NumberOfStrings / 2) - 1], Layout.Strings[Layout.NumberOfStrings / 2]);
                    if (stringCenter.Equation.IsVertical && stringCenter.Equation.X == 0)
                    {
                        centerExist = true;
                    }
                }
                else if (Options.ExportStrings && Layout.NumberOfStrings % 2 == 1)//odd number of strings
                {
                    var middleString = Layout.Strings[(Layout.NumberOfStrings - 1) / 2];
                    if (middleString.LayoutLine.Equation.IsVertical && middleString.LayoutLine.Equation.X == 0)
                    {
                        centerExist = true;
                    }
                }

                if (!centerExist)
                {
                    AddLayoutLine(centerLine, VisualElementType.CenterLine, Options.CenterLine);
                }
            }

            if (Options.ExportMidlines)
            {
                foreach (var stringCenter in Layout.GetElements <StringCenter>())
                {
                    AddLayoutLine(stringCenter, VisualElementType.StringMidline, Options.Midlines);
                }
            }

            if (!Options.ExportStrings && Options.ExportFingerboardMargins)//export first & last string to show fingerboard margin
            {
                var margins = Layout.GetElements <LayoutLine>(x => x.ElementType == VisualElementType.FingerboardMargin);

                if (margins.Any())
                {
                    foreach (var marginLine in margins)
                    {
                        AddLayoutLine(marginLine, VisualElementType.FingerboardMargin, Options.FingerboardMargins);
                    }
                }
                //else
                //{
                //    var firstString = Layout.FirstString.LayoutLine;
                //    var lastString = Layout.LastString.LayoutLine;
                //    var trebleEdge = Layout.GetStringBoundaryLine(Layout.FirstString, FingerboardSide.Treble);
                //    var bassEdge = Layout.GetStringBoundaryLine(Layout.LastString, FingerboardSide.Bass);

                //    var trebleMargin = new LayoutLine(firstString.P1, firstString.SnapToLine(trebleEdge.P2, LineSnapDirection.Horizontal));
                //    AddLayoutLine(trebleMargin, VisualElementType.FingerboardMargin, Options.FingerboardMargins);

                //    if (firstString != lastString)
                //    {
                //        var bassMargin = new LayoutLine(lastString.P1, lastString.SnapToLine(bassEdge.P2, LineSnapDirection.Horizontal));
                //        AddLayoutLine(bassMargin, VisualElementType.FingerboardMargin, Options.FingerboardMargins);
                //    }
                //}
            }

            if (Options.ExportFingerboardEdges && Options.FingerboardEdges.ContinueLines)
            {
                var endPoints = new List <PointM>();

                foreach (var guideLine in Layout.GetElements <LayoutLine>(l =>
                                                                          l.ElementType == VisualElementType.FingerboardContinuation))
                {
                    endPoints.Add(guideLine.P2);
                    AddLayoutLine(guideLine, VisualElementType.FingerboardContinuation, Options.GuideLines);
                }

                var pt1        = endPoints.OrderBy(pt => pt.X).First();
                var pt2        = endPoints.OrderByDescending(pt => pt.X).First();
                var bridgeLine = new LayoutLine(pt1, pt2);
                AddLayoutLine(bridgeLine, VisualElementType.FingerboardContinuation, Options.GuideLines);
            }
        }
Ejemplo n.º 28
0
        public static void Up(EditorViewController controller)
        {
            // Extract a number of useful variable for this method.
            IDisplayContext    displayContext = controller.DisplayContext;
            TextPosition       position       = displayContext.Caret.Position;
            EditorViewRenderer buffer         = displayContext.Renderer;

            // Figure out the layout and wrapped line we are currently on.
            Layout     layout;
            int        wrappedLineIndex;
            LayoutLine wrappedLine = position.GetWrappedLine(
                displayContext, out layout, out wrappedLineIndex);

            // Figure out the X coordinate of the line. If there is an action context,
            // use that. Otherwise, calculate it from the character index of the position.
            int lineX = GetLineX(controller, wrappedLine, position);

            // Figure out which wrapped line we'll be moving the caret to.
            LinePosition linePosition = position.LinePosition;
            int          lineIndex    = linePosition.GetLineIndex(buffer.LineBuffer);

            if (wrappedLineIndex == 0)
            {
                // If we are the last line in the buffer, just do nothing.
                if (linePosition == 0)
                {
                    return;
                }

                // Move to the next line.
                lineIndex--;
                layout           = buffer.GetLineLayout(lineIndex, LineContexts.None);
                wrappedLineIndex = layout.LineCount - 1;
                wrappedLine      = layout.Lines[wrappedLineIndex];
            }
            else
            {
                // Just move down in the layout.
                wrappedLineIndex--;
                wrappedLine = layout.Lines[wrappedLineIndex];
            }

            // Adjust the X coordinate for the current line.
            lineX -= GetLeftStylePaddingPango(controller, lineIndex);

            // The wrapped line has the current wrapped line, so use the lineX
            // to figure out which character to use.
            int trailing;
            int unicodeIndex;

            wrappedLine.XToIndex(lineX, out unicodeIndex, out trailing);

            // Calculate the character position, but we have to map UTF-8
            // characters because Pango uses that instead of C# strings.
            string lineText = controller.DisplayContext.LineBuffer.GetLineText(lineIndex);

            unicodeIndex = NormalizeEmptyStrings(lineText, unicodeIndex);
            int characterIndex = PangoUtility.TranslateStringToPangoIndex(
                lineText, unicodeIndex);

            if (lineText.Length > 0 &&
                trailing > 0)
            {
                characterIndex++;
            }

            // Draw the new location of the caret.
            var caretPosition = new TextPosition(lineIndex, characterIndex);

            displayContext.ScrollToCaret(caretPosition);
        }
Ejemplo n.º 29
0
 protected virtual void AddLayoutLine(LayoutLine line, VisualElementType elementType, LineExportConfig lineConfig)
 {
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Computes the layout of all visibile text spans and stores them the 
 /// member variable 'visibleLines'.
 /// </summary>
 /// <param name="g"></param>
 protected void ComputeLayout(Graphics g)
 {
     float cyLine = GetLineHeight();
     this.visibleLines = new SortedList<float, LayoutLine>();
     SizeF szClient = new SizeF(ClientSize);
     var rcLine = new RectangleF(0, 0, szClient.Width, cyLine);
     
     // Get the lines.
     int cVisibleLines = (int) Math.Ceiling(szClient.Height / cyLine);
     var lines = model != null ? model.GetLineSpans(cVisibleLines) : new TextSpan[0][];
     int iLine = 0;
     while (rcLine.Top < szClient.Height && 
            iLine < lines.Length)
     {
         var line = lines[iLine];
         var ll = new LayoutLine { 
             Extent = rcLine,
             Spans = ComputeSpanLayouts(line, rcLine, g)
         };
         this.visibleLines.Add(rcLine.Top, ll);
         ++iLine;
         rcLine.Offset(0, cyLine);
     }
 }
Ejemplo n.º 31
0
 public void LayoutText(PathF path, string text, ITextAttributes textAttributes, LayoutLine callback)
 {
     // Do nothing
 }
Ejemplo n.º 32
0
        private void LayoutStrings(Measure[] nutStringPos, Measure[] bridgeStringPos)
        {
            var stringLines = VisualElements.OfType <StringLine>();

            if (NumberOfStrings == 1)
            {
                ConstructString(Strings[0], nutStringPos[0], bridgeStringPos[0]);
            }
            else if (ScaleLengthMode != ScaleLengthType.Multiple)
            {
                var trebleStr = ConstructString(Strings[0], nutStringPos[0], bridgeStringPos[0]);
                var bassStr   = ConstructString(Strings[NumberOfStrings - 1], nutStringPos[NumberOfStrings - 1], bridgeStringPos[NumberOfStrings - 1]);

                var maxHeight = Measure.Max(trebleStr.Bounds.Height, bassStr.Bounds.Height);
                AdjustStringVerticalPosition(trebleStr, maxHeight);
                AdjustStringVerticalPosition(bassStr, maxHeight);

                var nutLine     = Line.FromPoints(trebleStr.P1.ToVector(), bassStr.P1.ToVector());
                var bridgeLine  = Line.FromPoints(trebleStr.P2.ToVector(), bassStr.P2.ToVector());
                var twelfthFret = new LayoutLine(PointM.Average(trebleStr.P1, trebleStr.P2), PointM.Average(bassStr.P1, bassStr.P2));

                //create the remaining strings by distributing them equally between the outer strings
                for (int i = 1; i < NumberOfStrings - 1; i++)
                {
                    var nutPos        = nutLine.GetPointForX(nutStringPos[i].NormalizedValue);
                    var bridgePos     = bridgeLine.GetPointForX(bridgeStringPos[i].NormalizedValue);
                    var createdString = AddVisualElement(new StringLine(Strings[i],
                                                                        PointM.FromVector(nutPos, nutStringPos[i].Unit),
                                                                        PointM.FromVector(bridgePos, bridgeStringPos[i].Unit)));

                    //strings distributed equally between the outer strings (which are tapered/angled) do not have their centers aligned
                    //so we correct the string length (at bridge) so that its center is aligned with the twelfth fret

                    var middle         = createdString.GetIntersection(twelfthFret);
                    var distFromNut    = PointM.Distance(createdString.P1, middle);
                    var distFromBridge = PointM.Distance(createdString.P2, middle);

                    var stringCenterOffset = Measure.Abs(distFromNut - distFromBridge);

                    if (!CompensateFretPositions && stringCenterOffset > Measure.Mm(0.05))
                    {
                        //adjust the end of the string so that it's center is above the 12th fret
                        createdString.P2 = createdString.P1 + (createdString.Direction * distFromNut * 2);
                    }

                    Strings[i].RecalculateLengths();//store the physical length of the string
                }
            }
            else
            {
                for (int i = 0; i < NumberOfStrings; i++)
                {
                    ConstructString(Strings[i], nutStringPos[i], bridgeStringPos[i]);
                }

                //*** Adjust strings position for multiscale
                var maxPerpHeight = Measure.FromNormalizedValue(stringLines.Max(l => l.Bounds.Height.NormalizedValue), UnitOfMeasure.Mm);
                foreach (var strLine in stringLines)
                {
                    AdjustStringVerticalPosition(strLine, maxPerpHeight);
                }
            }

            //calculate starting fret position if different from 0 (nut)
            foreach (var str in Strings)
            {
                if (str.StartingFret != 0)
                {
                    var startingFretPosRatio = GetEqualTemperedFretPosition(str.StartingFret);
                    var stringVector         = str.PlaceFretsRelativeToString ? str.LayoutLine.Direction * -1 : new Vector(0, 1);
                    var startingFretPos      = str.LayoutLine.P2 + (stringVector * str.CalculatedLength * startingFretPosRatio);

                    if (!str.PlaceFretsRelativeToString)
                    {
                        startingFretPos = str.LayoutLine.SnapToLine(startingFretPos, LineSnapDirection.Horizontal);
                    }

                    str.LayoutLine.P1 = startingFretPos;
                    str.RecalculateLengths();
                }
            }

            for (int i = 0; i < NumberOfStrings - 1; i++)
            {
                AddVisualElement(new StringCenter(Strings[i + 1].LayoutLine, Strings[i].LayoutLine));
            }
        }