public void Draw(bool isDrawingSquareLayer) { if (isDrawingSquareLayer) { psDoc.ActiveLayer = squareLayer; } else { psDoc.ActiveLayer = blockLayer; } // This unwrapped javascript code runs faster due to // suspendHistory capability in the javascript library. //have one subpath for each color Dictionary <RGBi, List <Pt2i> > colorSubpaths = new Dictionary <RGBi, List <Pt2i> >(); //Take all dirtied squares and add to respective color subpath for (int y = 0; y < numSquaresY; ++y) { for (int x = 0; x < numSquaresX; ++x) { if (squares[x][y].isDirty) { int xBrushLoc = boardX + x * (squareSize + squareSpacing) + squareSize / 2; int yBrushLoc = boardY + y * (squareSize + squareSpacing) + squareSize / 2; RGBi colorKey = squares[x][y].color; if (colorKey == null) { colorKey = Square.emptyColor; } if (!colorSubpaths.ContainsKey(colorKey)) { colorSubpaths[colorKey] = new List <Pt2i>(); } colorSubpaths[colorKey].Add(new Pt2i(xBrushLoc, yBrushLoc)); squares[x][y].isDirty = false; } } } javascriptBuffer.Append("activeDocument.suspendHistory(\"DrawBoard\",\""); //Loop through all colors and stroke the subpaths int i = 0; foreach (KeyValuePair <RGBi, List <Pt2i> > colorSubpathEntry in colorSubpaths) { //if drawing square layer, then only draw when RGBi is empty color if (isDrawingSquareLayer && colorSubpathEntry.Key != Square.emptyColor) { continue; } RGBi strokeColor = colorSubpathEntry.Key; Pt2i[] colorSubpath = colorSubpathEntry.Value.ToArray(); if (colorSubpath.Length > 0) { for (int j = 0; j < colorSubpath.Length; ++j) { javascriptBuffer.Append("var lineArray" + i + "_" + j + " = new Array(); "); javascriptBuffer.Append("lineArray" + i + "_" + j + "[0] = new PathPointInfo; "); javascriptBuffer.Append("lineArray" + i + "_" + j + "[0].kind = PointKind.CORNERPOINT; "); javascriptBuffer.Append("lineArray" + i + "_" + j + "[0].anchor = Array(" + colorSubpath[j].x + ", " + colorSubpath[j].y + "); "); javascriptBuffer.Append("lineArray" + i + "_" + j + "[0].leftDirection = lineArray" + i + "_" + j + "[0].anchor; "); javascriptBuffer.Append("lineArray" + i + "_" + j + "[0].rightDirection = lineArray" + i + "_" + j + "[0].anchor; "); } javascriptBuffer.Append("var lineSubPathArray" + i + " = new Array(); "); for (int j = 0; j < colorSubpath.Length; ++j) { javascriptBuffer.Append("lineSubPathArray" + i + "[" + j + "] = new SubPathInfo(); "); javascriptBuffer.Append("lineSubPathArray" + i + "[" + j + "].operation = ShapeOperation.SHAPEXOR; "); javascriptBuffer.Append("lineSubPathArray" + i + "[" + j + "].closed = false; "); javascriptBuffer.Append("lineSubPathArray" + i + "[" + j + "].entireSubPath = lineArray" + i + "_" + j + "; "); } //create the path item javascriptBuffer.Append("var myPathItem" + i + " = activeDocument.pathItems.add(\\\"Color" + i + "\\\", lineSubPathArray" + i + "); "); //Stroke it so we can see something. // if drawing block layer and RGBi is empty color, then use eraser if (!isDrawingSquareLayer && colorSubpathEntry.Key == Square.emptyColor) { javascriptBuffer.Append("myPathItem" + i + ".strokePath(ToolType.ERASER); "); } // otherwise, use pencil else { //set foreground color javascriptBuffer.Append("app.foregroundColor.rgb.hexValue = \'" + strokeColor.ToHexString() + "\'; "); javascriptBuffer.Append("myPathItem" + i + ".strokePath(ToolType.PENCIL); "); } } ++i; } javascriptBuffer.Append("activeDocument.pathItems.removeAll(); "); javascriptBuffer.Append("\")"); try { psApp.DoJavaScript(javascriptBuffer.ToString()); } catch (Exception) { } javascriptBuffer.Clear(); }