Skip to content

Commit

Permalink
fix(🌧️): fix major regression with the Glyphs component (#2944)
Browse files Browse the repository at this point in the history
  • Loading branch information
wcandillon authored Feb 5, 2025
1 parent 4bc9b79 commit 53e8fae
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 50 deletions.
46 changes: 22 additions & 24 deletions apps/paper/src/Examples/Matrix/Matrix.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useFont,
} from "@shopify/react-native-skia";
import React from "react";
import { useWindowDimensions, View } from "react-native";
import { useWindowDimensions } from "react-native";

import { COLS, ROWS, Symbol } from "./Symbol";

Expand Down Expand Up @@ -39,29 +39,27 @@ export const Matrix = () => {
if (font === null) {
return null;
}
const symbols = "abcdefghijklmnopqrstuvwxyz".split("");
const symbols = font.getGlyphIDs("abcdefghijklmnopqrstuvwxyz");
return (
<View style={{ flex: 1, backgroundColor: "black" }}>
<Canvas style={{ flex: 1 }} opaque>
<Fill color="black" />
<Group>
<BlurMask blur={4} style="solid" />
{cols.map((_i, i) =>
rows.map((_j, j) => (
<Symbol
symbols={symbols}
font={font}
timestamp={clock}
key={`${i}-${j}`}
i={i}
j={j}
stream={streams[i]}
symbol={symbol}
/>
))
)}
</Group>
</Canvas>
</View>
<Canvas style={{ flex: 1 }} opaque>
<Fill color="black" />
<Group>
<BlurMask blur={4} style="solid" />
{cols.map((_i, i) =>
rows.map((_j, j) => (
<Symbol
symbols={symbols}
font={font}
timestamp={clock}
key={`${i}-${j}`}
i={i}
j={j}
stream={streams[i]}
symbol={symbol}
/>
))
)}
</Group>
</Canvas>
);
};
22 changes: 15 additions & 7 deletions apps/paper/src/Examples/Matrix/Symbol.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import React, { useRef } from "react";
import type { SkFont } from "@shopify/react-native-skia";
import { interpolateColors, Text } from "@shopify/react-native-skia";
import { interpolateColors, vec, Glyphs } from "@shopify/react-native-skia";
import type { SharedValue } from "react-native-reanimated";
import { useDerivedValue } from "react-native-reanimated";

export const COLS = 16;
export const ROWS = 32;
export const COLS = 8;
export const ROWS = 15;
const pos = vec(0, 0);

interface SymbolProps {
i: number;
j: number;
timestamp: SharedValue<number>;
stream: number[];
font: SkFont;
symbols: string[];
symbols: number[];
symbol: { width: number; height: number };
}

Expand All @@ -31,9 +32,9 @@ export const Symbol = ({
const x = i * symbol.width;
const y = j * symbol.height;

const text = useDerivedValue(() => {
const glyphs = useDerivedValue(() => {
const idx = offset.current + Math.floor(timestamp.value / range.current);
return symbols[idx % symbols.length];
return [{ id: symbols[idx % symbols.length], pos }];
}, [timestamp]);

const opacity = useDerivedValue(() => {
Expand All @@ -52,6 +53,13 @@ export const Symbol = ({
);

return (
<Text x={x} y={y} font={font} text={text} opacity={opacity} color={color} />
<Glyphs
x={x + symbol.width / 4}
y={y + symbol.height}
font={font}
glyphs={glyphs}
opacity={opacity}
color={color}
/>
);
};
32 changes: 32 additions & 0 deletions packages/skia/cpp/api/recorder/Convertor.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,15 @@ struct Radius {
using ConversionFunction =
std::function<void(jsi::Runtime &runtime, const jsi::Object &object)>;
using Variables = std::map<std::string, std::vector<ConversionFunction>>;

using Patch = std::array<SkPoint, 12>;

struct GlyphData {
std::vector<SkGlyphID> glyphIds;
std::vector<SkPoint> positions;
};


bool isSharedValue(jsi::Runtime &runtime, const jsi::Value &value) {
return value.isObject() &&
value.asObject(runtime).hasProperty(runtime,
Expand Down Expand Up @@ -378,6 +385,31 @@ SkFont getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) {
throw std::runtime_error("Invalid prop value for SkFont received");
}

template <>
GlyphData getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) {
GlyphData result;
if (value.isObject() && value.asObject(runtime).isArray(runtime)) {
auto array = value.asObject(runtime).asArray(runtime);
size_t size = array.size(runtime);
result.glyphIds.reserve(size);
result.positions.reserve(size);

for (size_t i = 0; i < size; i++) {
auto glyph = array.getValueAtIndex(runtime, i).asObject(runtime);
// Get the glyph id
result.glyphIds.push_back(
static_cast<SkGlyphID>(glyph.getProperty(runtime, "id").asNumber())
);
// Get the position
result.positions.push_back(
processPoint(runtime, glyph.getProperty(runtime, "pos"))
);
}
return result;
}
throw std::runtime_error("Invalid prop value for GlyphData received");
}

template <>
SkRSXform getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value) {
if (value.isObject()) {
Expand Down
29 changes: 10 additions & 19 deletions packages/skia/cpp/api/recorder/Drawings.h
Original file line number Diff line number Diff line change
Expand Up @@ -745,16 +745,11 @@ class TextBlobCmd : public Command {
}
};

struct GlyphData {
std::vector<SkGlyphID> glyphIds;
std::vector<SkPoint> positions;
};

struct GlyphsCmdProps {
std::optional<SkFont> font;
float x;
float y;
// GlyphData glyphs;
GlyphData glyphs;
};

class GlyphsCmd : public Command {
Expand All @@ -768,22 +763,18 @@ class GlyphsCmd : public Command {
convertProperty(runtime, object, "font", props.font, variables);
convertProperty(runtime, object, "x", props.x, variables);
convertProperty(runtime, object, "y", props.y, variables);
// convertProperty(runtime, object, "glyphs", props.glyphs, variables);
convertProperty(runtime, object, "glyphs", props.glyphs, variables);
}

void draw(DrawingCtx *ctx) {
void draw(DrawingCtx *ctx) {
if (props.font.has_value()) {
// std::vector<uint16_t> glyphIds;
// std::vector<SkPoint> positions;
// for (const auto &[id, pos] : props.glyphs) {
// glyphIds.push_back(id);
// positions.push_back(pos);
// }
// ctx->canvas->drawGlyphs(
// static_cast<int>(props.glyphs.glyphIds.size()),
// props.glyphs.glyphIds.data(), props.glyphs.positions.data(),
// SkPoint::Make(props.x, props.y), props.font.value(),
// ctx->getPaint());
ctx->canvas->drawGlyphs(
static_cast<int>(props.glyphs.glyphIds.size()),
props.glyphs.glyphIds.data(),
props.glyphs.positions.data(),
SkPoint::Make(props.x, props.y),
props.font.value(),
ctx->getPaint());
}
}
};
Expand Down

0 comments on commit 53e8fae

Please sign in to comment.