Add DEFAULT_FONT_FAMILY constant, load fonts on paste and .fig import
Replace all 'Inter' string literals with DEFAULT_FONT_FAMILY from constants. Add loadFontsForNodes() that collects font families from text nodes and loads them into CanvasKit, called after clipboard paste and .fig file import.
This commit is contained in:
parent
da2df1296b
commit
534a7b298e
|
|
@ -32,6 +32,7 @@ export const PEN_CLOSE_RADIUS_BOOST = 2
|
|||
export const PEN_PATH_STROKE_WIDTH = 2
|
||||
export const PARENT_OUTLINE_ALPHA = 0.5
|
||||
export const PARENT_OUTLINE_DASH = 4
|
||||
export const DEFAULT_FONT_FAMILY = 'Inter'
|
||||
export const DEFAULT_FONT_SIZE = 14
|
||||
export const DEFAULT_STROKE_MITER_LIMIT = 4
|
||||
export const LABEL_FONT_SIZE = 11
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BLACK, DEFAULT_STROKE_MITER_LIMIT } from '../constants'
|
||||
import { BLACK, DEFAULT_FONT_FAMILY, DEFAULT_STROKE_MITER_LIMIT } from '../constants'
|
||||
import { styleToWeight } from '../fonts'
|
||||
import { decodeVectorNetworkBlob } from '../vector'
|
||||
|
||||
|
|
@ -449,7 +449,7 @@ export function nodeChangeToProps(
|
|||
cornerSmoothing: nc.cornerSmoothing ?? 0,
|
||||
text: nc.textData?.characters ?? '',
|
||||
fontSize: nc.fontSize ?? 14,
|
||||
fontFamily: nc.fontName?.family ?? 'Inter',
|
||||
fontFamily: nc.fontName?.family ?? DEFAULT_FONT_FAMILY,
|
||||
fontWeight: styleToWeight(nc.fontName?.style ?? ''),
|
||||
italic: nc.fontName?.style?.toLowerCase().includes('italic') ?? false,
|
||||
textAlignHorizontal:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { colorToHex } from '../color'
|
||||
import { DEFAULT_FONT_FAMILY } from '../constants'
|
||||
|
||||
import type { SceneGraph, SceneNode, Fill, Stroke, Effect, NodeType, Color } from '../scene-graph'
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ function collectProps(node: SceneNode, graph: SceneGraph): [string, unknown][] {
|
|||
|
||||
if (node.type === 'TEXT') {
|
||||
if (node.fontSize !== 14) props.push(['size', node.fontSize])
|
||||
if (node.fontFamily && node.fontFamily !== 'Inter') props.push(['font', node.fontFamily])
|
||||
if (node.fontFamily && node.fontFamily !== DEFAULT_FONT_FAMILY) props.push(['font', node.fontFamily])
|
||||
if (node.fontWeight !== 400) {
|
||||
if (node.fontWeight === 700) props.push(['weight', 'bold'])
|
||||
else if (node.fontWeight === 500) props.push(['weight', 'medium'])
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ import {
|
|||
RULER_MAJOR_TOLERANCE,
|
||||
TEXT_SELECTION_COLOR,
|
||||
TEXT_CARET_COLOR,
|
||||
TEXT_CARET_WIDTH
|
||||
TEXT_CARET_WIDTH,
|
||||
DEFAULT_FONT_FAMILY
|
||||
} from './constants'
|
||||
import { isFontLoaded } from './fonts'
|
||||
import { vectorNetworkToPath } from './vector'
|
||||
|
|
@ -306,7 +307,7 @@ export class SkiaRenderer {
|
|||
const { initFontService, loadFont } = await import('./fonts')
|
||||
initFontService(this.ck, this.fontProvider)
|
||||
|
||||
const fontData = await loadFont('Inter', 'Regular')
|
||||
const fontData = await loadFont(DEFAULT_FONT_FAMILY, 'Regular')
|
||||
if (fontData) {
|
||||
const typeface = this.ck.Typeface.MakeFreeTypeFaceFromData(fontData)
|
||||
if (typeface) {
|
||||
|
|
@ -1964,7 +1965,7 @@ export class SkiaRenderer {
|
|||
|
||||
isNodeFontLoaded(node: SceneNode): boolean {
|
||||
const families = new Set<string>()
|
||||
families.add(node.fontFamily || 'Inter')
|
||||
families.add(node.fontFamily || DEFAULT_FONT_FAMILY)
|
||||
for (const run of node.styleRuns) {
|
||||
if (run.style.fontFamily) families.add(run.style.fontFamily)
|
||||
}
|
||||
|
|
@ -2001,7 +2002,7 @@ export class SkiaRenderer {
|
|||
textAlign: this.getTextAlign(node.textAlignHorizontal),
|
||||
textStyle: {
|
||||
color: baseColor,
|
||||
fontFamilies: [node.fontFamily || 'Inter'],
|
||||
fontFamilies: [node.fontFamily || DEFAULT_FONT_FAMILY],
|
||||
fontSize: baseFontSize,
|
||||
fontStyle: {
|
||||
weight: { value: node.fontWeight || 400 } as FontWeight,
|
||||
|
|
@ -2029,7 +2030,7 @@ export class SkiaRenderer {
|
|||
builder.pushStyle(
|
||||
new ck.TextStyle({
|
||||
color: baseColor,
|
||||
fontFamilies: [s.fontFamily ?? (node.fontFamily || 'Inter')],
|
||||
fontFamilies: [s.fontFamily ?? (node.fontFamily || DEFAULT_FONT_FAMILY)],
|
||||
fontSize: s.fontSize ?? baseFontSize,
|
||||
fontStyle: {
|
||||
weight: { value: (s.fontWeight ?? node.fontWeight) || 400 } as FontWeight,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BLACK, DEFAULT_STROKE_MITER_LIMIT } from './constants'
|
||||
import { BLACK, DEFAULT_FONT_FAMILY, DEFAULT_STROKE_MITER_LIMIT } from './constants'
|
||||
|
||||
export type { GUID, Color } from './types'
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ function createDefaultNode(type: NodeType, overrides: Partial<SceneNode> = {}):
|
|||
clipsContent: false,
|
||||
text: '',
|
||||
fontSize: 14,
|
||||
fontFamily: 'Inter',
|
||||
fontFamily: DEFAULT_FONT_FAMILY,
|
||||
fontWeight: 400,
|
||||
italic: false,
|
||||
textAlignHorizontal: 'LEFT',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { isFontLoaded } from '@open-pencil/core'
|
||||
import { isFontLoaded, DEFAULT_FONT_FAMILY } from '@open-pencil/core'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import type { SceneNode } from '@open-pencil/core'
|
||||
|
|
@ -9,7 +9,7 @@ export function useNodeFontStatus(node: () => SceneNode) {
|
|||
if (n.type !== 'TEXT') return []
|
||||
|
||||
const families = new Set<string>()
|
||||
families.add(n.fontFamily || 'Inter')
|
||||
families.add(n.fontFamily || DEFAULT_FONT_FAMILY)
|
||||
for (const run of n.styleRuns) {
|
||||
if (run.style.fontFamily) families.add(run.style.fontFamily)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export {
|
|||
PEN_PATH_STROKE_WIDTH,
|
||||
PARENT_OUTLINE_ALPHA,
|
||||
PARENT_OUTLINE_DASH,
|
||||
DEFAULT_FONT_FAMILY,
|
||||
DEFAULT_FONT_SIZE,
|
||||
LABEL_FONT_SIZE,
|
||||
SIZE_FONT_SIZE,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import {
|
|||
CANVAS_BG_COLOR,
|
||||
ZOOM_DIVISOR,
|
||||
ZOOM_SCALE_MIN,
|
||||
ZOOM_SCALE_MAX
|
||||
ZOOM_SCALE_MAX,
|
||||
DEFAULT_FONT_FAMILY
|
||||
} from '@/constants'
|
||||
import {
|
||||
parseFigmaClipboard,
|
||||
|
|
@ -27,6 +28,7 @@ import { SceneGraph } from '@/engine/scene-graph'
|
|||
import { TextEditor } from '@/engine/text-editor'
|
||||
import { UndoManager } from '@/engine/undo'
|
||||
import { computeVectorBounds } from '@/engine/vector'
|
||||
import { loadFont } from '@/engine/fonts'
|
||||
import { readFigFile } from '@/kiwi/fig-file'
|
||||
|
||||
import type { ExportFormat } from '@/engine/render-image'
|
||||
|
|
@ -584,6 +586,7 @@ export function createEditorStore() {
|
|||
state.panY = 0
|
||||
state.zoom = 1
|
||||
state.pageColor = { ...CANVAS_BG_COLOR }
|
||||
loadFontsForNodes(graph.getChildren(firstPage?.id ?? graph.rootId).map((n) => n.id))
|
||||
requestRender()
|
||||
startWatchingFile()
|
||||
} catch (e) {
|
||||
|
|
@ -1691,6 +1694,26 @@ export function createEditorStore() {
|
|||
return result
|
||||
}
|
||||
|
||||
function loadFontsForNodes(nodeIds: string[]) {
|
||||
const families = new Set<string>()
|
||||
const collect = (id: string) => {
|
||||
const node = graph.getNode(id)
|
||||
if (!node) return
|
||||
if (node.type === 'TEXT') {
|
||||
families.add(node.fontFamily || DEFAULT_FONT_FAMILY)
|
||||
for (const run of node.styleRuns) {
|
||||
if (run.style.fontFamily) families.add(run.style.fontFamily)
|
||||
}
|
||||
}
|
||||
for (const childId of node.childIds) collect(childId)
|
||||
}
|
||||
for (const id of nodeIds) collect(id)
|
||||
families.delete(DEFAULT_FONT_FAMILY)
|
||||
if (families.size === 0) return
|
||||
const promises = [...families].map((f) => loadFont(f))
|
||||
Promise.all(promises).then(() => requestRender())
|
||||
}
|
||||
|
||||
function pasteFromHTML(html: string) {
|
||||
const ownNodes = parseOpenPencilClipboard(html)
|
||||
if (ownNodes) {
|
||||
|
|
@ -1741,6 +1764,7 @@ export function createEditorStore() {
|
|||
requestRender()
|
||||
}
|
||||
})
|
||||
loadFontsForNodes(created)
|
||||
requestRender()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue