Example #1
0
 private Dictionary <int, Color> createColorMap() => new Dictionary <int, Color>
 {
     [000] = Color.Black,                                    // unoccupied
     [001] = DmcColorProcessor.GetByDmcNumber("820").Color,  // Very Dark Royal Blue
     [010] = DmcColorProcessor.GetByDmcNumber("907").Color,  // Light Parrot Green
     [011] = DmcColorProcessor.GetByDmcNumber("3846").Color, // Light Bright Turquoise
     [100] = DmcColorProcessor.GetByDmcNumber("606").Color,  // Bright Orange-Red
     [101] = DmcColorProcessor.GetByDmcNumber("956").Color,  // Geranium pink
     [110] = DmcColorProcessor.GetByDmcNumber("973").Color,  // Bright Canary yellow
     [111] = Color.White,
 };
Example #2
0
 /// <summary>
 /// Replace per scanned model stored in Sprite, Pixels, json, et al.
 /// </summary>
 /// <param name="oldColor">Hex or DMC code</param>
 /// <param name="newColor">Hex or DMC code</param>
 public void TargetedReplace(string oldColor, string newColor)
 => TargetedReplace(DmcColorProcessor.SmartColorFinder(oldColor), DmcColorProcessor.SmartColorFinder(newColor));
Example #3
0
        public static void NaiveReplace(string file, string oldColorHex, string newColorHex, bool createBackupFile = false)
        {
            var processor = new DmcColorProcessor();

            NaiveReplace(file, processor.SmartColorFinder(oldColorHex), processor.SmartColorFinder(newColorHex), createBackupFile);
        }
Example #4
0
 /// <summary>
 /// Iterate through every pixel. If color matches: replace it
 /// </summary>
 public void NaiveReplace(string oldColorHex, string newColorHex)
 => NaiveReplace(DmcColorProcessor.SmartColorFinder(oldColorHex), DmcColorProcessor.SmartColorFinder(newColorHex));
