diff --git a/package.json b/package.json index 07de86c0d2..ab191652fc 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@types/node": "16.11.7", "clang-format": "1.6.0", "rimraf": "3.0.2", + "ts-morph": "^23.0.0", "ts-node": "10.4.0", "typescript": "5.3.3" }, @@ -29,7 +30,8 @@ "clang-format-common": "find package/cpp/ -iname *.h -o -iname *.m -o -iname *.cpp | xargs clang-format -i", "workflow-copy-libs": "yarn ts-node ./scripts/workflow-copy-libs.ts", "bootstrap": "yarn && cd ./package && yarn && cd .. && cd ./example && yarn && cd .. && cd ./fabricexample && yarn && cd ..", - "cpplint": "cpplint --linelength=230 --filter=-legal/copyright,-whitespace/indent,-whitespace/comments,-whitespace/ending_newline,-build/include_order,-runtime/references,-readability/todo,-whitespace/blank_line,-whitespace/todo,-runtime/int,-build/c++11,-whitespace/parens --exclude=package/cpp/skia --exclude=package/ios --exclude=package/android/build --exclude=package/node_modules --recursive package" + "cpplint": "cpplint --linelength=230 --filter=-legal/copyright,-whitespace/indent,-whitespace/comments,-whitespace/ending_newline,-build/include_order,-runtime/references,-readability/todo,-whitespace/blank_line,-whitespace/todo,-runtime/int,-build/c++11,-whitespace/parens --exclude=package/cpp/skia --exclude=package/ios --exclude=package/android/build --exclude=package/node_modules --recursive package", + "codegen": "yarn ts-node ./scripts/codegen.ts" }, "license": "MIT", "licenseFilename": "LICENSE.md", diff --git a/package/src/dom/nodes/datatypes/Circle.ts b/package/src/dom/nodes/datatypes/Circle.ts index 6fc473b19a..18db2da3eb 100644 --- a/package/src/dom/nodes/datatypes/Circle.ts +++ b/package/src/dom/nodes/datatypes/Circle.ts @@ -1,12 +1,15 @@ import type { Skia } from "../../../skia/types"; import type { CircleDef, ScalarCircleDef } from "../../types"; -export const isCircleScalarDef = (def: CircleDef): def is ScalarCircleDef => +export const isCircleScalarDef = (def: CircleDef): def is ScalarCircleDef => { + "worklet"; // We have an issue to check property existence on JSI backed instances // eslint-disable-next-line @typescript-eslint/no-explicit-any - (def as any).cx !== undefined; + return (def as any).cx !== undefined; +}; export const processCircle = (Skia: Skia, def: CircleDef) => { + "worklet"; if (isCircleScalarDef(def)) { return { c: Skia.Point(def.cx, def.cy), r: def.r }; } diff --git a/package/src/dom/nodes/datatypes/Enum.ts b/package/src/dom/nodes/datatypes/Enum.ts index 361c589fa8..1184e523d1 100644 --- a/package/src/dom/nodes/datatypes/Enum.ts +++ b/package/src/dom/nodes/datatypes/Enum.ts @@ -1,2 +1,4 @@ -export const enumKey = (k: K) => - (k.charAt(0).toUpperCase() + k.slice(1)) as Capitalize; +export const enumKey = (k: K) => { + "worklet"; + return (k.charAt(0).toUpperCase() + k.slice(1)) as Capitalize; +}; diff --git a/package/src/dom/nodes/datatypes/Path.ts b/package/src/dom/nodes/datatypes/Path.ts index 547839efec..da2fbe6b9d 100644 --- a/package/src/dom/nodes/datatypes/Path.ts +++ b/package/src/dom/nodes/datatypes/Path.ts @@ -3,6 +3,7 @@ import { isPath } from "../../../skia/types"; import type { PathDef } from "../../types"; export const processPath = (Skia: Skia, rawPath: PathDef) => { + "worklet"; const path = typeof rawPath === "string" ? Skia.Path.MakeFromSVGString(rawPath) @@ -14,5 +15,7 @@ export const processPath = (Skia: Skia, rawPath: PathDef) => { }; // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const isPathDef = (def: any): def is PathDef => - typeof def === "string" || isPath(def); +export const isPathDef = (def: any): def is PathDef => { + "worklet"; + return typeof def === "string" || isPath(def); +}; diff --git a/package/src/dom/nodes/datatypes/Rect.ts b/package/src/dom/nodes/datatypes/Rect.ts index a93c97d4c9..eee892680b 100644 --- a/package/src/dom/nodes/datatypes/Rect.ts +++ b/package/src/dom/nodes/datatypes/Rect.ts @@ -12,13 +12,19 @@ export const isEdge = (pos: Vector, b: SkRect) => { }; // We have an issue to check property existence on JSI backed instances -const isRRectCtor = (def: RRectDef): def is RRectCtor => - (def as any).rect === undefined; +const isRRectCtor = (def: RRectDef): def is RRectCtor => { + "worklet"; + return (def as any).rect === undefined; +}; + // We have an issue to check property existence on JSI backed instances -const isRectCtor = (def: RectDef): def is RectCtor => - (def as any).rect === undefined; +const isRectCtor = (def: RectDef): def is RectCtor => { + "worklet"; + return (def as any).rect === undefined; +}; export const processRect = (Skia: Skia, def: RectDef) => { + "worklet"; if (isRectCtor(def)) { return Skia.XYWHRect(def.x ?? 0, def.y ?? 0, def.width, def.height); } else { @@ -27,6 +33,7 @@ export const processRect = (Skia: Skia, def: RectDef) => { }; export const processRRect = (Skia: Skia, def: RRectDef) => { + "worklet"; if (isRRectCtor(def)) { const r = processRadius(Skia, def.r ?? 0); return Skia.RRectXY( diff --git a/package/src/sg/ColorFilters.ts b/package/src/sg/ColorFilters.ts new file mode 100644 index 0000000000..9fedc245c5 --- /dev/null +++ b/package/src/sg/ColorFilters.ts @@ -0,0 +1,48 @@ +import type { + BlendColorFilterProps, + ChildrenProps, + LerpColorFilterProps, + MatrixColorFilterProps, +} from "../dom/types"; + +import type { DrawingContext } from "./Context"; + +export const renderMatrixColorFilter = ( + _ctx: DrawingContext, + _props: MatrixColorFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderBlendColorFilter = ( + _ctx: DrawingContext, + _props: BlendColorFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderLinearToSRGBGammaColorFilter = ( + _ctx: DrawingContext, + _props: ChildrenProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderSRGBToLinearGammaColorFilter = ( + _ctx: DrawingContext, + _props: ChildrenProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderLerpColorFilter = ( + _ctx: DrawingContext, + _props: LerpColorFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; diff --git a/package/src/sg/Context.ts b/package/src/sg/Context.ts new file mode 100644 index 0000000000..8668f8c655 --- /dev/null +++ b/package/src/sg/Context.ts @@ -0,0 +1,45 @@ +import type { GroupProps } from "../dom/types"; +import { + processTransform3d, + type SkCanvas, + type SkPaint, + type Skia, +} from "../skia/types"; + +export interface PaintingContext { + paints: SkPaint[]; + // maskFilters: SkMaskFilter[]; + // shaders: SkShader[]; + // pathEffects: SkPathEffect[]; + // imageFilters: SkImageFilter[]; + // colorFilters: SkColorFilter[]; +} + +export interface DrawingContext extends PaintingContext { + Skia: Skia; + canvas: SkCanvas; +} + +export const getPaint = (ctx: DrawingContext) => { + "worklet"; + return ctx.paints[ctx.paints.length - 1]; +}; + +export const processContext = (ctx: DrawingContext, props: GroupProps) => { + "worklet"; + let restore = false; + if (props.matrix) { + ctx.canvas.save(); + ctx.canvas.concat(props.matrix); + restore = true; + } else if (props.transform) { + ctx.canvas.save(); + ctx.canvas.concat(processTransform3d(props.transform)); + restore = true; + } + if (props.color) { + const paint = getPaint(ctx); + paint.setColor(ctx.Skia.Color(props.color)); + } + return { restore }; +}; diff --git a/package/src/sg/Drawing.ts b/package/src/sg/Drawing.ts new file mode 100644 index 0000000000..ecf2e2e53f --- /dev/null +++ b/package/src/sg/Drawing.ts @@ -0,0 +1,267 @@ +import type { + AtlasProps, + CircleProps, + DiffRectProps, + ImageProps, + ImageSVGProps, + LineProps, + OvalProps, + PatchProps, + PathProps, + PictureProps, + PointsProps, + RectProps, + RoundedRectProps, + VerticesProps, + ChildrenProps, + PaintProps, + DrawingNodeProps, +} from "../dom/nodes"; +import { + enumKey, + fitRects, + processCircle, + processPath, + processRRect, + processRect, +} from "../dom/nodes"; +import { saturate } from "../renderer"; +import { BlendMode, FillType, PointMode, VertexMode } from "../skia/types"; +import type { Skia } from "../skia/types"; + +import { getPaint, type DrawingContext } from "./Context"; + +export const renderCircle = (ctx: DrawingContext, props: CircleProps) => { + "worklet"; + const { c, r } = processCircle(ctx.Skia, props); + const paint = getPaint(ctx); + ctx.canvas.drawCircle(c.x, c.y, r, paint); +}; + +export const renderFill = (ctx: DrawingContext, _props: DrawingNodeProps) => { + "worklet"; + const paint = getPaint(ctx); + ctx.canvas.drawPaint(paint); +}; + +export const renderPoints = (ctx: DrawingContext, props: PointsProps) => { + "worklet"; + const { points, mode } = props; + const paint = getPaint(ctx); + ctx.canvas.drawPoints(PointMode[enumKey(mode)], points, paint); +}; + +const computePath = (ctx: DrawingContext, props: PathProps) => { + "worklet"; + const { + start: trimStart, + end: trimEnd, + fillType, + stroke, + ...pathProps + } = props; + const start = saturate(trimStart); + const end = saturate(trimEnd); + const hasStartOffset = start !== 0; + const hasEndOffset = end !== 1; + const hasStrokeOptions = stroke !== undefined; + const hasFillType = !!fillType; + const willMutatePath = + hasStartOffset || hasEndOffset || hasStrokeOptions || hasFillType; + const pristinePath = processPath(ctx.Skia, pathProps.path); + const path = willMutatePath ? pristinePath.copy() : pristinePath; + if (hasFillType) { + path.setFillType(FillType[enumKey(fillType)]); + } + if (hasStrokeOptions) { + path.stroke(stroke); + } + if (hasStartOffset || hasEndOffset) { + path.trim(start, end, false); + } + return path; +}; + +export const renderPath = (ctx: DrawingContext, props: PathProps) => { + "worklet"; + const path = computePath(ctx, props); + const paint = getPaint(ctx); + ctx.canvas.drawPath(path, paint); +}; + +export const renderRect = (ctx: DrawingContext, props: RectProps) => { + "worklet"; + const rect = processRect(ctx.Skia, props); + const paint = getPaint(ctx); + ctx.canvas.drawRect(rect, paint); +}; + +export const renderRRect = (ctx: DrawingContext, props: RoundedRectProps) => { + "worklet"; + const rrect = processRRect(ctx.Skia, props); + const paint = getPaint(ctx); + ctx.canvas.drawRRect(rrect, paint); +}; + +export const renderOval = (ctx: DrawingContext, props: OvalProps) => { + "worklet"; + const oval = processRect(ctx.Skia, props); + const paint = getPaint(ctx); + ctx.canvas.drawOval(oval, paint); +}; + +const processImage = (Skia: Skia, props: ImageProps) => { + "worklet"; + const { image } = props; + if (!image) { + return { + src: { x: 0, y: 0, width: 0, height: 0 }, + dst: { x: 0, y: 0, width: 0, height: 0 }, + }; + } + const fit = props.fit ?? "contain"; + const rect = processRect(Skia, props); + const { src, dst } = fitRects( + fit, + { + x: 0, + y: 0, + width: image.width(), + height: image.height(), + }, + rect + ); + return { src, dst }; +}; + +export const renderImage = (ctx: DrawingContext, props: ImageProps) => { + "worklet"; + const { image } = props; + const { src, dst } = processImage(ctx.Skia, props); + if (!image) { + return; + } + const paint = getPaint(ctx); + ctx.canvas.drawImageRect(image, src, dst, paint); +}; + +export const renderLine = (ctx: DrawingContext, props: LineProps) => { + "worklet"; + const { p1, p2 } = props; + const paint = getPaint(ctx); + ctx.canvas.drawLine(p1.x, p1.y, p2.x, p2.y, paint); +}; + +const processPatch = (Skia: Skia, props: PatchProps) => { + "worklet"; + const { colors, blendMode, patch } = props; + const defaultBlendMode = colors ? BlendMode.DstOver : BlendMode.SrcOver; + const mode = blendMode ? BlendMode[enumKey(blendMode)] : defaultBlendMode; + // Patch requires a path with the following constraints: + // M tl + // C c1 c2 br + // C c1 c2 bl + // C c1 c2 tl (the redundant point in the last command is removed) + return { + mode, + points: [ + patch[0].pos, + patch[0].c2, + patch[1].c1, + patch[1].pos, + patch[1].c2, + patch[2].c1, + patch[2].pos, + patch[2].c2, + patch[3].c1, + patch[3].pos, + patch[3].c2, + patch[0].c1, + ], + colors: colors ? colors.map((c) => Skia.Color(c)) : undefined, + }; +}; + +export const renderPatch = (ctx: DrawingContext, props: PatchProps) => { + "worklet"; + const { texture } = props; + const { colors, points, mode } = processPatch(ctx.Skia, props); + const paint = getPaint(ctx); + ctx.canvas.drawPatch(points, colors, texture, mode, paint); +}; + +export const renderVertices = (ctx: DrawingContext, props: VerticesProps) => { + "worklet"; + const { colors, blendMode } = props; + const defaultBlendMode = colors ? BlendMode.DstOver : BlendMode.SrcOver; + const blend = blendMode ? BlendMode[enumKey(blendMode)] : defaultBlendMode; + const { mode, vertices, textures, indices } = props; + const vertexMode = mode ? VertexMode[enumKey(mode)] : VertexMode.Triangles; + const vert = ctx.Skia.MakeVertices( + vertexMode, + vertices, + textures, + colors ? colors.map((c) => ctx.Skia.Color(c)) : undefined, + indices + ); + const paint = getPaint(ctx); + ctx.canvas.drawVertices(vert, blend, paint); +}; + +export const renderDiffRect = (ctx: DrawingContext, props: DiffRectProps) => { + "worklet"; + const { outer, inner } = props; + const paint = getPaint(ctx); + ctx.canvas.drawDRRect(outer, inner, paint); +}; + +export const renderPicture = (ctx: DrawingContext, props: PictureProps) => { + "worklet"; + const { picture } = props; + ctx.canvas.drawPicture(picture); +}; + +const processImageSVG = (props: ImageSVGProps) => { + "worklet"; + if (props.rect) { + return props.rect; + } + const { x, y, width, height } = props; + return { x, y, width, height }; +}; + +export const renderImageSVG = (ctx: DrawingContext, props: ImageSVGProps) => { + "worklet"; + const { svg } = props; + + const { x, y, width, height } = processImageSVG(props); + if (svg === null) { + return; + } + ctx.canvas.save(); + if (x && y) { + ctx.canvas.translate(x, y); + } + ctx.canvas.drawSvg(svg, width, height); + ctx.canvas.restore(); +}; + +export const renderAtlas = (ctx: DrawingContext, props: AtlasProps) => { + "worklet"; + const { image, sprites, transforms, colors, blendMode } = props; + const blend = blendMode ? BlendMode[enumKey(blendMode)] : undefined; + if (image) { + const paint = getPaint(ctx); + ctx.canvas.drawAtlas(image, sprites, transforms, paint, blend, colors); + } +}; + +export const renderLayer = (_ctx: DrawingContext, _props: ChildrenProps) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderPaint = (_ctx: DrawingContext, _props: PaintProps) => { + "worklet"; + throw new Error("Not implemented"); +}; diff --git a/package/src/sg/ImageFilters.ts b/package/src/sg/ImageFilters.ts new file mode 100644 index 0000000000..6e53673886 --- /dev/null +++ b/package/src/sg/ImageFilters.ts @@ -0,0 +1,76 @@ +import type { + BlendImageFilterProps, + BlurImageFilterProps, + ChildrenProps, + DisplacementMapImageFilterProps, + DropShadowImageFilterProps, + MorphologyImageFilterProps, + OffsetImageFilterProps, + RuntimeShaderImageFilterProps, +} from "../dom/types"; + +import type { DrawingContext } from "./Context"; + +export const renderBlendImageFilter = ( + _ctx: DrawingContext, + _props: BlendImageFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderBlurImageFilter = ( + _ctx: DrawingContext, + _props: BlurImageFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderOffsetImageFilter = ( + _ctx: DrawingContext, + _props: OffsetImageFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderDropShadowImageFilter = ( + _ctx: DrawingContext, + _props: DropShadowImageFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderDisplacementMapImageFilter = ( + _ctx: DrawingContext, + _props: DisplacementMapImageFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderRuntimeShaderImageFilter = ( + _ctx: DrawingContext, + _props: RuntimeShaderImageFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderMorphologyImageFilter = ( + _ctx: DrawingContext, + _props: MorphologyImageFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderLumaColorFilter = ( + _ctx: DrawingContext, + _props: ChildrenProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; diff --git a/package/src/sg/MaskFilters.ts b/package/src/sg/MaskFilters.ts new file mode 100644 index 0000000000..ffcc230d8d --- /dev/null +++ b/package/src/sg/MaskFilters.ts @@ -0,0 +1,11 @@ +import type { BlurMaskFilterProps } from "../dom/types"; + +import type { DrawingContext } from "./Context"; + +export const renderBlurMaskFilter = ( + _ctx: DrawingContext, + _props: BlurMaskFilterProps +) => { + "worklet"; + console.warn("Not implemented"); +}; diff --git a/package/src/sg/Mixed.ts b/package/src/sg/Mixed.ts new file mode 100644 index 0000000000..dddccc55c1 --- /dev/null +++ b/package/src/sg/Mixed.ts @@ -0,0 +1,30 @@ +import type { BlendProps, BoxProps, BoxShadowProps } from "../dom/types"; +import type { BackdropFilterProps } from "../renderer"; + +import type { DrawingContext } from "./Context"; + +export const renderBlend = (_ctx: DrawingContext, _props: BlendProps) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderBackdropFilter = ( + _ctx: DrawingContext, + _props: BackdropFilterProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderBox = (_ctx: DrawingContext, _props: BoxProps) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderBoxShadow = ( + _ctx: DrawingContext, + _props: BoxShadowProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; diff --git a/package/src/sg/Node.ts b/package/src/sg/Node.ts new file mode 100644 index 0000000000..d44856ae47 --- /dev/null +++ b/package/src/sg/Node.ts @@ -0,0 +1,134 @@ +import type { + ChildrenProps, + DrawingNodeProps, + GroupProps, + PaintProps, + ImageProps, + CircleProps, + PathProps, + LineProps, + OvalProps, + PatchProps, + PointsProps, + RectProps, + RoundedRectProps, + AtlasProps, + VerticesProps, + TextProps, + TextPathProps, + TextBlobProps, + GlyphsProps, + DiffRectProps, + PictureProps, + ImageSVGProps, + BlurMaskFilterProps, + BlendImageFilterProps, + BlurImageFilterProps, + OffsetImageFilterProps, + DropShadowImageFilterProps, + DisplacementMapImageFilterProps, + RuntimeShaderImageFilterProps, + MorphologyImageFilterProps, + MatrixColorFilterProps, + BlendColorFilterProps, + LerpColorFilterProps, + ShaderProps, + ImageShaderProps, + TurbulenceProps, + FractalNoiseProps, + LinearGradientProps, + RadialGradientProps, + SweepGradientProps, + TwoPointConicalGradientProps, + DiscretePathEffectProps, + DashPathEffectProps, + Path1DPathEffectProps, + Path2DPathEffectProps, + CornerPathEffectProps, + Line2DPathEffectProps, + BlendProps, + BoxProps, + BoxShadowProps, + ParagraphProps, + ColorProps, + NodeType, +} from "../dom/types"; +import type { AnimatedProps, BackdropFilterProps } from "../renderer"; + +export interface PropMap { + [NodeType.Group]: GroupProps; + [NodeType.Layer]: ChildrenProps; + [NodeType.Paint]: PaintProps; + [NodeType.Fill]: DrawingNodeProps; + [NodeType.Image]: ImageProps; + [NodeType.Circle]: CircleProps; + [NodeType.Path]: PathProps; + [NodeType.Line]: LineProps; + [NodeType.Oval]: OvalProps; + [NodeType.Patch]: PatchProps; + [NodeType.Points]: PointsProps; + [NodeType.Rect]: RectProps; + [NodeType.RRect]: RoundedRectProps; + [NodeType.Atlas]: AtlasProps; + [NodeType.Vertices]: VerticesProps; + [NodeType.Text]: TextProps; + [NodeType.TextPath]: TextPathProps; + [NodeType.TextBlob]: TextBlobProps; + [NodeType.Glyphs]: GlyphsProps; + [NodeType.DiffRect]: DiffRectProps; + [NodeType.Picture]: PictureProps; + [NodeType.ImageSVG]: ImageSVGProps; + [NodeType.BlurMaskFilter]: BlurMaskFilterProps; + [NodeType.BlendImageFilter]: BlendImageFilterProps; + [NodeType.BlurImageFilter]: BlurImageFilterProps; + [NodeType.OffsetImageFilter]: OffsetImageFilterProps; + [NodeType.DropShadowImageFilter]: DropShadowImageFilterProps; + [NodeType.DisplacementMapImageFilter]: DisplacementMapImageFilterProps; + [NodeType.RuntimeShaderImageFilter]: RuntimeShaderImageFilterProps; + [NodeType.MorphologyImageFilter]: MorphologyImageFilterProps; + [NodeType.MatrixColorFilter]: MatrixColorFilterProps; + [NodeType.BlendColorFilter]: BlendColorFilterProps; + [NodeType.LinearToSRGBGammaColorFilter]: ChildrenProps; + [NodeType.SRGBToLinearGammaColorFilter]: ChildrenProps; + [NodeType.LumaColorFilter]: ChildrenProps; + [NodeType.LerpColorFilter]: LerpColorFilterProps; + [NodeType.Shader]: ShaderProps; + [NodeType.ImageShader]: ImageShaderProps; + [NodeType.ColorShader]: ColorProps; + [NodeType.Turbulence]: TurbulenceProps; + [NodeType.FractalNoise]: FractalNoiseProps; + [NodeType.LinearGradient]: LinearGradientProps; + [NodeType.RadialGradient]: RadialGradientProps; + [NodeType.SweepGradient]: SweepGradientProps; + [NodeType.TwoPointConicalGradient]: TwoPointConicalGradientProps; + [NodeType.DiscretePathEffect]: DiscretePathEffectProps; + [NodeType.DashPathEffect]: DashPathEffectProps; + [NodeType.Path1DPathEffect]: Path1DPathEffectProps; + [NodeType.Path2DPathEffect]: Path2DPathEffectProps; + [NodeType.CornerPathEffect]: CornerPathEffectProps; + [NodeType.SumPathEffect]: ChildrenProps; + [NodeType.Line2DPathEffect]: Line2DPathEffectProps; + [NodeType.Blend]: BlendProps; + [NodeType.BackdropFilter]: BackdropFilterProps; + [NodeType.Box]: BoxProps; + [NodeType.BoxShadow]: BoxShadowProps; + [NodeType.Paragraph]: ParagraphProps; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type UnknownProps = Record; + +export interface SGNode

