From c885043317bbcea5a1b099508c93ba53604ef3c5 Mon Sep 17 00:00:00 2001 From: Omikhleia Date: Mon, 5 Feb 2024 22:56:16 +0100 Subject: [PATCH 1/2] fix: Stop defaulting to black in framebox package --- packages/framebox/graphics/renderer.lua | 52 ++++++++++++++++++------- packages/framebox/init.lua | 24 ++++++------ rough-lua/rough/generator.lua | 4 +- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/packages/framebox/graphics/renderer.lua b/packages/framebox/graphics/renderer.lua index 2f14186..32bd79a 100644 --- a/packages/framebox/graphics/renderer.lua +++ b/packages/framebox/graphics/renderer.lua @@ -28,10 +28,13 @@ end --- Builds a PDF graphics color (stroke or fill) from a SILE parsed color. -- --- @tparam table color SILE color object --- @tparam boolean stroke Stroke or fill --- @treturn string PDF graphics color +-- @tparam table|nil color SILE color object +-- @tparam boolean stroke Stroke or fill +-- @treturn string PDF graphics color local function makeColorHelper (color, stroke) + if not color then + return "" -- let current color be used + end local colspec local colop if color.r then -- RGB @@ -81,25 +84,43 @@ end local DefaultPainter = pl.class() +DefaultPainter.defaultOptions = { + strokeWidth = 1, +} + +function DefaultPainter:_init (options) + if options then + self.defaultOptions = self:_o(options) + end +end + +function DefaultPainter:_o (options) + return options and pl.tablex.union(self.defaultOptions, options) or self.defaultOptions +end + -- Line from (x1, y1) to (x2, y2). -function DefaultPainter.line (_, x1, y1, x2, y2, options) +function DefaultPainter:line (x1, y1, x2, y2, options) + local o = self:_o(options) return { path = table.concat({ _r(x1), _r(y1), "m", _r(x2 - x1), _r(y2 - y1), "l" }, " "), - options = options, + options = o, } end --- Path for a rectangle with upper left (x, y), with given width and height. -function DefaultPainter.rectangle (_, x, y , w , h, options) +function DefaultPainter:rectangle (x, y , w , h, options) + local o = self:_o(options) return { path = table.concat({ _r(x), _r(y), _r(w), _r(h), "re" }, " "), - options = options, + options = o, } end --- Path for a rounded rectangle with upper left (x, y), with given width, -- height and border radius. -function DefaultPainter.roundedRectangle (_, x, y , w , h, rx, ry, options) +function DefaultPainter:roundedRectangle (x, y , w , h, rx, ry, options) + local o = self:_o(options) + local arc = 4 / 3 * (1.4142135623730951 - 1) -- starting point local x0 = x + rx @@ -116,7 +137,7 @@ function DefaultPainter.roundedRectangle (_, x, y , w , h, rx, ry, options) } return { path = makePathHelper(x0, y, segments), - options = options, + options = o, } end @@ -186,7 +207,9 @@ end -- Algorithm derived from https://gist.github.com/alexhornbake/6005176 (which used -- quadratic Bezier curves, but it doesn't really matter much here). -- -function DefaultPainter.curlyBrace (_, x1, y1 , x2 , y2, width, thickness, curvyness, options) +function DefaultPainter:curlyBrace (x1, y1 , x2 , y2, width, thickness, curvyness, options) + local o = self:_o(options) + -- Calculate unit vector local dx = x1 - x2 local dy = y1 - y2 @@ -244,7 +267,7 @@ function DefaultPainter.curlyBrace (_, x1, y1 , x2 , y2, width, thickness, curvy -- Round line caps and line joins 1, "J", 1, "j", }, " "), - options = options + options = o } end @@ -264,8 +287,8 @@ function DefaultPainter.draw (_, drawable, clippable) local o = drawable.options local path - if o.strokeWidth == 0 or not o.stroke then - if o.fill then + if o.strokeWidth == 0 or o.stroke == 'none' then + if o.fill ~= 'none' then -- Fill only path = table.concat({ drawable.path, @@ -275,7 +298,7 @@ function DefaultPainter.draw (_, drawable, clippable) else path = "" end - elseif o.fill then + elseif o.fill ~= 'none' then -- Stroke and fill path = table.concat({ drawable.path, @@ -368,7 +391,6 @@ function RoughPainter:draw (drawable) "S" }, " ") elseif drawing.type == "fillPath" then - print("fillPath") path = table.concat({ self:opsToPath(drawing, precision), makeColorHelper(o.fill, false), diff --git a/packages/framebox/init.lua b/packages/framebox/init.lua index aab9936..d40d130 100644 --- a/packages/framebox/init.lua +++ b/packages/framebox/init.lua @@ -119,12 +119,12 @@ function package:registerCommands () local borderwidth = SU.cast("measurement", options.borderwidth or SILE.settings:get("framebox.borderwidth")):tonumber() local bordercolor if borderwidth ~= 0 then - bordercolor = SILE.color(options.bordercolor or "black") + bordercolor = options.bordercolor and SILE.color(options.bordercolor) end - local fillcolor = options.fillcolor and SILE.color(options.fillcolor) + local fillcolor = options.fillcolor and SILE.color(options.fillcolor) or 'none' local shadow = SU.boolean(options.shadow, false) local shadowsize = shadow and SU.cast("measurement", options.shadowsize or SILE.settings:get("framebox.shadowsize")):tonumber() or 0 - local shadowcolor = shadow and SILE.color(options.shadowcolor or "black") + local shadowcolor = shadow and options.shadowcolor and SILE.color(options.shadowcolor) local hbox, hlist = SILE.typesetter:makeHbox(content) hbox = adjustPaddingHbox(hbox, padding, padding + shadowsize, padding, padding + shadowsize) @@ -134,7 +134,8 @@ function package:registerCommands () local shadowpath, path if shadowsize ~= 0 then shadowpath = painter:rectangleShadow(0, d, w , h + d, shadowsize, { - fill = shadowcolor + fill = shadowcolor, + stroke = 'none' }) end path = painter:rectangle(0, d , w , h + d, { @@ -149,12 +150,12 @@ function package:registerCommands () local borderwidth = SU.cast("measurement", options.borderwidth or SILE.settings:get("framebox.borderwidth")):tonumber() local bordercolor if borderwidth ~= 0 then - bordercolor = SILE.color(options.bordercolor or "black") + bordercolor = options.bordercolor and SILE.color(options.bordercolor) end - local fillcolor = options.fillcolor and SILE.color(options.fillcolor) + local fillcolor = options.fillcolor and SILE.color(options.fillcolor) or 'none' local shadow = SU.boolean(options.shadow, false) local shadowsize = shadow and SU.cast("measurement", options.shadowsize or SILE.settings:get("framebox.shadowsize")):tonumber() or 0 - local shadowcolor = shadow and SILE.color(options.shadowcolor or "black") + local shadowcolor = shadow and options.shadowcolor and SILE.color(options.shadowcolor) local cornersize = SU.cast("measurement", options.cornersize or SILE.settings:get("framebox.cornersize")):tonumber() @@ -170,7 +171,8 @@ function package:registerCommands () local shadowpath, path if shadowsize ~= 0 then shadowpath = painter:roundedRectangleShadow(0, d , w , H, cornersize, cornersize, shadowsize, { - fill = shadowcolor + fill = shadowcolor, + stroke = 'none' }) end path = painter:roundedRectangle(0, d , w , H, cornersize, cornersize, { @@ -190,7 +192,7 @@ function package:registerCommands () -- (for hachures etc.) borderwidth = SILE.settings:get("framebox.borderwidth"):tonumber() end - local bordercolor = SILE.color(options.bordercolor or "black") + local bordercolor = options.bordercolor and SILE.color(options.bordercolor) local fillcolor = options.fillcolor and SILE.color(options.fillcolor) local enlarge = SU.boolean(options.enlarge, false) @@ -227,7 +229,7 @@ function package:registerCommands () self:registerCommand("bracebox", function(options, content) local padding = SU.cast("measurement", options.padding or SILE.measurement("0.25em")):tonumber() local strokewidth = SU.cast("measurement", options.strokewidth or SILE.measurement("0.033em")):tonumber() - local bracecolor = SILE.color(options.bracecolor or "black") + local bracecolor = options.bracecolor and SILE.color(options.bracecolor) local bracewidth = SU.cast("measurement", options.bracewidth or SILE.measurement("0.25em")):tonumber() local bracethickness = SU.cast("measurement", options.bracethickness or SILE.measurement("0.05em")):tonumber() local curvyness = SU.cast("number", options.curvyness or 0.6) @@ -380,7 +382,7 @@ As for fine-tuning options, \autodoc:parameter{padding} controls the space betwe \autodoc:parameter{bracewidth} defines the width of the whole brace (defaults to 0.25em), \autodoc:parameter{strokewidth} (defaults to 0.033em) and \autodoc:parameter{bracethickness} (0.05em) define the drawing characteristics of the brace. -Its color, black by default, can be changed with \autodoc:parameter{bracecolor}. +Its color can be changed with \autodoc:parameter{bracecolor}. Finally, \autodoc:parameter{curvyness} (defaults to 0.6) is a number between 0.5 and 1, defining how curvy is the brace: 0.5 is the “normal” value (quite straight) and higher values giving a more “expressive” brace (anything above 0.725 is probably quite useless). As can be seen with the default values, diff --git a/rough-lua/rough/generator.lua b/rough-lua/rough/generator.lua index 4873d94..f256693 100644 --- a/rough-lua/rough/generator.lua +++ b/rough-lua/rough/generator.lua @@ -28,7 +28,9 @@ local RoughGenerator = pl.class({ maxRandomnessOffset = 2, roughness = 1, bowing = 1, - stroke = { l = 0 }, -- PORTING NOTE: COMPAT WITH SILE PARSED COLORS + stroke = nil, -- PORTING NOTE: Different from the original Javacript + -- implementation: We don't want to default to black, + -- but let the current color apply. strokeWidth = 1, curveTightness = 0, curveFitting = 0.95, From cf31e54471061ce272438279520d531375b55d75 Mon Sep 17 00:00:00 2001 From: Omikhleia Date: Mon, 5 Feb 2024 23:03:51 +0100 Subject: [PATCH 2/2] docs: Do not document the 'dots' pattern fill for rough boxes It might have a bug (though I don't see it when printing the graphics path out), or just be too demanding: from time to time it crashes my PDF viewer. --- packages/framebox/init.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/framebox/init.lua b/packages/framebox/init.lua index d40d130..c3a5725 100644 --- a/packages/framebox/init.lua +++ b/packages/framebox/init.lua @@ -352,7 +352,7 @@ For instance, here is a single-stroked \roughbox[bordercolor=#59b24c, singlestro and a cross-hatched \roughbox[border=false, fillcolor=#ecebbd, fillstyle=cross-hatch]{rough box.} The last example also shows the \autodoc:parameter{fillstyle} option (defaults to “hachure”). -It can also be set to “solid”, “zigzag”, “cross-hatch”, “dashed”, “zigzag-line” or “dots”. +It can also be set to “solid”, “zigzag”, “cross-hatch”, “dashed” or “zigzag-line”. \smallskip \roughbox[bordercolor=150, fillcolor=#bcc6d7, singlestroke=true]{Hachure,}\kern[width=0.8em] @@ -360,8 +360,7 @@ It can also be set to “solid”, “zigzag”, “cross-hatch”, “dashed” \roughbox[bordercolor=150, fillcolor=#bcc6d7, singlestroke=true, fillstyle=zigzag]{zigzag,}\kern[width=0.8em] \roughbox[bordercolor=150, fillcolor=#bcc6d7, singlestroke=true, fillstyle=cross-hatch]{cross-hatch,}\kern[width=0.8em] \roughbox[bordercolor=150, fillcolor=#bcc6d7, singlestroke=true, fillstyle=dashed]{dashed,}\kern[width=0.8em] -\roughbox[bordercolor=150, fillcolor=#bcc6d7, singlestroke=true, fillstyle=zigzag-line]{zigag-line.}\kern[width=0.8em] -\roughbox[bordercolor=150, fillcolor=#bcc6d7, singlestroke=true, fillstyle=dots]{and dots.} +\roughbox[bordercolor=150, fillcolor=#bcc6d7, singlestroke=true, fillstyle=zigzag-line]{zigag-line.} \smallskip The border width is actually the stroke width, also used for the hachures, etc.