Example #5
0
        /// <summary>Convert input Excel layout to printable cross stitch patterns</summary>
        public void ConvertToPattern()
        {
            var grids = getGrids().ToList();

            if (grids.Count < 1)
            {
                return;
            }

            var colorsAndGlyphs = getSortedColorsAndGlyphs();

            // aka offset within the original picture from 0,0 (aka 1,1)
            var location = Pattern.Sprite.Location;

            var size = Pattern.Sprite.Size;
            var rows = size.Height;
            var cols = size.Width;

            // top and left gutters for row/col numbers
            var numberRowsTop  = 0;
            var numberColsLeft = 0;

            if (PrintLineNumbers)
            {
                numberRowsTop  = (int)Math.Log10(cols) + 1;
                numberColsLeft = (int)Math.Log10(rows) + 1;
            }

            // bottom and right row for center triangles
            var bottomArrowCellSize = 0;
            var rightArrowCellSize  = 0;

            if (PrintArrowsAtMidpoints)
            {
                bottomArrowCellSize = 1;
                rightArrowCellSize  = 1;
            }

            // right buffer between pattern and legend
            var bufferBeforeLegend = 1;

            // legend:
            //   2 columns for colors/glyphs
            //   1 column DMC color # and name
            var legendWidth = 3;

            var gridHeight         = numberRowsTop + size.Height + bottomArrowCellSize;
            var bufferBetweenGrids = 1;

            // grid offset
            // 1st grid with 0 offset starts at top left 1,1
            // 14px tall picture + 2 top + 1 bottom for center-arrow + 1 row buffer = 18 gridOffset
            // - 1st grid will begin at 1,1 + (18*0) = 1, 1 aka  A1
            // - 2nd grid will begin at 1,1 + (18*1) = 1,19 aka A19
            // - 3rd grid will begin at 1,1 + (18*2) = 1,37 aka A37
            var gridOffset = gridHeight + bufferBetweenGrids;

            // total cell range needed for all 3 grids
            var totalHeight = (grids.Count * gridHeight) + ((grids.Count - 1) * bufferBetweenGrids);
            var totalWidth  = numberColsLeft + size.Width + rightArrowCellSize + bufferBeforeLegend + legendWidth;

            // these columns are same for all grids
            var contentColOffset = numberColsLeft;
            var rightArrowBuffer = contentColOffset + cols + rightArrowCellSize;

            using var writer = new ExcelWriter(OutputFile);
            // within total cell range:
            // - adjust col width and row height
            // - global font default: calibri. size 8. align middle and center
            {
                var totalRange = writer.GetRange(1, 1, totalHeight, totalWidth);

                //for (var r = 1; r <= totalHeight; r++)
                //	writer.Worksheet.Rows[r].RowHeight = 9.75; // =13px
                //for (var c = 1; c <= totalWidth; c++)
                //	writer.Worksheet.Columns[c].ColumnWidth = 1.14; // =13px
                totalRange.RowHeight   = 9.75;               // =13px
                totalRange.ColumnWidth = 1.14;               // =13px

                // DO NOT use these. they also alter the app's font: writer.App.StandardFont , writer.App.StandardFontSize

                // note, do NOT use totalRange.Style. This gets the style in that range and changes it. This change propogates to all other elements using that style which may include the client app itself.
                totalRange.Font.Name           = "Calibri";
                totalRange.Font.Size           = 8;
                totalRange.HorizontalAlignment = XlHAlign.xlHAlignCenter;
                totalRange.VerticalAlignment   = XlVAlign.xlVAlignCenter;
            }

            for (var g = 0; g < grids.Count; g++)
            {
                //// to put on different tabs instead of same:
                //// - uncomment this
                //// - apply above global stuff to all tabs
                //// - remove vertical offsets
                //// other possible configuration: print each to its own file
                //switch (g)
                //{
                //	case 0:
                //		// we already start with a worksheet. don't need to add one for 1st grid
                //		writer.Worksheet.Name = "Colors";
                //		break;
                //	case 1:
                //		writer.AddWorksheet();
                //		writer.Worksheet.Name = "Glyphs";
                //		break;
                //	case 2:
                //	default:
                //		writer.AddWorksheet();
                //		writer.Worksheet.Name = "Colors and glyphs";
                //		break;
                //}

                // eg: 18 gridOffset
                // - 1st grid will begin at 1,1 + (gridOffset*0) = 1, 1 : aka  A1
                // - 2nd grid will begin at 1,1 + (gridOffset*1) = 1,19 : aka A19
                // - 3rd grid will begin at 1,1 + (gridOffset*2) = 1,37 : aka A37

                var grid = grids[g];

                var offset           = gridOffset * g;
                var contentRowOffset = offset + numberRowsTop;

                if (PrintLineNumbers)
                {
                    // top line numbers
                    for (var x = 0; x < numberRowsTop; x++)
                    {
                        for (var c = 1; c <= cols; c++)
                        {
                            writer.GetCell(
                                1 + x + offset,
                                c + numberColsLeft)
                            .Value = c.ToString().PadLeft(numberRowsTop)[x].ToString().Trim();
                        }
                    }

                    // left line numbers
                    for (var x = 1; x <= rows; x++)
                    {
                        for (var c = 0; c < numberColsLeft; c++)
                        {
                            writer.GetCell(
                                x + offset + numberRowsTop,
                                1 + c)
                            .Value = x.ToString().PadLeft(numberColsLeft)[c].ToString().Trim();
                        }
                    }
                }

                // pattern/content area:
                // - dotted grid 1x1
                // - thin solid line grid 5x5
                // - thick solid line grid 10x10
                // - thick exterior solid line border
                if (PrintGridLines)
                {
                    // 1x1
                    var contentRange = writer.GetRange(1 + contentRowOffset, 1 + contentColOffset, rows + contentRowOffset, cols + contentColOffset);
                    contentRange.DrawInternalBorders(2, XlLineStyle.xlDash);

                    // 5x5, 10x10
                    for (var r = 1; r <= rows; r++)
                    {
                        // run this before getting range. Range inerop is significantly more expensive
                        if (r % 5 != 0)
                        {
                            continue;
                        }

                        var rangeRow = contentRowOffset + r;
                        var rowRange = writer.GetRange(rangeRow, contentColOffset + 1, rangeRow, contentColOffset + size.Width);
                        rowRange.Borders[XlBordersIndex.xlEdgeBottom].DrawEdgeBorder(r % 10 == 0 ? 3 : 2, XlLineStyle.xlContinuous);
                    }
                    for (var c = 1; c <= cols; c++)
                    {
                        // run this before getting range. Range inerop is significantly more expensive
                        if (c % 5 != 0)
                        {
                            continue;
                        }

                        var rangeCol = contentColOffset + c;
                        var colRange = writer.GetRange(contentRowOffset + 1, rangeCol, contentRowOffset + size.Height, rangeCol);
                        colRange.Borders[XlBordersIndex.xlEdgeRight].DrawEdgeBorder(c % 10 == 0 ? 3 : 2, XlLineStyle.xlContinuous);
                    }

                    // outer borders
                    var patternRange = writer.GetRange(contentRowOffset + 1, contentColOffset + 1, contentRowOffset + size.Height, contentColOffset + size.Width);
                    patternRange.DrawAllEdgeBorders(3, XlLineStyle.xlContinuous);
                }

                if (PrintArrowsAtMidpoints)
                {
                    // right arrow. merge. Wingdings 3. left-facing arrow is 't'
                    var rightArrowRange = writer.GetRange(contentRowOffset + 1, rightArrowBuffer, contentRowOffset + size.Height, rightArrowBuffer);
                    rightArrowRange.Merge();
                    rightArrowRange.Value     = "t";
                    rightArrowRange.Font.Name = "Wingdings 3";

                    // bottom arrow. merge. Wingdings 3. top-facing arrow is 'p'
                    var rangeRow         = contentRowOffset + rows + bottomArrowCellSize;
                    var bottomArrowRange = writer.GetRange(rangeRow, contentColOffset + 1, rangeRow, contentColOffset + size.Width);
                    bottomArrowRange.Merge();
                    bottomArrowRange.Value     = "p";
                    bottomArrowRange.Font.Name = "Wingdings 3";
                }

                // legend
                // all grid:
                //   print legend. each color:
                //   col 2: color box with thin black border
                //   col 3: DMC color # and name. align bottom left
                // conditional grids:
                //   grid 1: no changes
                //   grid 2: col 1: glyphs
                //   grid 3: col 2: glyphs. this will combine the color box and glyphs
                if (PrintLegend)
                {
                    var legendColBuffer = rightArrowBuffer + bufferBeforeLegend;
                    var legendCol1      = legendColBuffer + 1;
                    var legendCol2      = legendColBuffer + 2;
                    var legendCol3      = legendColBuffer + 3;

                    // set all borders with 1 command per grid over entire range
                    var legendBorderedRange = writer.GetRange(contentRowOffset + 1, legendCol2, contentRowOffset + colorsAndGlyphs.Count, legendCol2);
                    legendBorderedRange.DrawInternalBorders(2, XlLineStyle.xlContinuous);

                    for (var cs = 0; cs < colorsAndGlyphs.Count; cs++)
                    {
                        var(color, glyph) = colorsAndGlyphs[cs];

                        var legendRowOffset = contentRowOffset + cs + 1;

                        var legend1cell = writer.GetCell(legendRowOffset, legendCol1);
                        var legend2cell = writer.GetCell(legendRowOffset, legendCol2);
                        var legend3cell = writer.GetCell(legendRowOffset, legendCol3);

                        // column 1
                        if (grid.LegendGlyphsColumn1)
                        {
                            legend1cell.WriteGlyph(glyph);
                        }

                        // column 2
                        legend2cell.Interior.Color = color.ToOle();
                        if (grid.LegendGlyphsColumn2)
                        {
                            legend2cell.WriteGlyph(glyph);
                            legend2cell.EnsureTextContrast(color);
                        }

                        // column 3
                        legend3cell.Value
                            = DmcColorProcessor.TryGetMatch(color, out var dmcColor)
                                                        ? $"{dmcColor.DmcNumber} - {dmcColor.Name}"
                                                        : $"Non-DMC: #{color.ToHex()}";
                        legend3cell.HorizontalAlignment = XlHAlign.xlHAlignLeft;
                        legend3cell.VerticalAlignment   = XlVAlign.xlVAlignBottom;
                    }
                }

                // content
                // grid 1 content: print pattern pixel colors
                // grid 2 content: print pattern pixel glyphs
                // grid 3 content: print pattern pixel colors and glyphs
                foreach (var p in Pattern.Sprite.Pixels.Where(p => !p.Color.IsTransparent()))
                {
                    var row    = p.RowNumber + contentRowOffset - location.Y + 1;
                    var column = p.ColumnNumber + contentColOffset - location.X + 1;
                    var cell   = writer.GetCell(row, column);

                    if (grid.PatternColors)
                    {
                        cell.Interior.Color = p.Color.ToOle();
                    }

                    if (grid.PatternGlyphs)
                    {
                        cell.WriteGlyph(colorsAndGlyphs.Single(cs => p.Color.IsEquivalent(cs.Color)).Glyph);
                    }

                    if (grid.PatternColors && grid.PatternGlyphs)
                    {
                        cell.EnsureTextContrast(p.Color);
                    }
                }
            }
        }