diff --git a/src/display/draw_layer.js b/src/display/draw_layer.js index 4ef018a676dae2..3d4fa72d623582 100644 --- a/src/display/draw_layer.js +++ b/src/display/draw_layer.js @@ -135,9 +135,33 @@ class DrawLayer { path.setAttribute("d", outlines.toSVGPath()); path.setAttribute("vector-effect", "non-scaling-stroke"); + let maskId; + if (outlines.free) { + root.classList.add("free"); + const mask = DrawLayer._svgFactory.createElement("mask"); + defs.append(mask); + maskId = `mask_p${this.pageIndex}_${id}`; + mask.setAttribute("id", maskId); + mask.setAttribute("maskUnits", "objectBoundingBox"); + const rect = DrawLayer._svgFactory.createElement("rect"); + mask.append(rect); + rect.setAttribute("width", "1"); + rect.setAttribute("height", "1"); + rect.setAttribute("fill", "white"); + const use = DrawLayer._svgFactory.createElement("use"); + mask.append(use); + use.setAttribute("href", `#${pathId}`); + use.setAttribute("stroke", "none"); + use.setAttribute("fill", "black"); + use.setAttribute("fill-rule", "nonzero"); + } + const use1 = DrawLayer._svgFactory.createElement("use"); root.append(use1); use1.setAttribute("href", `#${pathId}`); + if (maskId) { + use1.setAttribute("mask", `url(#${maskId})`); + } const use2 = use1.cloneNode(); root.append(use2); use1.classList.add("mainOutline"); diff --git a/web/draw_layer_builder.css b/web/draw_layer_builder.css index b5bffec78c5739..1cfe86f91efb02 100644 --- a/web/draw_layer_builder.css +++ b/web/draw_layer_builder.css @@ -56,22 +56,52 @@ fill-rule: evenodd; fill: none; - &.hovered { - stroke: var(--hover-outline-color); - stroke-width: var(--outline-width); + &:not(.free) { + &.hovered:not(.selected) { + stroke: var(--hover-outline-color); + stroke-width: var(--outline-width); + } + + &.selected { + .mainOutline { + stroke: var(--outline-around-color); + stroke-width: calc( + var(--outline-width) + 2 * var(--outline-around-width) + ); + } + + .secondaryOutline { + stroke: var(--outline-color); + stroke-width: var(--outline-width); + } + } } - &.selected { - .mainOutline { - stroke: var(--outline-around-color); - stroke-width: calc( - var(--outline-width) + 2 * var(--outline-around-width) - ); + &.free { + /* + When drawing the outline we use a mask in order to remove the parts + that are inside the shape. Unfortunately, this removes the part of the + outline that is inside the shape. To "fix" this we draw the outline + we increase the width to have what we want to be visible outside the + shape. This is not a perfect solution, but it works well enough. + */ + &.hovered:not(.selected) { + stroke: var(--hover-outline-color); + stroke-width: calc(2 * var(--outline-width)); } - .secondaryOutline { - stroke: var(--outline-color); - stroke-width: var(--outline-width); + &.selected { + .mainOutline { + stroke: var(--outline-around-color); + stroke-width: calc( + 2 * (2 * var(--outline-width) + var(--outline-around-width)) + ); + } + + .secondaryOutline { + stroke: var(--outline-color); + stroke-width: calc(2 * var(--outline-width)); + } } } }