0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-10 17:18:21 -05:00

Merge pull request #1276 from penpot/bugfixes

Bugfixes
This commit is contained in:
Andrey Antukh 2021-10-13 13:40:07 +02:00 committed by GitHub
commit 925058467f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 217 additions and 151 deletions

View file

@ -3,10 +3,15 @@
## :rocket: Next
### :boom: Breaking changes
- Some stroke-caps can change behaviour
- Text display bug fix could potentialy make some texts jump a line
### :sparkles: New features
- Add boolean shapes: intersections, unions, difference and exclusions.
- Add advanced prototyping [#244](https://tree.taiga.io/project/penpot/us/244).
- Change order of the teams menu so it's in the joined time order
### :bug: Bugs fixed
@ -26,12 +31,15 @@
- Fix zoom context menu in viewer [Taiga #2041](https://tree.taiga.io/project/penpot/issue/2041)
- Fix stroke caps adjustments in relation with stroke size [Taiga #2123](https://tree.taiga.io/project/penpot/issue/2123)
- Fix problem duplicating paths [Taiga #2147](https://tree.taiga.io/project/penpot/issue/2147)
- Fix problem inheriting attributes from SVG root when importing [Taiga #2124](https://tree.taiga.io/project/penpot/issue/2124)
- Fix problem with lines and inside/outside stroke [Taiga #2146](https://tree.taiga.io/project/penpot/issue/2146)
- Add stroke width in selection calculation [Taiga #2146](https://tree.taiga.io/project/penpot/issue/2146)
- Fix shift+wheel to horizontal scrolling in MacOS [#1217](https://github.com/penpot/penpot/issues/1217)
- Fix path stroke is not working properly with high thickness [Taiga #2154](https://tree.taiga.io/project/penpot/issue/2154)
- Fix bug with transformation operations [Taiga #2155](https://tree.taiga.io/project/penpot/issue/2155)
- Fix bug in firefox when a text box is inside a mask [Taiga #2152](https://tree.taiga.io/project/penpot/issue/2152)
### :arrow_up: Deps updates
### :boom: Breaking changes
- Some stroke-caps can change behaviour
- Text display bug fix could potentialy make some texts jump a line
### :heart: Community contributions by (Thank you!)

View file

@ -58,7 +58,7 @@
join team as t on (t.id = tp.team_id)
where t.deleted_at is null
and tp.profile_id = ?
order by t.created_at asc")
order by tp.created_at asc")
(defn retrieve-teams
[conn profile-id]

View file

@ -160,6 +160,7 @@
;; PATHS
(d/export gsp/content->selrect)
(d/export gsp/transform-content)
(d/export gsp/open-path?)
;; Intersection
(d/export gin/overlaps?)

View file

@ -284,12 +284,19 @@
(defn overlaps?
"General case to check for overlaping between shapes and a rectangle"
[shape rect]
(let [stroke-width (/ (or (:stroke-width shape) 0) 2)
rect (-> rect
(update :x - stroke-width)
(update :y - stroke-width)
(update :width + (* 2 stroke-width))
(update :height + (* 2 stroke-width))
)]
(or (not shape)
(let [path? (= :path (:type shape))
circle? (= :circle (:type shape))]
(and (overlaps-rect-points? rect (:points shape))
(or (not path?) (overlaps-path? shape rect))
(or (not circle?) (overlaps-ellipse? shape rect))))))
(or (not circle?) (overlaps-ellipse? shape rect)))))))
(defn has-point-rect?
[rect point]

View file

@ -126,8 +126,8 @@
(let [tangent (curve-tangent curve t)]
(cond
(> (:y tangent) 0) 1
(< (:y tangent) 0) -1
(> (:y tangent) 0) -1
(< (:y tangent) 0) 1
:else 0)))
(defn curve-split
@ -822,30 +822,27 @@
(let [selrect (content->selrect content)
ray-line [point (gpt/point (inc (:x point)) (:y point))]
closed-subpaths
closed-content
(into []
(comp (filter sp/is-closed?)
(mapcat :data))
(->> content
(sp/close-subpaths)
(sp/get-subpaths)
(filterv sp/is-closed?))
(sp/get-subpaths)))
cast-ray
(fn [cmd]
(case (:command cmd)
:line-to (ray-line-intersect point (command->line cmd))
:curve-to (ray-curve-intersect ray-line (command->bezier cmd))
#_:else []))
#_:else []))]
is-point-in-subpath?
(fn [subpath]
(and (gpr/contains-point? (content->selrect (:data subpath)) point)
(->> (:data subpath)
(and (gpr/contains-point? selrect point)
(->> closed-content
(mapcat cast-ray)
(map second)
(reduce +)
(not= 0))))]
(and (gpr/contains-point? selrect point)
(some is-point-in-subpath? closed-subpaths))))
(not= 0)))))
(defn split-line-to
"Given a point and a line-to command will create a two new line-to commands
@ -948,3 +945,14 @@
(gsc/transform-points points-center transform-inverse)
(gpr/points->selrect))]
[points selrect]))
(defn open-path?
[shape]
(and (= :path (:type shape))
(not (->> shape
:content
(sp/close-subpaths)
(sp/get-subpaths)
(every? sp/is-closed?)))))

View file

@ -73,9 +73,15 @@
(fn [subpaths current]
(let [is-move? (= :move-to (:command current))
last-idx (dec (count subpaths))]
(if is-move?
(cond
is-move?
(conj subpaths (make-subpath current))
(update subpaths last-idx add-subpath-command current))))]
(>= last-idx 0)
(update subpaths last-idx add-subpath-command current)
:else
subpaths)))]
(->> content
(reduce reduce-subpath []))))

View file

@ -432,6 +432,7 @@
(ptk/reify ::duplicate-selected
ptk/WatchEvent
(watch [it state _]
(when (nil? (get-in state [:workspace-local :transform]))
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
@ -461,7 +462,7 @@
:undo-changes uchanges
:origin it})
(select-shapes selected)
(memorize-duplicated id-original id-duplicated))))))
(memorize-duplicated id-original id-duplicated)))))))
(defn change-hover-state
[id value]

View file

@ -178,7 +178,8 @@
:y (+ y offset-y)}
(gsh/setup-selrect)
(assoc :svg-attrs (-> (:attrs svg-data)
(dissoc :viewBox :xmlns))))))
(dissoc :viewBox :xmlns)
(d/without-keys usvg/inheritable-props))))))
(defn create-group [name frame-id svg-data {:keys [attrs]}]
(let [svg-transform (usvg/parse-transform (:transform attrs))
@ -387,7 +388,7 @@
(setup-stroke)))
children (cond->> (:content element-data)
(= tag :g)
(or (= tag :g) (= tag :svg))
(mapv #(usvg/inherit-attributes attrs %)))]
[shape children]))))
@ -487,11 +488,15 @@
;; Creates the root shape
changes (dwc/add-shape-changes page-id objects selected root-shape false)
root-attrs (-> (:attrs svg-data)
(usvg/format-styles))
;; Reduces the children to create the changes to add the children shapes
[_ [rchanges uchanges]]
(reduce (partial add-svg-child-changes page-id objects selected frame-id root-id svg-data)
[unames changes]
(d/enumerate (:content svg-data)))
(d/enumerate (->> (:content svg-data)
(mapv #(usvg/inherit-attributes root-attrs %)))))
reg-objects-action {:type :reg-objects
:page-id page-id

View file

@ -70,10 +70,7 @@
(defn- fix-init-point
"Fix the initial point so the resizes are accurate"
[initial handler shape]
(let [{:keys [x y width height]} (:selrect shape)
{:keys [rotation]} shape
rotation (or rotation 0)]
(if (= rotation 0)
(let [{:keys [x y width height]} (:selrect shape)]
(cond-> initial
(contains? #{:left :top-left :bottom-left} handler)
(assoc :x x)
@ -85,8 +82,7 @@
(assoc :y y)
(contains? #{:bottom :bottom-right :bottom-left} handler)
(assoc :y (+ y height)))
initial)))
(assoc :y (+ y height)))))
(defn finish-transform []
(ptk/reify ::finish-transform
@ -285,10 +281,19 @@
(letfn [(resize [shape initial layout [point lock? center? point-snap]]
(let [{:keys [width height]} (:selrect shape)
{:keys [rotation]} shape
shape-center (gsh/center-shape shape)
shape-transform (:transform shape (gmt/matrix))
shape-transform-inverse (:transform-inverse shape (gmt/matrix))
rotation (or rotation 0)
initial (gsh/transform-point-center initial shape-center shape-transform-inverse)
initial (fix-init-point initial handler shape)
point (gsh/transform-point-center (if (= rotation 0) point-snap point)
shape-center shape-transform-inverse)
shapev (-> (gpt/point width height))
scale-text (:scale-text layout)
@ -300,8 +305,7 @@
handler-mult (let [[x y] (handler-multipliers handler)] (gpt/point x y))
;; Difference between the origin point in the coordinate system of the rotation
deltav (-> (gpt/to-vec initial (if (= rotation 0) point-snap point))
(gpt/transform (gmt/rotate-matrix (- rotation)))
deltav (-> (gpt/to-vec initial point)
(gpt/multiply handler-mult))
;; Resize vector
@ -317,24 +321,23 @@
scalev)
;; Resize origin point given the selected handler
origin (handler-resize-origin (:selrect shape) handler)
handler-origin (handler-resize-origin (:selrect shape) handler)
shape-center (gsh/center-shape shape)
shape-transform (:transform shape (gmt/matrix))
shape-transform-inverse (:transform-inverse shape (gmt/matrix))
;; If we want resize from center, displace the shape
;; so it is still centered after resize.
displacement (when center?
displacement
(when center?
(-> shape-center
(gpt/subtract origin)
(gpt/subtract handler-origin)
(gpt/multiply scalev)
(gpt/add origin)
(gpt/add handler-origin)
(gpt/subtract shape-center)
(gpt/multiply (gpt/point -1 -1))
(gpt/transform shape-transform)))
origin (cond-> (gsh/transform-point-center origin shape-center shape-transform)
resize-origin
(cond-> (gsh/transform-point-center handler-origin shape-center shape-transform)
(some? displacement)
(gpt/add displacement))
@ -344,7 +347,7 @@
(rx/of (set-modifiers ids
{:displacement displacement
:resize-vector scalev
:resize-origin origin
:resize-origin resize-origin
:resize-transform shape-transform
:resize-scale-text scale-text
:resize-transform-inverse shape-transform-inverse}))))

View file

@ -25,22 +25,24 @@
[cuerdas.core :as str]
[rumext.alpha :as mf]))
(defn bounds
(defn calc-bounds
[object objects]
(if (= :group (:type object))
(let [children-bounds
(into []
(comp (map #(get objects %))
(map #(bounds % objects)))
(:shapes object))]
(gsh/join-rects children-bounds))
(let [padding (filters/calculate-padding object)]
(let [xf-get-bounds (comp (map #(get objects %)) (map #(calc-bounds % objects)))
padding (filters/calculate-padding object)
obj-bounds
(-> (filters/get-filters-bounds object)
(update :x - padding)
(update :y - padding)
(update :width + (* 2 padding))
(update :height + (* 2 padding))))))
(update :height + (* 2 padding)))]
(if (= :group (:type object))
(->> (:shapes object)
(into [obj-bounds] xf-get-bounds)
(gsh/join-rects))
obj-bounds)))
(mf/defc object-svg
{::mf/wrap [mf/memo]}
@ -64,7 +66,7 @@
objects (reduce updt-fn objects mod-ids)
object (get objects object-id)
{:keys [x y width height] :as bs} (bounds object objects)
{:keys [x y width height] :as bs} (calc-bounds object objects)
[_ _ width height :as coords] (->> [x y width height] (map #(* % zoom)))
vbox (str/join " " coords)

View file

@ -14,12 +14,14 @@
[rumext.alpha :as mf]))
(defn- stroke-type->dasharray
[style]
(case style
:mixed "5,5,1,5"
:dotted "5,5"
:dashed "10,10"
nil))
[width style]
(let [values (case style
:mixed [5 5 1 5]
:dotted [5 5]
:dashed [10 10]
nil)]
(->> values (map #(+ % width)) (str/join ","))))
(defn- truncate-side
[shape ra-attr rb-attr dimension-attr]
@ -102,10 +104,11 @@
(defn add-stroke [attrs shape render-id]
(let [stroke-style (:stroke-style shape :none)
stroke-color-gradient-id (str "stroke-color-gradient_" render-id)]
stroke-color-gradient-id (str "stroke-color-gradient_" render-id)
stroke-width (:stroke-width shape 1)]
(if (not= stroke-style :none)
(let [stroke-attrs
(cond-> {:strokeWidth (:stroke-width shape 1)}
(cond-> {:strokeWidth stroke-width}
(:stroke-color-gradient shape)
(assoc :stroke (str/format "url(#%s)" stroke-color-gradient-id))
@ -118,7 +121,7 @@
(assoc :strokeOpacity (:stroke-opacity shape nil))
(not= stroke-style :svg)
(assoc :strokeDasharray (stroke-type->dasharray stroke-style))
(assoc :strokeDasharray (stroke-type->dasharray stroke-width stroke-style))
;; For simple line caps we use svg stroke-line-cap attribute. This
;; only works if all caps are the same and we are not using the tricks

View file

@ -7,6 +7,7 @@
(ns app.main.ui.shapes.custom-stroke
(:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.main.ui.context :as muc]
[app.util.object :as obj]
[cuerdas.core :as str]
@ -145,6 +146,8 @@
(mf/defc stroke-defs
[{:keys [shape render-id]}]
(when (and (= (:type shape) :path)
(gsh/open-path? shape))
(cond
(and (= :inner (:stroke-alignment shape :center))
(> (:stroke-width shape 0) 0))
@ -160,7 +163,7 @@
(some? (:stroke-cap-end shape)))
(= (:stroke-alignment shape) :center))
[:& cap-markers {:shape shape
:render-id render-id}]))
:render-id render-id}])))
;; Outer alingmnent: display the shape in two layers. One
;; without stroke (only fill), and another one only with stroke
@ -253,15 +256,17 @@
stroke-position (:stroke-alignment shape :center)
has-stroke? (and (> stroke-width 0)
(not= stroke-style :none))
closed? (or (not= :path (:type shape))
(not (gsh/open-path? shape)))
inner? (= :inner stroke-position)
outer? (= :outer stroke-position)]
(cond
(and has-stroke? inner?)
(and has-stroke? inner? closed?)
[:& inner-stroke {:shape shape}
child]
(and has-stroke? outer?)
(and has-stroke? outer? closed?)
[:& outer-stroke {:shape shape}
child]

View file

@ -27,13 +27,23 @@
[(first childs) (rest childs)]
[nil childs])
;; We need to separate mask and clip into two because a bug in Firefox
;; breaks when the group has clip+mask+foreignObject
;; Clip and mask separated will work in every platform
; Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1734805
[clip-wrapper clip-props]
(if masked-group?
["g" (-> (obj/new)
(obj/set! "clipPath" (clip-url render-id mask)))]
[mf/Fragment nil])
[mask-wrapper mask-props]
(if masked-group?
["g" (-> (obj/new)
(obj/set! "clipPath" (clip-url render-id mask))
(obj/set! "mask" (mask-url render-id mask)))]
[mf/Fragment nil])]
[:> clip-wrapper clip-props
[:> mask-wrapper mask-props
(when masked-group?
[:> render-mask #js {:frame frame :mask mask}])
@ -41,7 +51,7 @@
(for [item childs]
[:& shape-wrapper {:frame frame
:shape item
:key (:id item)}])]))))
:key (:id item)}])]]))))

View file

@ -363,12 +363,14 @@
delta-y (-> (.-deltaY ^js event)
(* unit)
(/ zoom))
delta-x (-> (.-deltaX ^js event)
(* unit)
(/ zoom))]
(dom/prevent-default event)
(dom/stop-propagation event)
(if (kbd/shift? event)
(if (and (not (cfg/check-platform? :macos)) ;; macos sends delta-x automaticaly, don't need to do it
(kbd/shift? event))
(st/emit! (dw/update-viewport-position {:x #(+ % delta-y)}))
(st/emit! (dw/update-viewport-position {:x #(+ % delta-x)
:y #(+ % delta-y)})))))))))

View file

@ -229,7 +229,12 @@
current-transform (mf/deref refs/current-transform)
selrect (:selrect shape)
transform (geom/transform-matrix shape {:no-flip true})]
transform (geom/transform-matrix shape {:no-flip true})
rotation (-> (gpt/point 1 0)
(gpt/transform (:transform shape))
(gpt/angle)
(mod 360))]
(when (not (#{:move :rotate} current-transform))
[:g.controls {:pointer-events (if disable-handlers "none" "visible")}
@ -249,7 +254,7 @@
:on-rotate on-rotate
:on-resize (partial on-resize position)
:transform transform
:rotation (:rotation shape)
:rotation rotation
:color color
:overflow-text overflow-text}
props (map->obj (merge common-props props))]