diff --git a/example/src/Examples/Neumorphism/Dashboard/components/Control.tsx b/example/src/Examples/Neumorphism/Dashboard/components/Control.tsx index 4bd0d58f83..af1cedfbcc 100644 --- a/example/src/Examples/Neumorphism/Dashboard/components/Control.tsx +++ b/example/src/Examples/Neumorphism/Dashboard/components/Control.tsx @@ -34,9 +34,7 @@ export const Control = ({ progress, active, }: ControlProps) => { - const labelWidth = font - .getGlyphWidths(font.getGlyphIDs(label)) - .reduce((a, b) => a + b, 0); + const labelWidth = font.getTextWidth(label); return ( { if (font === null) { return null; } - const textWidth = font - .getGlyphWidths(font.getGlyphIDs("00°C")) - .reduce((a, b) => a + b, 0); + const textWidth = font.getTextWidth("00°C"); return ( diff --git a/example/src/Examples/Neumorphism/Dashboard/components/Title.tsx b/example/src/Examples/Neumorphism/Dashboard/components/Title.tsx index cc0f19c0e6..3704189315 100644 --- a/example/src/Examples/Neumorphism/Dashboard/components/Title.tsx +++ b/example/src/Examples/Neumorphism/Dashboard/components/Title.tsx @@ -14,9 +14,7 @@ export const Title = ({ title }: Title) => { if (!font) { return null; } - const titleWidth = font - .getGlyphWidths(font.getGlyphIDs(title)) - .reduce((a, b) => a + b, 0); + const titleWidth = font.getTextWidth(title); const offsetX = 30 + BUTTON_SIZE; const space = 298 - offsetX; return ( diff --git a/example/src/Examples/Wallet/components/Label.tsx b/example/src/Examples/Wallet/components/Label.tsx index 2fcbb4bb75..87eb6caf36 100644 --- a/example/src/Examples/Wallet/components/Label.tsx +++ b/example/src/Examples/Wallet/components/Label.tsx @@ -49,17 +49,13 @@ export const Label = ({ state, y, graphs, width, height }: LabelProps) => { } const graph = graphs[state.current.current]; const title = format(graph.data.maxPrice); - const titleWidth = titleFont - .getGlyphWidths(titleFont.getGlyphIDs(title)) - .reduce((a, b) => a + b, 0); + const titleWidth = titleFont.getTextWidth(title); return width / 2 - titleWidth / 2; }, [state, titleFont]); if (!titleFont || !subtitleFont) { return null; } - const subtitleWidth = subtitleFont - .getGlyphWidths(subtitleFont.getGlyphIDs(subtitle)) - .reduce((a, b) => a + b, 0); + const subtitleWidth = subtitleFont.getTextWidth(subtitle); return ( <> #include #include +#include #include #include "JsiSkHostObjects.h" @@ -86,6 +87,28 @@ namespace RNSkia return jsiWidths; } + JSI_HOST_FUNCTION(getTextWidth) { + auto str = arguments[0].asString(runtime).utf8(runtime); + auto numGlyphIDs = str.length(); + std::vector glyphs; + glyphs.resize(numGlyphIDs); + int glyphsSize = static_cast(numGlyphIDs); + getObject()->textToGlyphs(str.c_str(), str.length(), SkTextEncoding::kUTF8, + static_cast(glyphs.data()), glyphsSize); + std::vector widthPtrs; + widthPtrs.resize(numGlyphIDs); + if (count > 1) + { + auto paint = JsiSkPaint::fromValue(runtime, arguments[1]); + getObject()->getWidthsBounds(glyphs.data(), glyphsSize, static_cast(widthPtrs.data()), nullptr, paint.get()); + } + else + { + getObject()->getWidthsBounds(glyphs.data(), glyphsSize, static_cast(widthPtrs.data()), nullptr, nullptr); + } + return jsi::Value(std::accumulate(widthPtrs.begin(), widthPtrs.end(), 0)); + } + JSI_HOST_FUNCTION(getMetrics) { SkFontMetrics fm; @@ -273,7 +296,8 @@ namespace RNSkia JSI_EXPORT_FUNC(JsiSkFont, setEmbolden), JSI_EXPORT_FUNC(JsiSkFont, setSubpixel), JSI_EXPORT_FUNC(JsiSkFont, setTypeface), - JSI_EXPORT_FUNC(JsiSkFont, getGlyphWidths)) + JSI_EXPORT_FUNC(JsiSkFont, getGlyphWidths), + JSI_EXPORT_FUNC(JsiSkFont, getTextWidth)) JsiSkFont(std::shared_ptr context, const SkFont &font) : JsiSkWrappingSharedPtrHostObject(std::move(context), diff --git a/package/src/skia/types/Font/Font.ts b/package/src/skia/types/Font/Font.ts index 6f5c568c8b..dc11eb622a 100644 --- a/package/src/skia/types/Font/Font.ts +++ b/package/src/skia/types/Font/Font.ts @@ -12,6 +12,13 @@ export interface FontMetrics { } export interface SkFont extends SkJSIInstance<"Font"> { + /** + * Retrieves the total width of the provided text + * @param text + * @param paint + */ + getTextWidth(text: string, paint?: SkPaint): number; + /** * Retrieves the advanceX measurements for each glyph. * If paint is not null, its stroking, PathEffect, and MaskFilter fields are respected. diff --git a/package/src/skia/web/JsiSkFont.ts b/package/src/skia/web/JsiSkFont.ts index b83a79aa5b..c7716b8214 100644 --- a/package/src/skia/web/JsiSkFont.ts +++ b/package/src/skia/web/JsiSkFont.ts @@ -27,6 +27,12 @@ Clients should use "Font.getGlyphWidths" instead (the latter does no shaping)` return new JsiSkRect(this.CanvasKit, this.CanvasKit.XYWHRect(0, 0, 0, 0)); } + getTextWidth(text: string, paint?: SkPaint | undefined) { + const ids = this.getGlyphIDs(text); + const widths = this.getGlyphWidths(ids, paint); + return widths.reduce((a, b) => a + b, 0); + } + getMetrics() { const result = this.ref.getMetrics(); return {