Merge pull request #7729 from penpot/ladybenko-12514-fix-font-variants
🐛 Fix downloading wrong font variant
|
After Width: | Height: | Size: 9.7 KiB |
@@ -23,11 +23,18 @@ export class BasePage {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async mockFileMediaAsset(page, assetId, assetFilename, options) {
|
static async mockFileMediaAsset(
|
||||||
|
page,
|
||||||
|
assetId,
|
||||||
|
assetFilename,
|
||||||
|
assetThumbnailFilename,
|
||||||
|
options,
|
||||||
|
) {
|
||||||
const ids = Array.isArray(assetId) ? assetId : [assetId];
|
const ids = Array.isArray(assetId) ? assetId : [assetId];
|
||||||
|
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
const url = `**/assets/by-file-media-id/${id}`;
|
const url = `**/assets/by-file-media-id/${id}`;
|
||||||
|
const thumbnailUrl = `${url}/thumbnail`;
|
||||||
|
|
||||||
await page.route(url, (route) =>
|
await page.route(url, (route) =>
|
||||||
route.fulfill({
|
route.fulfill({
|
||||||
@@ -36,6 +43,16 @@ export class BasePage {
|
|||||||
...options,
|
...options,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (assetThumbnailFilename) {
|
||||||
|
await page.route(thumbnailUrl, (route) =>
|
||||||
|
route.fulfill({
|
||||||
|
path: `playwright/data/${assetThumbnailFilename}`,
|
||||||
|
status: 200,
|
||||||
|
...options,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,22 +72,6 @@ export class BasePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async mockFileMediaAsset(page, assetId, assetFilename, options) {
|
|
||||||
const ids = Array.isArray(assetId) ? assetId : [assetId];
|
|
||||||
|
|
||||||
for (const id of ids) {
|
|
||||||
const url = `**/assets/by-file-media-id/${id}`;
|
|
||||||
|
|
||||||
await page.route(url, (route) =>
|
|
||||||
route.fulfill({
|
|
||||||
path: `playwright/data/${assetFilename}`,
|
|
||||||
status: 200,
|
|
||||||
...options,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static async mockConfigFlags(page, flags) {
|
static async mockConfigFlags(page, flags) {
|
||||||
const url = "**/js/config.js?ts=*";
|
const url = "**/js/config.js?ts=*";
|
||||||
return await page.route(url, (route) =>
|
return await page.route(url, (route) =>
|
||||||
@@ -100,11 +101,17 @@ export class BasePage {
|
|||||||
return BasePage.mockConfigFlags(this.page, flags);
|
return BasePage.mockConfigFlags(this.page, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
async mockFileMediaAsset(assetId, assetFilename, options) {
|
async mockFileMediaAsset(
|
||||||
|
assetId,
|
||||||
|
assetFilename,
|
||||||
|
assetThumbnailFilename,
|
||||||
|
options,
|
||||||
|
) {
|
||||||
return BasePage.mockFileMediaAsset(
|
return BasePage.mockFileMediaAsset(
|
||||||
this.page,
|
this.page,
|
||||||
assetId,
|
assetId,
|
||||||
assetFilename,
|
assetFilename,
|
||||||
|
assetThumbnailFilename,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ test("Renders a file with solid, gradient and image fills", async ({
|
|||||||
"1ebcea38-f1bf-8101-8006-4c8f579da49c",
|
"1ebcea38-f1bf-8101-8006-4c8f579da49c",
|
||||||
],
|
],
|
||||||
"render-wasm/assets/penguins.jpg",
|
"render-wasm/assets/penguins.jpg",
|
||||||
|
"render-wasm/assets/pattern-thumbnail.png", // FIXME: get real thumbnail
|
||||||
);
|
);
|
||||||
await workspace.mockGetFile("render-wasm/get-file-shapes-fills.json");
|
await workspace.mockGetFile("render-wasm/get-file-shapes-fills.json");
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ test("Renders a file with strokes", async ({ page }) => {
|
|||||||
"202c1104-9385-81d3-8006-507560ce29e3",
|
"202c1104-9385-81d3-8006-507560ce29e3",
|
||||||
],
|
],
|
||||||
"render-wasm/assets/penguins.jpg",
|
"render-wasm/assets/penguins.jpg",
|
||||||
|
"render-wasm/assets/pattern-thumbnail.png", // FIXME: get real thumbnail
|
||||||
);
|
);
|
||||||
await workspace.mockGetFile("render-wasm/get-file-shapes-strokes.json");
|
await workspace.mockGetFile("render-wasm/get-file-shapes-strokes.json");
|
||||||
|
|
||||||
@@ -88,6 +90,11 @@ test("Renders a file with shapes with multiple fills", async ({ page }) => {
|
|||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-multiple-fills.json");
|
await workspace.mockGetFile("render-wasm/get-file-multiple-fills.json");
|
||||||
|
await workspace.mockFileMediaAsset(
|
||||||
|
["c0939f58-37bc-805d-8006-51cda84a405a"],
|
||||||
|
"render-wasm/assets/penguins.jpg",
|
||||||
|
"render-wasm/assets/pattern-thumbnail.png", // FIXME: get real thumbnail
|
||||||
|
);
|
||||||
|
|
||||||
await workspace.goToWorkspace({
|
await workspace.goToWorkspace({
|
||||||
id: "c0939f58-37bc-805d-8006-51cd3a51c255",
|
id: "c0939f58-37bc-805d-8006-51cd3a51c255",
|
||||||
@@ -127,6 +134,7 @@ test("Renders shapes with exif rotated images fills and strokes", async ({
|
|||||||
"27270c45-35b4-80f3-8006-63a3ea82557f",
|
"27270c45-35b4-80f3-8006-63a3ea82557f",
|
||||||
],
|
],
|
||||||
"render-wasm/assets/landscape.jpg",
|
"render-wasm/assets/landscape.jpg",
|
||||||
|
"render-wasm/assets/pattern-thumbnail.png", // FIXME: get real thumbnail
|
||||||
);
|
);
|
||||||
await workspace.mockGetFile(
|
await workspace.mockGetFile(
|
||||||
"render-wasm/get-file-shapes-exif-rotated-fills.json",
|
"render-wasm/get-file-shapes-exif-rotated-fills.json",
|
||||||
@@ -170,6 +178,15 @@ test("Renders a file with blurs applied to any kind of shape", async ({
|
|||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-blurs.json");
|
await workspace.mockGetFile("render-wasm/get-file-blurs.json");
|
||||||
|
await workspace.mockFileMediaAsset(
|
||||||
|
[
|
||||||
|
"aa0a383a-7553-808a-8006-ae13a3c575eb",
|
||||||
|
"aa0a383a-7553-808a-8006-ae13c84d6e3a",
|
||||||
|
"aa0a383a-7553-808a-8006-ae131157fc26",
|
||||||
|
],
|
||||||
|
"render-wasm/assets/pattern.png",
|
||||||
|
"render-wasm/assets/pattern-thumbnail.png", // FIXME: get real thumbnail
|
||||||
|
);
|
||||||
|
|
||||||
await workspace.goToWorkspace({
|
await workspace.goToWorkspace({
|
||||||
id: "aa0a383a-7553-808a-8006-ae1237b52cf9",
|
id: "aa0a383a-7553-808a-8006-ae1237b52cf9",
|
||||||
@@ -212,10 +229,7 @@ test("Renders a file with a closed path shape with multiple segments using strok
|
|||||||
await expect(workspace.canvas).toHaveScreenshot();
|
await expect(workspace.canvas).toHaveScreenshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Renders a file with paths and svg attrs", async ({ page }) => {
|
||||||
test("Renders a file with paths and svg attrs", async ({
|
|
||||||
page,
|
|
||||||
}) => {
|
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-svg-attrs.json");
|
await workspace.mockGetFile("render-wasm/get-file-svg-attrs.json");
|
||||||
@@ -234,7 +248,9 @@ test("Renders a file with nested frames with inherited blur", async ({
|
|||||||
}) => {
|
}) => {
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-frame-with-nested-blur.json");
|
await workspace.mockGetFile(
|
||||||
|
"render-wasm/get-file-frame-with-nested-blur.json",
|
||||||
|
);
|
||||||
|
|
||||||
await workspace.goToWorkspace({
|
await workspace.goToWorkspace({
|
||||||
id: "58c5cc60-d124-81bd-8007-0ee4e5030609",
|
id: "58c5cc60-d124-81bd-8007-0ee4e5030609",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 318 KiB |
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 335 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 44 KiB |
@@ -141,6 +141,7 @@ test("Renders a file with texts with images", async ({ page }) => {
|
|||||||
"4f89252d-ebbc-813e-8006-8699e4170e18",
|
"4f89252d-ebbc-813e-8006-8699e4170e18",
|
||||||
],
|
],
|
||||||
"render-wasm/assets/pattern.png",
|
"render-wasm/assets/pattern.png",
|
||||||
|
"render-wasm/assets/pattern-thumbnail.png",
|
||||||
);
|
);
|
||||||
await mockGetEmojiFont(workspace);
|
await mockGetEmojiFont(workspace);
|
||||||
await mockGetJapaneseFont(workspace);
|
await mockGetJapaneseFont(workspace);
|
||||||
@@ -179,6 +180,7 @@ test("Renders a file with text decoration", async ({ page }) => {
|
|||||||
await workspace.mockFileMediaAsset(
|
await workspace.mockFileMediaAsset(
|
||||||
["d6c33e7b-7b64-80f3-8006-78509a3a2d21"],
|
["d6c33e7b-7b64-80f3-8006-78509a3a2d21"],
|
||||||
"render-wasm/assets/pattern.png",
|
"render-wasm/assets/pattern.png",
|
||||||
|
"render-wasm/assets/pattern-thumbnail.png",
|
||||||
);
|
);
|
||||||
await mockGetEmojiFont(workspace);
|
await mockGetEmojiFont(workspace);
|
||||||
await mockGetJapaneseFont(workspace);
|
await mockGetJapaneseFont(workspace);
|
||||||
@@ -281,14 +283,10 @@ test("Renders a file with different text shadows combinations", async ({
|
|||||||
await expect(workspace.canvas).toHaveScreenshot();
|
await expect(workspace.canvas).toHaveScreenshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Renders a file with multiple text shadows in order", async ({
|
test("Renders a file with multiple text shadows in order", async ({ page }) => {
|
||||||
page,
|
|
||||||
}) => {
|
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile(
|
await workspace.mockGetFile("render-wasm/get-file-text-shadows-order.json");
|
||||||
"render-wasm/get-file-text-shadows-order.json",
|
|
||||||
);
|
|
||||||
|
|
||||||
await workspace.goToWorkspace({
|
await workspace.goToWorkspace({
|
||||||
id: "48ffa82f-6950-81b5-8006-e49a2a39657f",
|
id: "48ffa82f-6950-81b5-8006-e49a2a39657f",
|
||||||
@@ -337,7 +335,9 @@ test("Renders a file with texts with with text spans of different sizes", async
|
|||||||
}) => {
|
}) => {
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-text-spans-different-sizes.json");
|
await workspace.mockGetFile(
|
||||||
|
"render-wasm/get-file-text-spans-different-sizes.json",
|
||||||
|
);
|
||||||
|
|
||||||
await workspace.goToWorkspace({
|
await workspace.goToWorkspace({
|
||||||
id: "a0b1a70e-0d02-8082-8006-ff6d160f15ce",
|
id: "a0b1a70e-0d02-8082-8006-ff6d160f15ce",
|
||||||
@@ -347,9 +347,8 @@ test("Renders a file with texts with with text spans of different sizes", async
|
|||||||
await expect(workspace.canvas).toHaveScreenshot();
|
await expect(workspace.canvas).toHaveScreenshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Renders a file with texts with tabs", async ({
|
// TODO: enable this test once we use the wasm renderer in the new editor
|
||||||
page,
|
test.skip("Renders a file with texts with tabs", async ({ page }) => {
|
||||||
}) => {
|
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-text-tabs.json");
|
await workspace.mockGetFile("render-wasm/get-file-text-tabs.json");
|
||||||
@@ -367,9 +366,8 @@ test("Renders a file with texts with tabs", async ({
|
|||||||
await expect(workspace.canvas).toHaveScreenshot();
|
await expect(workspace.canvas).toHaveScreenshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Renders a file with texts with empty lines", async ({
|
// TODO: enable this test once we use the wasm renderer in the new editor
|
||||||
page,
|
test.skip("Renders a file with texts with empty lines", async ({ page }) => {
|
||||||
}) => {
|
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-empty-lines.json");
|
await workspace.mockGetFile("render-wasm/get-file-empty-lines.json");
|
||||||
@@ -387,9 +385,8 @@ test("Renders a file with texts with empty lines", async ({
|
|||||||
await expect(workspace.canvas).toHaveScreenshot();
|
await expect(workspace.canvas).toHaveScreenshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Renders a file with texts with breaking words", async ({
|
// TODO: enable this test once we use the wasm renderer in the new editor
|
||||||
page,
|
test.skip("Renders a file with texts with breaking words", async ({ page }) => {
|
||||||
}) => {
|
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
await workspace.setupEmptyFile();
|
await workspace.setupEmptyFile();
|
||||||
await workspace.mockGetFile("render-wasm/get-file-empty-lines.json");
|
await workspace.mockGetFile("render-wasm/get-file-empty-lines.json");
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 247 KiB |
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 104 KiB |
@@ -912,7 +912,7 @@
|
|||||||
(map :id)
|
(map :id)
|
||||||
(run! f/update-text-layout)))
|
(run! f/update-text-layout)))
|
||||||
|
|
||||||
(defn process-pending
|
(defn process-pending!
|
||||||
[shapes thumbnails full]
|
[shapes thumbnails full]
|
||||||
(let [event (js/CustomEvent. "wasm:set-objects-finished")
|
(let [event (js/CustomEvent. "wasm:set-objects-finished")
|
||||||
pending-thumbnails (-> (d/index-by :key :callback thumbnails) vals)
|
pending-thumbnails (-> (d/index-by :key :callback thumbnails) vals)
|
||||||
@@ -920,11 +920,11 @@
|
|||||||
(->> (rx/concat
|
(->> (rx/concat
|
||||||
(->> (rx/from pending-thumbnails)
|
(->> (rx/from pending-thumbnails)
|
||||||
(rx/merge-map (fn [callback] (callback)))
|
(rx/merge-map (fn [callback] (callback)))
|
||||||
(rx/reduce conj [])
|
(rx/reduce conj []))
|
||||||
(rx/tap #(.dispatchEvent ^js js/document event)))
|
|
||||||
(->> (rx/from pending-full)
|
(->> (rx/from pending-full)
|
||||||
(rx/mapcat (fn [callback] (callback)))
|
(rx/mapcat (fn [callback] (callback)))
|
||||||
(rx/reduce conj [])))
|
(rx/reduce conj [])
|
||||||
|
(rx/tap #(.dispatchEvent ^js js/document event))))
|
||||||
(rx/subs!
|
(rx/subs!
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(update-text-layouts shapes)
|
(update-text-layouts shapes)
|
||||||
@@ -933,7 +933,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)))
|
(process-pending! [shape] thumbnails full)))
|
||||||
|
|
||||||
(defn set-objects
|
(defn set-objects
|
||||||
[objects]
|
[objects]
|
||||||
@@ -951,7 +951,7 @@
|
|||||||
(into full-acc full)))
|
(into full-acc full)))
|
||||||
{:thumbnails thumbnails-acc :full full-acc}))]
|
{:thumbnails thumbnails-acc :full full-acc}))]
|
||||||
(perf/end-measure "set-objects")
|
(perf/end-measure "set-objects")
|
||||||
(process-pending shapes thumbnails full)))
|
(process-pending! shapes thumbnails full)))
|
||||||
|
|
||||||
(defn clear-focus-mode
|
(defn clear-focus-mode
|
||||||
[]
|
[]
|
||||||
|
|||||||
@@ -66,9 +66,10 @@
|
|||||||
:custom
|
:custom
|
||||||
(let [font-uuid (custom-font-id->uuid font-id)
|
(let [font-uuid (custom-font-id->uuid font-id)
|
||||||
matching-font (d/seek (fn [[_ font]]
|
matching-font (d/seek (fn [[_ font]]
|
||||||
(and (= (:font-id font) font-uuid)
|
(let [variant-id (or (:font-variant-id font) (dm/str (:font-style font) "-" (:font-weight font)))]
|
||||||
(or (nil? (:font-variant-id font))
|
(and (= (:font-id font) font-uuid)
|
||||||
(= (:font-variant-id font) font-variant-id))))
|
(or (nil? font-variant-id)
|
||||||
|
(= variant-id font-variant-id)))))
|
||||||
(seq @fonts))]
|
(seq @fonts))]
|
||||||
(when matching-font
|
(when matching-font
|
||||||
(:ttf-file-id (second matching-font))))
|
(:ttf-file-id (second matching-font))))
|
||||||
@@ -85,7 +86,7 @@
|
|||||||
(aget shape-id-buffer 2)
|
(aget shape-id-buffer 2)
|
||||||
(aget shape-id-buffer 3))))
|
(aget shape-id-buffer 3))))
|
||||||
|
|
||||||
;; IMPORTANT: It should be noted that only TTF fonts can be stored.
|
;; IMPORTANT: Only TTF fonts can be stored.
|
||||||
(defn- store-font-buffer
|
(defn- store-font-buffer
|
||||||
[shape-id font-data font-array-buffer emoji? fallback?]
|
[shape-id font-data font-array-buffer emoji? fallback?]
|
||||||
(let [font-id-buffer (:family-id-buffer font-data)
|
(let [font-id-buffer (:family-id-buffer font-data)
|
||||||
@@ -231,6 +232,7 @@
|
|||||||
|
|
||||||
(store-font-id shape-id font-data asset-id emoji? fallback?)))
|
(store-font-id shape-id font-data asset-id emoji? fallback?)))
|
||||||
|
|
||||||
|
|
||||||
(defn store-fonts
|
(defn store-fonts
|
||||||
[shape-id fonts]
|
[shape-id fonts]
|
||||||
(keep (fn [font] (store-font shape-id font)) fonts))
|
(keep (fn [font] (store-font shape-id font)) fonts))
|
||||||
|
|||||||
@@ -198,20 +198,20 @@
|
|||||||
:coptic #"[\u2C80-\u2CFF]"
|
:coptic #"[\u2C80-\u2CFF]"
|
||||||
:ol-chiki #"[\u1C50-\u1C7F]"
|
:ol-chiki #"[\u1C50-\u1C7F]"
|
||||||
:vai #"[\uA500-\uA63F]"
|
:vai #"[\uA500-\uA63F]"
|
||||||
:shavian #"[\u10450-\u1047F]"
|
:shavian #"\uD801[\uDC50-\uDC7F]"
|
||||||
:osmanya #"[\u10480-\u104AF]"
|
:osmanya #"\uD801[\uDC80-\uDCAF]"
|
||||||
:runic #"[\u16A0-\u16FF]"
|
:runic #"[\u16A0-\u16FF]"
|
||||||
:old-italic #"[\u10300-\u1032F]"
|
:old-italic #"\uD800[\uDF00-\uDF2F]"
|
||||||
:brahmi #"[\u11000-\u1107F]"
|
:brahmi #"\uD804[\uDC00-\uDC7F]"
|
||||||
:modi #"[\u11600-\u1165F]"
|
:modi #"\uD805[\uDE00-\uDE5F]"
|
||||||
:sora-sompeng #"[\u110D0-\u110FF]"
|
:sora-sompeng #"\uD804[\uDCD0-\uDCFF]"
|
||||||
:bamum #"[\uA6A0-\uA6FF]"
|
:bamum #"[\uA6A0-\uA6FF]"
|
||||||
:meroitic #"[\u10980-\u1099F]"
|
:meroitic #"\uD802[\uDD80-\uDD9F]"
|
||||||
;; Arrows, Mathematical Operators, Misc Technical, Geometric Shapes, Misc Symbols, Dingbats, Supplemental Arrows, etc.
|
;; Arrows, Mathematical Operators, Misc Technical, Geometric Shapes, Misc Symbols, Dingbats, Supplemental Arrows, etc.
|
||||||
:symbols #"[\u2190-\u21FF\u2200-\u22FF\u2300-\u23FF\u25A0-\u25FF\u2600-\u26FF\u2700-\u27BF\u2B00-\u2BFF]"
|
:symbols #"[\u2190-\u21FF\u2200-\u22FF\u2300-\u23FF\u25A0-\u25FF\u2600-\u26FF\u2700-\u27BF\u2B00-\u2BFF]"
|
||||||
;; Additional arrows, math, technical, geometric, and symbol blocks
|
;; Additional arrows, math, technical, geometric, and symbol blocks
|
||||||
:symbols-2 #"[\u2190-\u21FF\u2200-\u22FF\u2300-\u23FF\u25A0-\u25FF\u2600-\u26FF\u2700-\u27BF\u2B00-\u2BFF]"
|
:symbols-2 #"[\u2190-\u21FF\u2200-\u22FF\u2300-\u23FF\u25A0-\u25FF\u2600-\u26FF\u2700-\u27BF\u2B00-\u2BFF]"
|
||||||
:music #"[\u2669-\u267B\u1D100-\u1D1FF]"})
|
:music #"[\u2669-\u267B]|\uD834[\uDD00-\uDD1F]"})
|
||||||
|
|
||||||
(defn contains-emoji? [text]
|
(defn contains-emoji? [text]
|
||||||
(let [result (re-find emoji-pattern text)]
|
(let [result (re-find emoji-pattern text)]
|
||||||
|
|||||||
@@ -187,8 +187,12 @@
|
|||||||
(api/set-shape-svg-raw-content (api/get-static-markup shape))
|
(api/set-shape-svg-raw-content (api/get-static-markup shape))
|
||||||
|
|
||||||
(= (:type shape) :text)
|
(= (:type shape) :text)
|
||||||
(do (api/set-shape-text-content id v)
|
(let [pending-thumbnails (into [] (concat (api/set-shape-text-content id v)))
|
||||||
(api/set-shape-text-images id v)))
|
pending-full (into [] (concat (api/set-shape-text-images id v)))]
|
||||||
|
;; FIXME: this is a hack to process the pending tasks asynchronously
|
||||||
|
;; we should probably modify set-wasm-attr! to return a list of callbacks to be executed in a second pass.
|
||||||
|
(api/process-pending! [shape] pending-thumbnails pending-full)
|
||||||
|
nil))
|
||||||
|
|
||||||
:grow-type
|
:grow-type
|
||||||
(api/set-shape-grow-type v)
|
(api/set-shape-grow-type v)
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ fn draw_text(
|
|||||||
paragraph.paint(canvas, xy);
|
paragraph.paint(canvas, xy);
|
||||||
|
|
||||||
if paragraph_index == group_len - 1 {
|
if paragraph_index == group_len - 1 {
|
||||||
group_offset_y += paragraph.height();
|
group_offset_y += paragraph.ideographic_baseline();
|
||||||
}
|
}
|
||||||
|
|
||||||
for line_metrics in paragraph.get_line_metrics().iter() {
|
for line_metrics in paragraph.get_line_metrics().iter() {
|
||||||
|
|||||||