{ + type: NodeType; + props: AnimatedProps

; + children?: SGNode[]; +} + +export const createNode = ( + type: T, + props: AnimatedProps, + children?: SGNode[] +): SGNode => { + "worklet"; + return { type, props, children }; +}; diff --git a/package/src/sg/Paragraph.ts b/package/src/sg/Paragraph.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package/src/sg/PathEffects.ts b/package/src/sg/PathEffects.ts new file mode 100644 index 0000000000..48865c8fca --- /dev/null +++ b/package/src/sg/PathEffects.ts @@ -0,0 +1,67 @@ +import type { + ChildrenProps, + CornerPathEffectProps, + DashPathEffectProps, + DiscretePathEffectProps, + Line2DPathEffectProps, + Path1DPathEffectProps, + Path2DPathEffectProps, +} from "../dom/types"; + +import type { DrawingContext } from "./Context"; + +export const renderDiscretePathEffect = ( + _ctx: DrawingContext, + _props: DiscretePathEffectProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderDashPathEffect = ( + _ctx: DrawingContext, + _props: DashPathEffectProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderPath1DPathEffect = ( + _ctx: DrawingContext, + _props: Path1DPathEffectProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderPath2DPathEffect = ( + _ctx: DrawingContext, + _props: Path2DPathEffectProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderCornerPathEffect = ( + _ctx: DrawingContext, + _props: CornerPathEffectProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderSumPathEffect = ( + _ctx: DrawingContext, + _props: ChildrenProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderLine2DPathEffect = ( + _ctx: DrawingContext, + _props: Line2DPathEffectProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; diff --git a/package/src/sg/Renderer.ts b/package/src/sg/Renderer.ts new file mode 100644 index 0000000000..bd4f208187 --- /dev/null +++ b/package/src/sg/Renderer.ts @@ -0,0 +1,346 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { NodeType } from "../dom/types"; +import type { AnimatedProps } from "../renderer"; +import { exhaustiveCheck } from "../renderer/typeddash"; + +import { processContext, type DrawingContext } from "./Context"; +import { + renderAtlas, + renderCircle, + renderDiffRect, + renderFill, + renderImage, + renderImageSVG, + renderLayer, + renderLine, + renderOval, + renderPaint, + renderPatch, + renderPath, + renderPicture, + renderPoints, + renderRRect, + renderRect, + renderVertices, +} from "./Drawing"; +import type { PropMap, SGNode } from "./Node"; +import { + renderGlyphs, + renderParagraph, + renderText, + renderTextBlob, + renderTextPath, +} from "./Text"; +import { renderBlurMaskFilter } from "./MaskFilters"; +import { + renderBlendImageFilter, + renderBlurImageFilter, + renderDisplacementMapImageFilter, + renderDropShadowImageFilter, + renderLumaColorFilter, + renderMorphologyImageFilter, + renderOffsetImageFilter, + renderRuntimeShaderImageFilter, +} from "./ImageFilters"; +import { + renderBlendColorFilter, + renderLerpColorFilter, + renderLinearToSRGBGammaColorFilter, + renderMatrixColorFilter, + renderSRGBToLinearGammaColorFilter, +} from "./ColorFilters"; +import { + renderColorShader, + renderFractalNoise, + renderImageShader, + renderLinearGradient, + renderRadialGradient, + renderShader, + renderSweepGradient, + renderTurbulence, + renderTwoPointConicalGradient, +} from "./Shaders"; +import { + renderCornerPathEffect, + renderDashPathEffect, + renderDiscretePathEffect, + renderLine2DPathEffect, + renderPath1DPathEffect, + renderPath2DPathEffect, + renderSumPathEffect, +} from "./PathEffects"; +import { + renderBackdropFilter, + renderBlend, + renderBox, + renderBoxShadow, +} from "./Mixed"; + +const isSharedValueKind = (value: unknown): value is { value: unknown } => { + "worklet"; + return typeof value === "object" && value !== null && "value" in value; +}; + +const materialize =

(props: AnimatedProps

) => { + "worklet"; + const materializedProps: Record = {}; + for (const key in props) { + const value = props[key]; + if (isSharedValueKind(value)) { + materializedProps[key] = value.value; + } else { + materializedProps[key] = value; + } + } + return materializedProps as any; +}; + +export const renderNode = (ctx: DrawingContext, node: SGNode) => { + "worklet"; + const materializedProps = materialize(node.props) as unknown; + let restore = false; + switch (node.type) { + case NodeType.Group: + const result = processContext( + ctx, + materializedProps as PropMap[typeof node.type] + ); + // eslint-disable-next-line prefer-destructuring + restore = result.restore; + node.children?.forEach((child) => renderNode(ctx, child)); + break; + case NodeType.Layer: + renderLayer(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Paint: + renderPaint(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Fill: + renderFill(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Image: + renderImage(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Circle: + renderCircle(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Path: + renderPath(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Line: + renderLine(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Oval: + renderOval(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Patch: + renderPatch(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Points: + renderPoints(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Rect: + renderRect(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.RRect: + renderRRect(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Atlas: + renderAtlas(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Vertices: + renderVertices(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Text: + renderText(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.TextPath: + renderTextPath(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.TextBlob: + renderTextBlob(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Glyphs: + renderGlyphs(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.DiffRect: + renderDiffRect(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Picture: + renderPicture(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.ImageSVG: + renderImageSVG(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.BlurMaskFilter: + renderBlurMaskFilter(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.BlendImageFilter: + renderBlendImageFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.BlurImageFilter: + renderBlurImageFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.OffsetImageFilter: + renderOffsetImageFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.DropShadowImageFilter: + renderDropShadowImageFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.DisplacementMapImageFilter: + renderDisplacementMapImageFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.RuntimeShaderImageFilter: + renderRuntimeShaderImageFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.MorphologyImageFilter: + renderMorphologyImageFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.MatrixColorFilter: + renderMatrixColorFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.BlendColorFilter: + renderBlendColorFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.LinearToSRGBGammaColorFilter: + renderLinearToSRGBGammaColorFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.SRGBToLinearGammaColorFilter: + renderSRGBToLinearGammaColorFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.LumaColorFilter: + renderLumaColorFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.LerpColorFilter: + renderLerpColorFilter( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.Shader: + renderShader(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.ImageShader: + renderImageShader(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.ColorShader: + renderColorShader(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Turbulence: + renderTurbulence(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.FractalNoise: + renderFractalNoise(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.LinearGradient: + renderLinearGradient(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.RadialGradient: + renderRadialGradient(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.SweepGradient: + renderSweepGradient(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.TwoPointConicalGradient: + renderTwoPointConicalGradient( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.DiscretePathEffect: + renderDiscretePathEffect( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.DashPathEffect: + renderDashPathEffect(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Path1DPathEffect: + renderPath1DPathEffect( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.Path2DPathEffect: + renderPath2DPathEffect( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.CornerPathEffect: + renderCornerPathEffect( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.SumPathEffect: + renderSumPathEffect(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Line2DPathEffect: + renderLine2DPathEffect( + ctx, + materializedProps as PropMap[typeof node.type] + ); + break; + case NodeType.Blend: + renderBlend(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.BackdropFilter: + renderBackdropFilter(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Box: + renderBox(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.BoxShadow: + renderBoxShadow(ctx, materializedProps as PropMap[typeof node.type]); + break; + case NodeType.Paragraph: + renderParagraph(ctx, materializedProps as PropMap[typeof node.type]); + break; + default: + return exhaustiveCheck(node.type); + } + if (restore) { + ctx.canvas.restore(); + } + // if (restorePaint) { + // //ctx.paint.restore(); + // } +}; diff --git a/package/src/sg/Shaders.ts b/package/src/sg/Shaders.ts new file mode 100644 index 0000000000..fe2ace6273 --- /dev/null +++ b/package/src/sg/Shaders.ts @@ -0,0 +1,78 @@ +import type { + ColorProps, + ImageShaderProps, + LinearGradientProps, + RadialGradientProps, + ShaderProps, + SweepGradientProps, + TurbulenceProps, + TwoPointConicalGradientProps, +} from "../dom/types"; + +import type { DrawingContext } from "./Context"; + +export const renderShader = (_ctx: DrawingContext, _props: ShaderProps) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderImageShader = ( + _ctx: DrawingContext, + _props: ImageShaderProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderColorShader = (_ctx: DrawingContext, _props: ColorProps) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderTurbulence = ( + _ctx: DrawingContext, + _props: TurbulenceProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderFractalNoise = ( + _ctx: DrawingContext, + _props: TurbulenceProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderLinearGradient = ( + _ctx: DrawingContext, + _props: LinearGradientProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderRadialGradient = ( + _ctx: DrawingContext, + _props: RadialGradientProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderSweepGradient = ( + _ctx: DrawingContext, + _props: SweepGradientProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; + +export const renderTwoPointConicalGradient = ( + _ctx: DrawingContext, + _props: TwoPointConicalGradientProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; diff --git a/package/src/sg/Text.ts b/package/src/sg/Text.ts new file mode 100644 index 0000000000..215998253e --- /dev/null +++ b/package/src/sg/Text.ts @@ -0,0 +1,45 @@ +import type { + GlyphsProps, + ParagraphProps, + TextBlobProps, + TextPathProps, + TextProps, +} from "../dom/types"; + +import type { DrawingContext } from "./Context"; + +export const renderText = (_ctx: DrawingContext, _props: TextProps) => { + "worklet"; + // const { text, x, y, font } = processText(ctx.Skia, props); + // ctx.canvas.drawText(text, x, y, font, ctx.paint); + throw new Error("Not implemented"); +}; + +export const renderTextPath = (_ctx: DrawingContext, _props: TextPathProps) => { + "worklet"; + // const { text, path, font } = processTextPath(ctx.Skia, props); + // ctx.canvas.drawTextOnPath(text, path, font, ctx.paint); + throw new Error("Not implemented"); +}; + +export const renderTextBlob = (_ctx: DrawingContext, _props: TextBlobProps) => { + "worklet"; + // const { textBlob, x, y } = processTextBlob(ctx.Skia, props); + // ctx.canvas.drawTextBlob(textBlob, x, y, ctx.paint); + throw new Error("Not implemented"); +}; + +export const renderGlyphs = (_ctx: DrawingContext, _props: GlyphsProps) => { + "worklet"; + // const { glyphs, positions, font } = processGlyphs(ctx.Skia, props); + // ctx.canvas.drawGlyphs(glyphs, positions, font, ctx.paint); + throw new Error("Not implemented"); +}; + +export const renderParagraph = ( + _ctx: DrawingContext, + _props: ParagraphProps +) => { + "worklet"; + throw new Error("Not implemented"); +}; diff --git a/package/src/sg/__tests__/Breathe.spec.tsx b/package/src/sg/__tests__/Breathe.spec.tsx new file mode 100644 index 0000000000..ae9f1e6ac3 --- /dev/null +++ b/package/src/sg/__tests__/Breathe.spec.tsx @@ -0,0 +1,157 @@ +import { importSkia, width, height } from "../../renderer/__tests__/setup"; +import { processResult } from "../../__tests__/setup"; +import type { SGNode } from "../Node"; +import { createNode } from "../Node"; +import { NodeType } from "../../dom/types"; +import { renderNode } from "../Renderer"; +import { setupSkia } from "../../skia/__tests__/setup"; + +describe("Breathe", () => { + it("Apple Breathe Demo", () => { + const { surface, canvas } = setupSkia(width, height); + const { Skia, vec, polar2Canvas } = importSkia(); + const c = vec(width / 2, height / 2); + const c1 = Skia.Color("#61bea2"); + const c2 = Skia.Color("#529ca0"); + const R = width / 4; + const color = Skia.Color("rgb(36,43,56)"); + const fill = createNode(NodeType.Fill, {}); + + const blur = createNode(NodeType.BlurMaskFilter, { + blur: 10, + style: "solid", + respectCTM: true, + }); + + const ringChildren: SGNode[] = []; + for (let i = 0; i < 6; i++) { + const theta = (i * (2 * Math.PI)) / 6; + const matrix = Skia.Matrix(); + const { x, y } = polar2Canvas({ theta, radius: R }, { x: 0, y: 0 }); + matrix.translate(x, y); + const ring = createNode( + NodeType.Group, + { + matrix, + color: i % 2 ? c1 : c2, + }, + [createNode(NodeType.Circle, { c, r: R })] + ); + ringChildren.push(ring); + } + const rings = createNode(NodeType.Group, { blendMode: "screen" }, [ + blur, + ...ringChildren, + ]); + const root = createNode( + NodeType.Group, + { + color, + }, + [fill, rings] + ); + const ctx = { + Skia, + canvas, + paints: [Skia.Paint()], + }; + renderNode(ctx, root); + processResult(surface, "snapshots/demos/breathe.png"); + }); + // it("1Demo", () => { + + // }); + // it("Apple Breathe Demo with the new API", () => { + // const { surface, canvas } = setupSkia(width, height); + // const { Skia, vec, polar2Canvas } = importSkia(); + // const Sk = getSkDOM(); + // const c = vec(width / 2, height / 2); + // const c1 = Skia.Color("#61bea2"); + // const c2 = Skia.Color("#529ca0"); + // const R = width / 4; + // const color = Skia.Color("rgb(36,43,56)"); + // const root = Sk.Group({ color }); + // root.addChild(Sk.Fill()); + // const rings = Sk.Group({ + // blendMode: "screen", + // }); + // const blur = Sk.BlurMaskFilter({ + // blur: 10, + // style: "solid", + // respectCTM: true, + // }); + // rings.addChild(blur); + // for (let i = 0; i < 6; i++) { + // const theta = (i * (2 * Math.PI)) / 6; + // const matrix = Skia.Matrix(); + // const { x, y } = polar2Canvas({ theta, radius: R }, { x: 0, y: 0 }); + // matrix.translate(x, y); + // rings.addChild(Sk.Circle({ c, r: R, matrix, color: i % 2 ? c1 : c2 })); + // } + // root.addChild(rings); + // const ctx = new JsiDrawingContext(Skia, canvas); + // root.render(ctx); + // processResult(surface, "snapshots/demos/breathe.png"); + // }); + // it("Apple Breathe Demo with animations", () => { + // const { surface, canvas } = setupSkia(width, height); + // const { Skia, vec, polar2Canvas } = importSkia(); + // const Sk = getSkDOM(); + // const c = vec(width / 2, height / 2); + // const c1 = Skia.Color("#61bea2"); + // const c2 = Skia.Color("#529ca0"); + // const R = width / 4; + // const color = Skia.Color("rgb(36,43,56)"); + // const root = Sk.Group({ color }); + // root.addChild(Sk.Fill()); + // const rings = Sk.Group({ + // blendMode: "screen", + // }); + // const blur = Sk.BlurMaskFilter({ + // blur: 10, + // style: "solid", + // respectCTM: true, + // }); + // rings.addChild(blur); + // for (let i = 0; i < 6; i++) { + // const theta = (i * (2 * Math.PI)) / 6; + // const matrix = Skia.Matrix(); + // const { x, y } = polar2Canvas({ theta, radius: R }, { x: 0, y: 0 }); + // matrix.translate(x, y); + // rings.addChild(Sk.Circle({ c, r: R, matrix, color: i % 2 ? c1 : c2 })); + // } + // root.addChild(rings); + // const ctx = new JsiDrawingContext(Skia, canvas); + // root.render(ctx); + // processResult(surface, "snapshots/demos/breathe.png"); + // blur.setProp("blur", 0); + // root.setProp("transform", [ + // { translateX: c.x }, + // { translateY: c.y }, + // { rotate: Math.PI / 4 }, + // { translateX: -c.x }, + // { translateY: -c.y }, + // ]); + // for (let i = 0; i < 6; i++) { + // const theta = (i * (2 * Math.PI)) / 6; + // const matrix = Skia.Matrix(); + // const scale = 0.5; + // const { x, y } = polar2Canvas({ theta, radius: 0.5 * R }, { x: 0, y: 0 }); + // matrix.translate(x, y); + // // eslint-disable-next-line @typescript-eslint/no-explicit-any + // const ring = rings.children()[i + 1] as any; + // ring.setProp("matrix", undefined); + // ring.setProp("transform", [ + // { translateX: c.x }, + // { translateY: c.y }, + // { translateX: x }, + // { translateY: y }, + // { scale }, + // { translateX: -c.x }, + // { translateY: -c.y }, + // ]); + // } + // root.render(ctx); + // processResult(surface, "snapshots/demos/breathe2.png"); + // }); +}); diff --git a/package/src/sg/__tests__/Simple.spec.tsx b/package/src/sg/__tests__/Simple.spec.tsx new file mode 100644 index 0000000000..ad323070db --- /dev/null +++ b/package/src/sg/__tests__/Simple.spec.tsx @@ -0,0 +1,21 @@ +import { importSkia, width, height } from "../../renderer/__tests__/setup"; +import { processResult } from "../../__tests__/setup"; +import { createNode } from "../Node"; +import { NodeType } from "../../dom/types"; +import { renderNode } from "../Renderer"; +import { setupSkia } from "../../skia/__tests__/setup"; + +describe("Simple", () => { + it("Fill", () => { + const { surface, canvas } = setupSkia(width, height); + const { Skia } = importSkia(); + const root = createNode(NodeType.Fill, { color: "red" }); + const ctx = { + Skia, + canvas, + paints: [Skia.Paint()], + }; + renderNode(ctx, root); + processResult(surface, "snapshots/demos/simple1.png"); + }); +}); diff --git a/scripts/codegen.ts b/scripts/codegen.ts new file mode 100644 index 0000000000..57d01a0f88 --- /dev/null +++ b/scripts/codegen.ts @@ -0,0 +1,38 @@ +import * as path from "path"; + +import { Node, Project, SyntaxKind } from "ts-morph"; + +// Define the path to the WebGPU type declaration file +const tsConfigFilePath = path.resolve(__dirname, "../package/tsconfig.json"); +const filePath = path.resolve( + __dirname, + "../package/src/renderer/HostComponents.ts", +); +const project = new Project({ + tsConfigFilePath, +}); + +const sourceFile = project.addSourceFileAtPath(filePath); + +const decl = sourceFile.getDescendantsOfKind(SyntaxKind.InterfaceDeclaration).filter(node => node.getName() === "IntrinsicElements")[0]; +decl.getProperties().forEach(prop => { + const nodeType = prop.getName().substring(2); + console.log(`${nodeType}Props,`); +}); +// decl.getProperties().forEach(prop => { +// const nodeType = prop.getName().substring(2); +// console.log(`[NodeType.${nodeType}]: ${nodeType}Props;`); +// }); +// decl.getProperties().forEach(prop => { +// const nodeType = prop.getName().substring(2); +// console.log(`case NodeType.${nodeType}: +// render${nodeType}(ctx, materializedProps); +// break;`); +// }); + +// console.log(sourceFile.getDescendantsOfKind(SyntaxKind.InterfaceDeclaration).map(node => { +// // node.getName() +// return node.getText(); +// })); +//console.log(sourceFile.getInterface("IntrinsicElements")!.getText()); +//console.log(sourceFile.getModule("global")!.getText()); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 2d9f2a24eb..69dfae9689 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,6 +14,37 @@ dependencies: "@cspotcode/source-map-consumer" "0.8.0" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@ts-morph/common@~0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.24.0.tgz#9125b3d5ef9e2633cd6a54296b420b89366599c1" + integrity sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A== + dependencies: + fast-glob "^3.3.2" + minimatch "^9.0.4" + mkdirp "^3.0.1" + path-browserify "^1.0.1" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -72,6 +103,20 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + clang-format@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/clang-format/-/clang-format-1.6.0.tgz#48fac4387712aeeae0f47b5d72f639f3fd95f4b6" @@ -81,6 +126,11 @@ clang-format@1.6.0: glob "^7.0.0" resolve "^1.1.6" +code-block-writer@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-13.0.1.tgz#52ac60ca6076d8700b88a45bd71e06a577158405" + integrity sha512-c5or4P6erEA69TxaxTNcHUNcIn+oyxSRTOWV+pSYF+z4epXqNvwvJ70XPGjPNgue83oAFAPBRQYwpAJ/Hpe/Sg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -96,6 +146,31 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -106,6 +181,13 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + glob@^7.0.0, glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -145,11 +227,41 @@ is-core-module@^2.13.0: dependencies: hasown "^2.0.0" +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -157,6 +269,18 @@ minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -164,6 +288,11 @@ once@^1.3.0: dependencies: wrappy "1" +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -174,6 +303,16 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + resolve@^1.1.6: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" @@ -183,6 +322,11 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -190,11 +334,33 @@ rimraf@3.0.2: dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-morph@^23.0.0: + version "23.0.0" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-23.0.0.tgz#601d74edd1d24247e312b9fa5d147bdc659bff15" + integrity sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug== + dependencies: + "@ts-morph/common" "~0.24.0" + code-block-writer "^13.0.1" + ts-node@10.4.0: version "10.4.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"