mirror of https://github.com/penpot/penpot.git
Merge branch 'staging-render' into develop
This commit is contained in:
commit
52b8560b70
|
|
@ -23,7 +23,14 @@
|
||||||
- Fix wrong board size presets in Android [Taiga #12339](https://tree.taiga.io/project/penpot/issue/12339)
|
- Fix wrong board size presets in Android [Taiga #12339](https://tree.taiga.io/project/penpot/issue/12339)
|
||||||
|
|
||||||
|
|
||||||
## 2.12.0 (Unreleased)
|
## 2.12.1
|
||||||
|
|
||||||
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
|
- Fix setting a portion of text as bold or underline messes things up [Github #7980](https://github.com/penpot/penpot/issues/7980)
|
||||||
|
|
||||||
|
|
||||||
|
## 2.12.0
|
||||||
|
|
||||||
### :boom: Breaking changes & Deprecations
|
### :boom: Breaking changes & Deprecations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,30 +23,25 @@ tmux -2 new-session -d -s penpot
|
||||||
tmux rename-window -t penpot:0 'frontend watch'
|
tmux rename-window -t penpot:0 'frontend watch'
|
||||||
tmux select-window -t penpot:0
|
tmux select-window -t penpot:0
|
||||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||||
tmux send-keys -t penpot 'yarn run watch' enter
|
tmux send-keys -t penpot './scripts/watch app' enter
|
||||||
|
|
||||||
tmux new-window -t penpot:1 -n 'frontend shadow'
|
tmux new-window -t penpot:1 -n 'frontend storybook'
|
||||||
tmux select-window -t penpot:1
|
tmux select-window -t penpot:1
|
||||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||||
tmux send-keys -t penpot 'yarn run watch:app' enter
|
tmux send-keys -t penpot './scripts/watch storybook' enter
|
||||||
|
|
||||||
tmux new-window -t penpot:2 -n 'frontend storybook'
|
tmux new-window -t penpot:2 -n 'exporter'
|
||||||
tmux select-window -t penpot:2
|
tmux select-window -t penpot:2
|
||||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
|
||||||
tmux send-keys -t penpot 'yarn run watch:storybook' enter
|
|
||||||
|
|
||||||
tmux new-window -t penpot:3 -n 'exporter'
|
|
||||||
tmux select-window -t penpot:3
|
|
||||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||||
tmux send-keys -t penpot 'rm -f target/app.js*' enter C-l
|
tmux send-keys -t penpot 'rm -f target/app.js*' enter C-l
|
||||||
tmux send-keys -t penpot 'yarn run watch' enter
|
tmux send-keys -t penpot './scripts/watch' enter
|
||||||
|
|
||||||
tmux split-window -v
|
tmux split-window -v
|
||||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||||
tmux send-keys -t penpot './scripts/wait-and-start.sh' enter
|
tmux send-keys -t penpot './scripts/wait-and-start.sh' enter
|
||||||
|
|
||||||
tmux new-window -t penpot:4 -n 'backend'
|
tmux new-window -t penpot:3 -n 'backend'
|
||||||
tmux select-window -t penpot:4
|
tmux select-window -t penpot:3
|
||||||
tmux send-keys -t penpot 'cd penpot/backend' enter C-l
|
tmux send-keys -t penpot 'cd penpot/backend' enter C-l
|
||||||
tmux send-keys -t penpot './scripts/start-dev' enter
|
tmux send-keys -t penpot './scripts/start-dev' enter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clear:shadow-cache": "rm -rf .shadow-cljs && rm -rf target",
|
"clear:shadow-cache": "rm -rf .shadow-cljs && rm -rf target",
|
||||||
"watch:app": "clojure -M:dev:shadow-cljs watch main",
|
"watch:app": "yarn run clear:shadow-cache && clojure -M:dev:shadow-cljs watch main",
|
||||||
"watch": "yarn run clear:shadow-cache && yarn run watch:app",
|
"watch": "yarn run watch:app",
|
||||||
"build:app": "clojure -M:dev:shadow-cljs release main",
|
"build:app": "clojure -M:dev:shadow-cljs release main",
|
||||||
"build": "yarn run clear:shadow-cache && yarn run build:app",
|
"build": "yarn run clear:shadow-cache && yarn run build:app",
|
||||||
"fmt:clj:check": "cljfmt check --parallel=false src/",
|
"fmt:clj:check": "cljfmt check --parallel=false src/",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
TARGET=${1:-app};
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
exec yarn run watch:$TARGET
|
||||||
|
|
@ -47,10 +47,9 @@
|
||||||
"watch:app:libs": "node ./scripts/build-libs.js --watch",
|
"watch:app:libs": "node ./scripts/build-libs.js --watch",
|
||||||
"watch:app:main": "clojure -M:dev:shadow-cljs watch main worker storybook",
|
"watch:app:main": "clojure -M:dev:shadow-cljs watch main worker storybook",
|
||||||
"clear:shadow-cache": "rm -rf .shadow-cljs",
|
"clear:shadow-cache": "rm -rf .shadow-cljs",
|
||||||
"watch:app": "yarn run clear:shadow-cache && concurrently \"yarn run watch:app:main\" \"yarn run watch:app:libs\"",
|
"watch": "exit 0",
|
||||||
"watch": "yarn run watch:app:assets",
|
"watch:app": "yarn run clear:shadow-cache && concurrently --kill-others-on-fail \"yarn run watch:app:assets\" \"yarn run watch:app:main\" \"yarn run watch:app:libs\"",
|
||||||
"watch:storybook": "yarn run build:storybook:assets && concurrently \"storybook dev -p 6006 --no-open\" \"yarn run watch:storybook:assets\"",
|
"watch:storybook": "yarn run build:storybook:assets && concurrently --kill-others-on-fail \"storybook dev -p 6006 --no-open\" \"node ./scripts/watch-storybook.js\""
|
||||||
"watch:storybook:assets": "node ./scripts/watch-storybook.js"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@penpot/draft-js": "portal:./packages/draft-js",
|
"@penpot/draft-js": "portal:./packages/draft-js",
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ export function isJsFile(path) {
|
||||||
export async function compileSass(worker, path, options) {
|
export async function compileSass(worker, path, options) {
|
||||||
path = ph.resolve(path);
|
path = ph.resolve(path);
|
||||||
|
|
||||||
log.info("compile:", path);
|
// log.info("compile:", path);
|
||||||
return worker.exec("compileSass", [path, options]);
|
return worker.exec("compileSass", [path, options]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
TARGET=${1:-app};
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
exec yarn run watch:$TARGET
|
||||||
|
|
@ -106,9 +106,11 @@
|
||||||
:overflowWrap "initial"
|
:overflowWrap "initial"
|
||||||
:lineBreak "auto"
|
:lineBreak "auto"
|
||||||
:whiteSpace "break-spaces"
|
:whiteSpace "break-spaces"
|
||||||
:textRendering "geometricPrecision"
|
:textRendering "geometricPrecision"}
|
||||||
:display "inline-block"
|
base (cond-> base
|
||||||
:verticalAlign "top"}
|
(= (:line-height data) "0")
|
||||||
|
(-> (obj/set! "display" "inline-block")
|
||||||
|
(obj/set! "verticalAlign" "top")))
|
||||||
fills
|
fills
|
||||||
(cond
|
(cond
|
||||||
;; DEPRECATED: still here for backward compatibility with
|
;; DEPRECATED: still here for backward compatibility with
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
[app.common.types.path :as path]
|
[app.common.types.path :as path]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.workspace.transforms :as dwt]
|
[app.main.data.workspace.transforms :as dwt]
|
||||||
[app.main.data.workspace.variants :as dwv]
|
[app.main.data.workspace.variants :as dwv]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
|
|
@ -305,9 +306,15 @@
|
||||||
(->> wasm.api/module
|
(->> wasm.api/module
|
||||||
(p/fmap (fn [ready?]
|
(p/fmap (fn [ready?]
|
||||||
(when ready?
|
(when ready?
|
||||||
(let [init? (wasm.api/init-canvas-context canvas)]
|
(let [init? (try
|
||||||
|
(wasm.api/init-canvas-context canvas)
|
||||||
|
(catch :default e
|
||||||
|
(js/console.error "Error initializing canvas context:" e)
|
||||||
|
false))]
|
||||||
(reset! canvas-init? init?)
|
(reset! canvas-init? init?)
|
||||||
(when-not init? (js/alert "WebGL not supported")))))))
|
(when-not init?
|
||||||
|
(js/alert "WebGL not supported")
|
||||||
|
(st/emit! (dcm/go-to-dashboard-recent))))))))
|
||||||
(fn []
|
(fn []
|
||||||
(wasm.api/clear-canvas))))
|
(wasm.api/clear-canvas))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
[app.common.types.text :as txt]
|
[app.common.types.text :as txt]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
|
[app.main.data.render-wasm :as drw]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.render :as render]
|
[app.main.render :as render]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
|
@ -96,20 +97,20 @@
|
||||||
;; This should never be called from the outside.
|
;; This should never be called from the outside.
|
||||||
(defn- render
|
(defn- render
|
||||||
[timestamp]
|
[timestamp]
|
||||||
(when wasm/context-initialized?
|
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
||||||
(h/call wasm/internal-module "_render" timestamp)
|
(h/call wasm/internal-module "_render" timestamp)
|
||||||
(set! wasm/internal-frame-id nil)
|
(set! wasm/internal-frame-id nil)
|
||||||
(ug/dispatch! (ug/event "penpot:wasm:render"))))
|
(ug/dispatch! (ug/event "penpot:wasm:render"))))
|
||||||
|
|
||||||
(defn render-sync
|
(defn render-sync
|
||||||
[]
|
[]
|
||||||
(when wasm/context-initialized?
|
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
||||||
(h/call wasm/internal-module "_render_sync")
|
(h/call wasm/internal-module "_render_sync")
|
||||||
(set! wasm/internal-frame-id nil)))
|
(set! wasm/internal-frame-id nil)))
|
||||||
|
|
||||||
(defn render-sync-shape
|
(defn render-sync-shape
|
||||||
[id]
|
[id]
|
||||||
(when wasm/context-initialized?
|
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
||||||
(let [buffer (uuid/get-u32 id)]
|
(let [buffer (uuid/get-u32 id)]
|
||||||
(h/call wasm/internal-module "_render_sync_shape"
|
(h/call wasm/internal-module "_render_sync_shape"
|
||||||
(aget buffer 0)
|
(aget buffer 0)
|
||||||
|
|
@ -123,7 +124,7 @@
|
||||||
|
|
||||||
(defn request-render
|
(defn request-render
|
||||||
[_requester]
|
[_requester]
|
||||||
(when (not @pending-render)
|
(when (and wasm/context-initialized? (not @pending-render) (not @wasm/context-lost?))
|
||||||
(reset! pending-render true)
|
(reset! pending-render true)
|
||||||
(js/requestAnimationFrame
|
(js/requestAnimationFrame
|
||||||
(fn [ts]
|
(fn [ts]
|
||||||
|
|
@ -759,13 +760,8 @@
|
||||||
(h/call wasm/internal-module "_clear_shape_layout"))
|
(h/call wasm/internal-module "_clear_shape_layout"))
|
||||||
|
|
||||||
(defn- set-shape-layout
|
(defn- set-shape-layout
|
||||||
[shape objects]
|
[shape]
|
||||||
(clear-layout)
|
(clear-layout)
|
||||||
(when (or (ctl/any-layout? shape)
|
|
||||||
(ctl/any-layout-immediate-child? objects shape)
|
|
||||||
(has-any-layout-prop? shape))
|
|
||||||
(set-layout-data shape))
|
|
||||||
|
|
||||||
(when (ctl/flex-layout? shape)
|
(when (ctl/flex-layout? shape)
|
||||||
(set-flex-layout shape))
|
(set-flex-layout shape))
|
||||||
|
|
||||||
|
|
@ -916,7 +912,7 @@
|
||||||
(perf/end-measure "set-view-box::zoom")))))
|
(perf/end-measure "set-view-box::zoom")))))
|
||||||
|
|
||||||
(defn set-object
|
(defn set-object
|
||||||
[objects shape]
|
[shape]
|
||||||
(perf/begin-measure "set-object")
|
(perf/begin-measure "set-object")
|
||||||
(let [shape (svg-filters/apply-svg-derived shape)
|
(let [shape (svg-filters/apply-svg-derived shape)
|
||||||
id (dm/get-prop shape :id)
|
id (dm/get-prop shape :id)
|
||||||
|
|
@ -981,7 +977,7 @@
|
||||||
(when (= type :text)
|
(when (= type :text)
|
||||||
(set-shape-grow-type grow-type))
|
(set-shape-grow-type grow-type))
|
||||||
|
|
||||||
(set-shape-layout shape objects)
|
(set-shape-layout shape)
|
||||||
(set-shape-selrect selrect)
|
(set-shape-selrect selrect)
|
||||||
|
|
||||||
(let [pending_thumbnails (into [] (concat
|
(let [pending_thumbnails (into [] (concat
|
||||||
|
|
@ -1035,7 +1031,7 @@
|
||||||
|
|
||||||
(defn process-object
|
(defn process-object
|
||||||
[shape]
|
[shape]
|
||||||
(let [{:keys [thumbnails full]} (set-object [] shape)]
|
(let [{:keys [thumbnails full]} (set-object shape)]
|
||||||
(process-pending [shape] thumbnails full noop-fn)))
|
(process-pending [shape] thumbnails full noop-fn)))
|
||||||
|
|
||||||
(defn set-objects
|
(defn set-objects
|
||||||
|
|
@ -1050,7 +1046,7 @@
|
||||||
(loop [index 0 thumbnails-acc [] full-acc []]
|
(loop [index 0 thumbnails-acc [] full-acc []]
|
||||||
(if (< index total-shapes)
|
(if (< index total-shapes)
|
||||||
(let [shape (nth shapes index)
|
(let [shape (nth shapes index)
|
||||||
{:keys [thumbnails full]} (set-object objects shape)]
|
{:keys [thumbnails full]} (set-object shape)]
|
||||||
(recur (inc index)
|
(recur (inc index)
|
||||||
(into thumbnails-acc thumbnails)
|
(into thumbnails-acc thumbnails)
|
||||||
(into full-acc full)))
|
(into full-acc full)))
|
||||||
|
|
@ -1254,40 +1250,57 @@
|
||||||
|
|
||||||
;; Initialize Wasm Render Engine
|
;; Initialize Wasm Render Engine
|
||||||
(h/call wasm/internal-module "_init" (/ (.-width ^js canvas) dpr) (/ (.-height ^js canvas) dpr))
|
(h/call wasm/internal-module "_init" (/ (.-width ^js canvas) dpr) (/ (.-height ^js canvas) dpr))
|
||||||
(h/call wasm/internal-module "_set_render_options" flags dpr))
|
(h/call wasm/internal-module "_set_render_options" flags dpr)
|
||||||
(set! wasm/context-initialized? true))
|
|
||||||
|
|
||||||
(h/call wasm/internal-module "_set_browser" browser)
|
;; Set browser and canvas size only after initialization
|
||||||
|
(h/call wasm/internal-module "_set_browser" browser)
|
||||||
|
(set-canvas-size canvas)
|
||||||
|
|
||||||
|
;; Add event listeners for WebGL context lost
|
||||||
|
(let [handler (fn [event]
|
||||||
|
(.preventDefault event)
|
||||||
|
(reset! wasm/context-lost? true)
|
||||||
|
(log/warn :hint "WebGL context lost")
|
||||||
|
(st/emit! (drw/context-lost)))]
|
||||||
|
(set! wasm/context-lost-handler handler)
|
||||||
|
(set! wasm/context-lost-canvas canvas)
|
||||||
|
(.addEventListener canvas "webglcontextlost" handler))
|
||||||
|
(set! wasm/context-initialized? true)))
|
||||||
|
|
||||||
(h/call wasm/internal-module "_set_render_options" flags dpr)
|
|
||||||
(set-canvas-size canvas)
|
|
||||||
context-init?))
|
context-init?))
|
||||||
|
|
||||||
(defn clear-canvas
|
(defn clear-canvas
|
||||||
[]
|
[]
|
||||||
(try
|
(when wasm/context-initialized?
|
||||||
;; TODO: perform corresponding cleaning
|
(try
|
||||||
(set! wasm/context-initialized? false)
|
;; TODO: perform corresponding cleaning
|
||||||
(h/call wasm/internal-module "_clean_up")
|
(set! wasm/context-initialized? false)
|
||||||
|
(h/call wasm/internal-module "_clean_up")
|
||||||
|
|
||||||
;; Ensure the WebGL context is properly disposed so browsers do not keep
|
;; Remove event listener for WebGL context lost
|
||||||
;; accumulating active contexts between page switches.
|
(when (and wasm/context-lost-handler wasm/context-lost-canvas)
|
||||||
(when-let [gl (unchecked-get wasm/internal-module "GL")]
|
(.removeEventListener wasm/context-lost-canvas "webglcontextlost" wasm/context-lost-handler)
|
||||||
(when-let [handle wasm/gl-context-handle]
|
(set! wasm/context-lost-canvas nil)
|
||||||
(try
|
(set! wasm/context-lost-handler nil))
|
||||||
;; Ask the browser to release resources explicitly if available.
|
|
||||||
(when-let [ctx wasm/gl-context]
|
|
||||||
(when-let [lose-ext (.getExtension ^js ctx "WEBGL_lose_context")]
|
|
||||||
(.loseContext ^js lose-ext)))
|
|
||||||
(.deleteContext ^js gl handle)
|
|
||||||
(finally
|
|
||||||
(set! wasm/gl-context-handle nil)
|
|
||||||
(set! wasm/gl-context nil)))))
|
|
||||||
|
|
||||||
;; If this calls panics we don't want to crash. This happens sometimes
|
;; Ensure the WebGL context is properly disposed so browsers do not keep
|
||||||
;; with hot-reload in develop
|
;; accumulating active contexts between page switches.
|
||||||
(catch :default error
|
(when-let [gl (unchecked-get wasm/internal-module "GL")]
|
||||||
(.error js/console error))))
|
(when-let [handle wasm/gl-context-handle]
|
||||||
|
(try
|
||||||
|
;; Ask the browser to release resources explicitly if available.
|
||||||
|
(when-let [ctx wasm/gl-context]
|
||||||
|
(when-let [lose-ext (.getExtension ^js ctx "WEBGL_lose_context")]
|
||||||
|
(.loseContext ^js lose-ext)))
|
||||||
|
(.deleteContext ^js gl handle)
|
||||||
|
(finally
|
||||||
|
(set! wasm/gl-context-handle nil)
|
||||||
|
(set! wasm/gl-context nil)))))
|
||||||
|
|
||||||
|
;; If this calls panics we don't want to crash. This happens sometimes
|
||||||
|
;; with hot-reload in develop
|
||||||
|
(catch :default error
|
||||||
|
(.error js/console error)))))
|
||||||
|
|
||||||
(defn show-grid
|
(defn show-grid
|
||||||
[id]
|
[id]
|
||||||
|
|
|
||||||
|
|
@ -354,32 +354,32 @@
|
||||||
:is-fallback true}))
|
:is-fallback true}))
|
||||||
|
|
||||||
(def noto-fonts
|
(def noto-fonts
|
||||||
{:japanese {:font-id "gfont-noto-sans-jp" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
{:japanese {:font-id "gfont-noto-sans-jp" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:chinese {:font-id "gfont-noto-sans-sc" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:chinese {:font-id "gfont-noto-sans-sc" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:korean {:font-id "gfont-noto-sans-kr" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:korean {:font-id "gfont-noto-sans-kr" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:arabic {:font-id "gfont-noto-sans-arabic" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:arabic {:font-id "gfont-noto-sans-arabic" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:cyrillic {:font-id "gfont-noto-sans-cyrillic" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:cyrillic {:font-id "gfont-noto-sans" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:greek {:font-id "gfont-noto-sans-greek" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:greek {:font-id "gfont-noto-sans" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:hebrew {:font-id "gfont-noto-sans-hebrew" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:hebrew {:font-id "gfont-noto-sans-hebrew" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:thai {:font-id "gfont-noto-sans-thai" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:thai {:font-id "gfont-noto-sans-thai" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:devanagari {:font-id "gfont-noto-sans-devanagari" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:devanagari {:font-id "gfont-noto-sans" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:tamil {:font-id "gfont-noto-sans-tamil" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:tamil {:font-id "gfont-noto-sans-tamil" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:latin-ext {:font-id "gfont-noto-sans" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:latin-ext {:font-id "gfont-noto-sans" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:vietnamese {:font-id "gfont-noto-sans" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:vietnamese {:font-id "gfont-noto-sans" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:armenian {:font-id "gfont-noto-sans-armenian" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:armenian {:font-id "gfont-noto-sans-armenian" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:bengali {:font-id "gfont-noto-sans-bengali" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:bengali {:font-id "gfont-noto-sans-bengali" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:cherokee {:font-id "gfont-noto-sans-cherokee" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:cherokee {:font-id "gfont-noto-sans-cherokee" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:ethiopic {:font-id "gfont-noto-sans-ethiopic" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:ethiopic {:font-id "gfont-noto-sans-ethiopic" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:georgian {:font-id "gfont-noto-sans-georgian" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:georgian {:font-id "gfont-noto-sans-georgian" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:gujarati {:font-id "gfont-noto-sans-gujarati" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:gujarati {:font-id "gfont-noto-sans-gujarati" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:gurmukhi {:font-id "gfont-noto-sans-gurmukhi" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:gurmukhi {:font-id "gfont-noto-sans-gurmukhi" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:khmer {:font-id "gfont-noto-sans-khmer" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:khmer {:font-id "gfont-noto-sans-khmer" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:lao {:font-id "gfont-noto-sans-lao" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:lao {:font-id "gfont-noto-sans-lao" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:malayalam {:font-id "gfont-noto-sans-malayalam" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:malayalam {:font-id "gfont-noto-sans-malayalam" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:myanmar {:font-id "gfont-noto-sans-myanmar" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:myanmar {:font-id "gfont-noto-sans-myanmar" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:sinhala {:font-id "gfont-noto-sans-sinhala" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:sinhala {:font-id "gfont-noto-sans-sinhala" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:telugu {:font-id "gfont-noto-sans-telugu" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:telugu {:font-id "gfont-noto-sans-telugu" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:tibetan {:font-id "gfont-noto-sans-tibetan" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:tibetan {:font-id "gfont-noto-serif-tibetan" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:javanese {:font-id "gfont-noto-sans-javanese" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:javanese {:font-id "gfont-noto-sans-javanese" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:kannada {:font-id "gfont-noto-sans-kannada" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:kannada {:font-id "gfont-noto-sans-kannada" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:oriya {:font-id "gfont-noto-sans-oriya" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:oriya {:font-id "gfont-noto-sans-oriya" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
|
|
@ -399,8 +399,8 @@
|
||||||
:bamum {:font-id "gfont-noto-sans-bamum" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:bamum {:font-id "gfont-noto-sans-bamum" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:meroitic {:font-id "gfont-noto-sans-meroitic" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:meroitic {:font-id "gfont-noto-sans-meroitic" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:symbols {:font-id "gfont-noto-sans-symbols" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:symbols {:font-id "gfont-noto-sans-symbols" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:symbols-2 {:font-id "gfont-noto-sans-symbols-2" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
:symbols-2 {:font-id "gfont-noto-sans-symbols-2" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}
|
||||||
:music {:font-id "gfont-noto-music" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}})
|
:music {:font-id "gfont-noto-music" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true}})
|
||||||
|
|
||||||
(defn add-noto-fonts [fonts languages]
|
(defn add-noto-fonts [fonts languages]
|
||||||
(reduce (fn [acc lang]
|
(reduce (fn [acc lang]
|
||||||
|
|
|
||||||
|
|
@ -280,8 +280,18 @@
|
||||||
:layout-grid-cells
|
:layout-grid-cells
|
||||||
(api/set-grid-layout-cells v)
|
(api/set-grid-layout-cells v)
|
||||||
|
|
||||||
(:layout
|
:layout
|
||||||
:layout-flex-dir
|
(do
|
||||||
|
(api/clear-layout)
|
||||||
|
(cond
|
||||||
|
(ctl/grid-layout? shape)
|
||||||
|
(api/set-grid-layout shape)
|
||||||
|
|
||||||
|
(ctl/flex-layout? shape)
|
||||||
|
(api/set-flex-layout shape))
|
||||||
|
(api/set-layout-data shape))
|
||||||
|
|
||||||
|
(:layout-flex-dir
|
||||||
:layout-gap-type
|
:layout-gap-type
|
||||||
:layout-gap
|
:layout-gap
|
||||||
:layout-align-items
|
:layout-align-items
|
||||||
|
|
@ -291,15 +301,12 @@
|
||||||
:layout-wrap-type
|
:layout-wrap-type
|
||||||
:layout-padding-type
|
:layout-padding-type
|
||||||
:layout-padding)
|
:layout-padding)
|
||||||
(do
|
(cond
|
||||||
(api/clear-layout)
|
(ctl/grid-layout? shape)
|
||||||
(cond
|
(api/set-grid-layout-data shape)
|
||||||
(ctl/grid-layout? shape)
|
|
||||||
(api/set-grid-layout-data shape)
|
|
||||||
|
|
||||||
(ctl/flex-layout? shape)
|
(ctl/flex-layout? shape)
|
||||||
(api/set-flex-layout shape))
|
(api/set-flex-layout shape))
|
||||||
(api/set-layout-data shape))
|
|
||||||
|
|
||||||
;; Property not in WASM
|
;; Property not in WASM
|
||||||
nil))))
|
nil))))
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,6 @@
|
||||||
:fill-rule shared/RawFillRule})
|
:fill-rule shared/RawFillRule})
|
||||||
|
|
||||||
(defonce context-initialized? false)
|
(defonce context-initialized? false)
|
||||||
|
(defonce context-lost? (atom false))
|
||||||
|
(defonce context-lost-handler nil)
|
||||||
|
(defonce context-lost-canvas nil)
|
||||||
|
|
@ -275,6 +275,14 @@ pub extern "C" fn set_view_end() {
|
||||||
}
|
}
|
||||||
performance::end_measure!("set_view_end::rebuild_tiles");
|
performance::end_measure!("set_view_end::rebuild_tiles");
|
||||||
performance::end_timed_log!("rebuild_tiles", _rebuild_start);
|
performance::end_timed_log!("rebuild_tiles", _rebuild_start);
|
||||||
|
} else {
|
||||||
|
// During pan, we only clear the tile index without
|
||||||
|
// invalidating cached textures, which is more efficient.
|
||||||
|
let _clear_start = performance::begin_timed_log!("clear_tile_index");
|
||||||
|
performance::begin_measure!("set_view_end::clear_tile_index");
|
||||||
|
state.clear_tile_index();
|
||||||
|
performance::end_measure!("set_view_end::clear_tile_index");
|
||||||
|
performance::end_timed_log!("clear_tile_index", _clear_start);
|
||||||
}
|
}
|
||||||
performance::end_measure!("set_view_end");
|
performance::end_measure!("set_view_end");
|
||||||
performance::end_timed_log!("set_view_end", _end_start);
|
performance::end_timed_log!("set_view_end", _end_start);
|
||||||
|
|
|
||||||
|
|
@ -999,12 +999,13 @@ impl RenderState {
|
||||||
|
|
||||||
let viewbox_cache_size = get_cache_size(self.viewbox, scale);
|
let viewbox_cache_size = get_cache_size(self.viewbox, scale);
|
||||||
let cached_viewbox_cache_size = get_cache_size(self.cached_viewbox, scale);
|
let cached_viewbox_cache_size = get_cache_size(self.cached_viewbox, scale);
|
||||||
if viewbox_cache_size != cached_viewbox_cache_size {
|
// Only resize cache if the new size is larger than the cached size
|
||||||
self.surfaces.resize_cache(
|
// This avoids unnecessary surface recreations when the cache size decreases
|
||||||
&mut self.gpu_state,
|
if viewbox_cache_size.width > cached_viewbox_cache_size.width
|
||||||
viewbox_cache_size,
|
|| viewbox_cache_size.height > cached_viewbox_cache_size.height
|
||||||
VIEWPORT_INTEREST_AREA_THRESHOLD,
|
{
|
||||||
);
|
self.surfaces
|
||||||
|
.resize_cache(viewbox_cache_size, VIEWPORT_INTEREST_AREA_THRESHOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - review debug
|
// FIXME - review debug
|
||||||
|
|
@ -1961,6 +1962,17 @@ impl RenderState {
|
||||||
performance::end_measure!("rebuild_tiles_shallow");
|
performance::end_measure!("rebuild_tiles_shallow");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clears the tile index without invalidating cached tile textures.
|
||||||
|
/// This is useful when tile positions don't change (e.g., during pan operations)
|
||||||
|
/// but the tile index needs to be synchronized. The cached tile textures remain
|
||||||
|
/// valid since they don't depend on the current view position, only on zoom level.
|
||||||
|
/// This is much more efficient than clearing the entire cache surface.
|
||||||
|
pub fn clear_tile_index(&mut self) {
|
||||||
|
performance::begin_measure!("clear_tile_index");
|
||||||
|
self.surfaces.clear_tiles();
|
||||||
|
performance::end_measure!("clear_tile_index");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rebuild_tiles_from(&mut self, tree: ShapesPoolRef, base_id: Option<&Uuid>) {
|
pub fn rebuild_tiles_from(&mut self, tree: ShapesPoolRef, base_id: Option<&Uuid>) {
|
||||||
performance::begin_measure!("rebuild_tiles");
|
performance::begin_measure!("rebuild_tiles");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,10 @@ impl Surfaces {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_tiles(&mut self) {
|
||||||
|
self.tiles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, gpu_state: &mut GpuState, new_width: i32, new_height: i32) {
|
pub fn resize(&mut self, gpu_state: &mut GpuState, new_width: i32, new_height: i32) {
|
||||||
self.reset_from_target(gpu_state.create_target_surface(new_width, new_height));
|
self.reset_from_target(gpu_state.create_target_surface(new_width, new_height));
|
||||||
}
|
}
|
||||||
|
|
@ -248,13 +252,8 @@ impl Surfaces {
|
||||||
// The rest are tile size surfaces
|
// The rest are tile size surfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize_cache(
|
pub fn resize_cache(&mut self, cache_dims: skia::ISize, interest_area_threshold: i32) {
|
||||||
&mut self,
|
self.cache = self.target.new_surface_with_dimensions(cache_dims).unwrap();
|
||||||
gpu_state: &mut GpuState,
|
|
||||||
cache_dims: skia::ISize,
|
|
||||||
interest_area_threshold: i32,
|
|
||||||
) {
|
|
||||||
self.cache = gpu_state.create_surface_with_isize("cache".to_string(), cache_dims);
|
|
||||||
self.cache.canvas().reset_matrix();
|
self.cache.canvas().reset_matrix();
|
||||||
self.cache.canvas().translate((
|
self.cache.canvas().translate((
|
||||||
(interest_area_threshold as f32 * TILE_SIZE),
|
(interest_area_threshold as f32 * TILE_SIZE),
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,10 @@ impl<'a> State<'a> {
|
||||||
self.render_state.rebuild_tiles_shallow(&self.shapes);
|
self.render_state.rebuild_tiles_shallow(&self.shapes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_tile_index(&mut self) {
|
||||||
|
self.render_state.clear_tile_index();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rebuild_tiles(&mut self) {
|
pub fn rebuild_tiles(&mut self) {
|
||||||
self.render_state.rebuild_tiles_from(&self.shapes, None);
|
self.render_state.rebuild_tiles_from(&self.shapes, None);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue