diff --git a/bench/lib/DrawBench.re b/bench/lib/DrawBench.re index 561520ac0..7e8d01f94 100644 --- a/bench/lib/DrawBench.re +++ b/bench/lib/DrawBench.re @@ -14,12 +14,14 @@ module Data = { let testString = String.make(50, 'a') ++ String.make(50, 'X'); let paint = { let textPaint = Skia.Paint.make(); - Skia.Paint.setTextEncoding(textPaint, GlyphId); - Skia.Paint.setLcdRenderText(textPaint, true); Skia.Paint.setAntiAlias(textPaint, true); - Skia.Paint.setTextSize(textPaint, 20.); textPaint; }; + let font = { + let textFont = Skia.Font.makeDefault(); + Skia.Font.setTextSize(textFont, 20.); + textFont; + }; let rectPaint = Skia.Paint.make(); }; @@ -29,7 +31,7 @@ let drawText = canvasContext => { | Error(_) => failwith("Unable to load font!") | Ok(font) => Skia.Paint.setColor(Data.paint, Revery_Core.Color.toSkia(Colors.white)); - Skia.Paint.setTypeface(Data.paint, Revery.Font.getSkiaTypeface(font)); + Skia.Font.setTypeface(Data.font, Revery.Font.getSkiaTypeface(font)); let shapedText = Data.testString @@ -41,6 +43,7 @@ let drawText = canvasContext => { ~y=1., ~paint=Data.paint, ~text=shapedText, + ~font=Data.font, canvasContext, ); }; diff --git a/examples/CanvasExample.re b/examples/CanvasExample.re index f85d51198..198679e26 100644 --- a/examples/CanvasExample.re +++ b/examples/CanvasExample.re @@ -58,26 +58,28 @@ module Sample = { | Ok(font) => let textPaint = Skia.Paint.make(); Skia.Paint.setColor(textPaint, Color.toSkia(Colors.white)); - Skia.Paint.setTypeface( - textPaint, - FontCache.getSkiaTypeface(font), - ); - Skia.Paint.setLcdRenderText(textPaint, true); + // ASK: What we should do + // Skia.Paint.setLcdRenderText(textPaint, true); Skia.Paint.setAntiAlias(textPaint, true); - Skia.Paint.setTextSize(textPaint, 20.); + let fontText = + Skia.Font.makeWithValues( + FontCache.getSkiaTypeface(font), + 20., + 1., + 0., + ); let shapedText = "Hello, World" |> FontCache.shape(font) |> ShapeResult.getGlyphString; - Skia.Paint.setTextEncoding(textPaint, GlyphId); - CanvasContext.drawText( ~paint=textPaint, ~x=10.0, ~y=20.0, ~text=shapedText, + ~font=fontText, canvasContext, ); }; diff --git a/examples/skia-cli/SkiaCli.re b/examples/skia-cli/SkiaCli.re index b1ca00f47..33e30c194 100644 --- a/examples/skia-cli/SkiaCli.re +++ b/examples/skia-cli/SkiaCli.re @@ -61,7 +61,8 @@ let draw = canvas => { let fill3 = Paint.make(); Paint.setColor(fill3, Color.makeArgb(0xFFl, 0xFFl, 0xFFl, 0xFFl)); - Paint.setTextSize(fill3, 30.); + // TODO: add some setter + // split creation of font let nonExistentTypeface = Typeface.makeFromFile("non-existent-font.ttf", 0); assert(nonExistentTypeface == None); @@ -74,11 +75,11 @@ let draw = canvas => { | None => failwith("Unable to load font: " ++ filePath) | Some(typeFace) => print_endline(__LOC__ ++ ": we will set."); - Paint.setTypeface(fill3, typeFace); - print_endline(__LOC__ ++ ": setTypeface is OK."); - Canvas.drawText(canvas, "Hello, world!", 30., 30., fill3); + let font = Font.makeWithValues(typeFace, 30., 1., 0.); + print_endline(__LOC__ ++ ": makeWithValues is OK."); + Canvas.drawText(canvas, "Hello, world!", GlyphId, 30., 30., font, fill3); let metrics = FontMetrics.make(); - let _ret: float = Paint.getFontMetrics(fill3, metrics, 1.0); + let _ret: float = Font.getFontMetrics(font, metrics); print_endline( "-- Top: " ++ string_of_float(FontMetrics.getTop(metrics)), @@ -99,10 +100,12 @@ let draw = canvas => { print_endline(__LOC__ ++ ": We return."); // Measure - let measurement = Paint.measureText(fill3, "Hello, world!", None); + let measurement = + Font.measureText(font, "Hello, world!", GlyphId, None, Some(fill3)); print_endline("Measured text: " ++ string_of_float(measurement)); - Paint.setTextSize(fill3, 50.); - let largeMeasurement = Paint.measureText(fill3, "Hello, world!", None); + Font.setTextSize(font, 50.); + let largeMeasurement = + Font.measureText(font, "Hello, world!", GlyphId, None, Some(fill3)); print_endline( "Large measured text: " ++ string_of_float(largeMeasurement), ); @@ -155,12 +158,10 @@ let draw = canvas => { switch (maybeTypeface) { | None => failwith("Unable to load font: " ++ filePath) | Some(typeFace) => + let font = Font.makeWithValues(typeFace, 30., 1., 0.); let fill = Paint.make(); Paint.setColor(fill, Color.makeArgb(0xFFl, 0xFFl, 0xFFl, 0xFFl)); - Paint.setTextSize(fill, 30.); - Paint.setTypeface(fill, typeFace); - Paint.setSubpixelText(fill, true); - Paint.setTextEncoding(fill, GlyphId); + Font.setSubpixelText(font, true); let glyphsToString = glyphs => { let len = List.length(glyphs); @@ -185,7 +186,7 @@ let draw = canvas => { // For FiraCode, this is a==>b let str = glyphsToString([136, 1624, 1624, 1495, 148]); - Canvas.drawText(canvas, str, 50., 100., fill); + Canvas.drawText(canvas, str, GlyphId, 50., 100., font, fill); }; let fill = Paint.make(); diff --git a/examples/skia-font-manager-cli/SkiaFontManagerCli.re b/examples/skia-font-manager-cli/SkiaFontManagerCli.re index 428d3c7c9..c5f2bc75b 100644 --- a/examples/skia-font-manager-cli/SkiaFontManagerCli.re +++ b/examples/skia-font-manager-cli/SkiaFontManagerCli.re @@ -20,17 +20,18 @@ let draw = canvas => { let maybeTypeface = FontManager.matchFamilyStyle(fontManager, "Arial", style); let fill = Paint.make(); + let font = Font.makeDefault(); Paint.setColor(fill, Color.makeArgb(0xFFl, 0xFFl, 0xFFl, 0xFFl)); - Paint.setTextSize(fill, 16.); - Paint.setSubpixelText(fill, true); + Font.setTextSize(font, 16.); + Font.setSubpixelText(font, true); switch (maybeTypeface) { | None => print_endline("Normal Arial not found. Ensure you have it available.") | Some(typeface) => - Paint.setTypeface(fill, typeface); - Canvas.drawText(canvas, "Arial (System)", 10., 20., fill); + Font.setTypeface(font, typeface); + Canvas.drawText(canvas, "Arial (System)", GlyphId, 10., 20., font, fill); let stream = Typeface.toStream(typeface); let length = Stream.getLength(stream); Printf.printf("Stream length: %d\n", length); @@ -50,8 +51,16 @@ let draw = canvas => { "Normal Times New Roman not found. Ensure you have it available.", ) | Some(typeface) => - Paint.setTypeface(fill, typeface); - Canvas.drawText(canvas, "Times New Roman (System)", 10., 40., fill); + Font.setTypeface(font, typeface); + Canvas.drawText( + canvas, + "Times New Roman (System)", + GlyphId, + 10., + 40., + font, + fill, + ); }; let maybeTypeface = @@ -62,9 +71,9 @@ let draw = canvas => { "Normal Consolas not found. Ensure your system has it available.", ) | Some(typeface) => - Paint.setTypeface(fill, typeface); + Font.setTypeface(font, typeface); let metrics = FontMetrics.make(); - let _ret: float = Paint.getFontMetrics(fill, metrics, 1.0); + let _ret: float = Font.getFontMetrics(font, metrics); print_endline("__Consolas__"); print_endline( "-- Average character width: " @@ -82,9 +91,9 @@ let draw = canvas => { switch (maybeTypeface) { | None => failwith("Unable to load font: " ++ filePath) | Some(typeface) => - Paint.setTypeface(fill, typeface); + Font.setTypeface(font, typeface); let metrics = FontMetrics.make(); - let _ret: float = Paint.getFontMetrics(fill, metrics, 1.0); + let _ret: float = Font.getFontMetrics(font, metrics); print_endline("__Fira Code__"); print_endline( "-- Average character width: " diff --git a/examples/skia-sdl2/SkiaSdl.re b/examples/skia-sdl2/SkiaSdl.re index 780f96b22..ac7497307 100644 --- a/examples/skia-sdl2/SkiaSdl.re +++ b/examples/skia-sdl2/SkiaSdl.re @@ -123,7 +123,7 @@ let run = () => { Skia.Color.makeArgb(0xFFl, 0xFFl, 0xFFl, 0xFFl), ); - Skia.Canvas.drawText(canvas, "Hello, world!", 50., 50., paint); + Skia.Canvas.drawText(canvas, "Hello, world!", GlyphId, 50., 50., Font.makeDefault(), paint); Skia.Canvas.flush(canvas); Sdl2.Gl.swapWindow(window); diff --git a/src/Draw/CanvasContext.re b/src/Draw/CanvasContext.re index 24f50b5c5..e42c053a8 100644 --- a/src/Draw/CanvasContext.re +++ b/src/Draw/CanvasContext.re @@ -185,8 +185,8 @@ let drawImage = (~x, ~y, ~width, ~height, ~paint=?, data: Skia.Image.t, v: t) => ); }; -let drawText = (~paint, ~x=0., ~y=0., ~text, v: t) => { - Canvas.drawText(v.canvas, text, x, y, paint); +let drawText = (~paint, ~x=0., ~y=0., ~text, ~font, v: t) => { + Canvas.drawText(v.canvas, text, GlyphId, x, y, font, paint); }; let _topMatrix = Skia.Matrix.make(); @@ -233,17 +233,23 @@ module Deprecated = { | Error(_) => () | Ok(font) => let textPaint = Skia.Paint.make(); + // ASK: put outside ? + let font' = + Skia.Font.makeWithValues( + FontCache.getSkiaTypeface(font), + fontSize, + 1., + 0., + ); Skia.Paint.setColor(textPaint, Revery_Core.Color.toSkia(color)); - Skia.Paint.setTypeface(textPaint, FontCache.getSkiaTypeface(font)); - Skia.Paint.setTextEncoding(textPaint, GlyphId); - Skia.Paint.setLcdRenderText(textPaint, true); + // ASK: What we should do + // Skia.Paint.setLcdRenderText(textPaint, true); Skia.Paint.setAntiAlias(textPaint, true); - Skia.Paint.setTextSize(textPaint, fontSize); let shapedText = text |> FontCache.shape(font) |> ShapeResult.getGlyphString; - drawText(~x, ~y, ~paint=textPaint, ~text=shapedText, v); + drawText(~x, ~y, ~paint=textPaint, ~text=shapedText, ~font=font', v); }; }; }; diff --git a/src/Font/FontCache.re b/src/Font/FontCache.re index 37d7c7c23..2caac1842 100644 --- a/src/Font/FontCache.re +++ b/src/Font/FontCache.re @@ -99,12 +99,10 @@ let getMetrics: (t, float) => FontMetrics.t = MetricsLruHash.promote(size, metricsCache); v; | None => - let paint = Skia.Paint.make(); - Skia.Paint.setTypeface(paint, skiaFace); - Skia.Paint.setTextSize(paint, size); + let font = Skia.Font.makeWithValues(skiaFace, size, 1., 0.); let metrics = Skia.FontMetrics.make(); - let lineHeight = Skia.Paint.getFontMetrics(paint, metrics, 1.0); + let lineHeight = Skia.Font.getFontMetrics(font, metrics); let ret = FontMetrics.ofSkia(size, lineHeight, metrics); MetricsLruHash.add(size, ret, metricsCache); diff --git a/src/Font/FontRenderer.re b/src/Font/FontRenderer.re index 5fd970eaf..5f308a05c 100644 --- a/src/Font/FontRenderer.re +++ b/src/Font/FontRenderer.re @@ -5,20 +5,20 @@ type measureResult = { let measure = { let paint = Skia.Paint.make(); - Skia.Paint.setTextEncoding(paint, GlyphId); (~smoothing: Smoothing.t, font, size, text: string) => { let {height, _}: FontMetrics.t = FontCache.getMetrics(font, size); let skiaFace = FontCache.getSkiaTypeface(font); + // TODO: put outside + let font' = Skia.Font.makeWithValues(skiaFace, size, 1., 0.); let glyphString = text |> FontCache.shape(font) |> ShapeResult.getGlyphString; - Smoothing.setPaint(~smoothing, paint); + Smoothing.setPaint(~smoothing, paint, font'); - Skia.Paint.setTypeface(paint, skiaFace); - Skia.Paint.setTextSize(paint, size); - let width = Skia.Paint.measureText(paint, glyphString, None); + let width = + Skia.Font.measureText(font', glyphString, GlyphId, None, Some(paint)); {height, width}; }; }; diff --git a/src/Font/Smoothing.re b/src/Font/Smoothing.re index 723ceec3e..e0d78e257 100644 --- a/src/Font/Smoothing.re +++ b/src/Font/Smoothing.re @@ -9,16 +9,16 @@ type t = // - https://github.com/onivim/oni2/issues/1592 let default = SubpixelAntialiased; -let setPaint = (~smoothing: t, paint: Skia.Paint.t) => { +let setPaint = (~smoothing: t, paint: Skia.Paint.t, font: Skia.Font.t) => { switch (smoothing) { | None => Skia.Paint.setAntiAlias(paint, false); - Skia.Paint.setSubpixelText(paint, false); + Skia.Font.setSubpixelText(font, false); | Antialiased => Skia.Paint.setAntiAlias(paint, true); - Skia.Paint.setSubpixelText(paint, false); + Skia.Font.setSubpixelText(font, false); | SubpixelAntialiased => Skia.Paint.setAntiAlias(paint, true); - Skia.Paint.setSubpixelText(paint, true); + Skia.Font.setSubpixelText(font, true); }; }; diff --git a/src/UI/TextNode.re b/src/UI/TextNode.re index 592380e1a..8519c77d1 100644 --- a/src/UI/TextNode.re +++ b/src/UI/TextNode.re @@ -27,8 +27,8 @@ class textNode (text: string) = { val mutable _underlined = false; val _textPaint = { let paint = Skia.Paint.make(); - Skia.Paint.setTextEncoding(paint, GlyphId); - Skia.Paint.setLcdRenderText(paint, true); + // ASK: What we should do + // Skia.Paint.setLcdRenderText(paint, true); Skia.Paint.setAntiAlias(paint, true); paint; }; @@ -49,14 +49,17 @@ class textNode (text: string) = { ) ) { | Error(_) => () - | Ok(font) => - Revery_Font.Smoothing.setPaint(~smoothing=_smoothing, _textPaint); + | Ok(fontCache) => + let font = + Skia.Font.makeWithValues( + Revery_Font.FontCache.getSkiaTypeface(fontCache), + _fontSize, + 1., + 0., + ); + // TODO: scale, skew + Revery_Font.Smoothing.setPaint(~smoothing=_smoothing, _textPaint, font); Skia.Paint.setColor(_textPaint, Color.toSkia(colorWithAppliedOpacity)); - Skia.Paint.setTypeface( - _textPaint, - Revery_Font.FontCache.getSkiaTypeface(font), - ); - Skia.Paint.setTextSize(_textPaint, _fontSize); let ascentPx = Text.ascent( @@ -93,7 +96,7 @@ class textNode (text: string) = { let glyphString = line - |> Revery_Font.shape(font) + |> Revery_Font.shape(fontCache) |> Revery_Font.ShapeResult.getGlyphString; CanvasContext.drawText( @@ -101,16 +104,17 @@ class textNode (text: string) = { ~x=0., ~y=baselineY, ~text=glyphString, + ~font, canvas, ); if (_underlined) { let {underlinePosition, underlineThickness, _}: FontMetrics.t = - FontCache.getMetrics(font, _fontSize); + FontCache.getMetrics(fontCache, _fontSize); let width = FontRenderer.measure( ~smoothing=_smoothing, - font, + fontCache, _fontSize, line, ). diff --git a/src/reason-skia/Skia.re b/src/reason-skia/Skia.re index e7780d227..d257ed194 100644 --- a/src/reason-skia/Skia.re +++ b/src/reason-skia/Skia.re @@ -132,10 +132,6 @@ module Paint = { paint; }; - let measureText = (paint, text, rectOpt) => { - SkiaWrapped.Paint.measureText(paint, text, String.length(text), rectOpt); - }; - [@noalloc] external _setColor: (CI.fatptr(_), [@unboxed] int32) => unit = "reason_skia_paint_set_color_byte" "reason_skia_paint_set_color"; @@ -147,23 +143,10 @@ module Paint = { let setColor = (paint, color) => _setColor(CI.cptr(paint), color); let setAlpha = (paint, alpha) => _setAlphaf(CI.cptr(paint), alpha); - let setHinting = SkiaWrapped.Paint.setHinting; - let getHinting = SkiaWrapped.Paint.getHinting; - - let isAutohinted = SkiaWrapped.Paint.isAutohinted; - let setAutohinted = SkiaWrapped.Paint.setAutohinted; - let setAntiAlias = SkiaWrapped.Paint.setAntiAlias; let setStyle = SkiaWrapped.Paint.setStyle; let setStrokeWidth = SkiaWrapped.Paint.setStrokeWidth; - let setLcdRenderText = SkiaWrapped.Paint.setLcdRenderText; - let setSubpixelText = SkiaWrapped.Paint.setSubpixelText; - let setTextSize = SkiaWrapped.Paint.setTextSize; - let setTypeface = SkiaWrapped.Paint.setTypeface; - let getFontMetrics = SkiaWrapped.Paint.getFontMetrics; let setImageFilter = SkiaWrapped.Paint.setImageFilter; - let setTextEncoding = SkiaWrapped.Paint.setTextEncoding; - let getTextEncoding = SkiaWrapped.Paint.getTextEncoding; let setShader = SkiaWrapped.Paint.setShader; }; @@ -474,6 +457,44 @@ module Rect = { }; }; +module Font = { + type t = SkiaWrapped.Font.t; + + let makeDefault = () => { + let fnt = SkiaWrapped.Font.makeDefault(); + Gc.finalise(SkiaWrapped.Font.delete, fnt); + fnt; + }; + + let makeWithValues = (typeface, size, scaleX, skewX) => { + let fnt = SkiaWrapped.Font.makeWidthValues(typeface, size, scaleX, skewX); + Gc.finalise(SkiaWrapped.Font.delete, fnt); + fnt; + }; + + let measureText = (font, text, encoding, rectOpt, paint) => + SkiaWrapped.Font.measureText( + font, + text, + String.length(text), + encoding, + rectOpt, + paint, + ); + + let getFontMetrics = SkiaWrapped.Font.getFontMetrics; + let setTypeface = SkiaWrapped.Font.setTypeface; + let setTextSize = SkiaWrapped.Font.setTextSize; + + let setSubpixelText = SkiaWrapped.Font.setSubpixelText; + + let isAutohinted = SkiaWrapped.Font.isAutohinted; + let setAutohinted = SkiaWrapped.Font.setAutohinted; + + let getHinting = SkiaWrapped.Font.getHinting; + let setHinting = SkiaWrapped.Font.setHinting; +}; + module FontStyle = { type t = SkiaWrapped.FontStyle.t; type slant = SkiaWrapped.FontStyle.slant; @@ -712,13 +733,14 @@ module Canvas = { let drawPath = SkiaWrapped.Canvas.drawPath; let drawCircle = SkiaWrapped.Canvas.drawCircle; - let drawText = (canvas, text, x, y, paint) => { + let drawText = (canvas, text, x, y, font, paint) => { SkiaWrapped.Canvas.drawText( canvas, text, - String.length(text), + Unsigned.Size_t.of_int(String.length(text)), x, y, + font, paint, ); }; diff --git a/src/reason-skia/Skia.rei b/src/reason-skia/Skia.rei index df3f7f65f..79eba28f2 100644 --- a/src/reason-skia/Skia.rei +++ b/src/reason-skia/Skia.rei @@ -187,27 +187,32 @@ module Paint: { let setColor: (t, Color.t) => unit; let setAntiAlias: (t, bool) => unit; - let setAutohinted: (t, bool) => unit; - let isAutohinted: t => bool; - - let setHinting: (t, Hinting.t) => unit; - let getHinting: t => Hinting.t; - let setStyle: (t, style) => unit; let setStrokeWidth: (t, float) => unit; let setImageFilter: (t, ImageFilter.t) => unit; + let setAlpha: (t, float) => unit; + + let setShader: (t, Shader.t) => unit; +}; + +module Font: { + type t = SkiaWrapped.Font.t; + + let makeDefault: unit => t; + let makeWithValues: (Typeface.t, float, float, float) => t; + let measureText: + (t, string, TextEncoding.t, option(Rect.t), option(Paint.t)) => float; + let getFontMetrics: (t, SkiaWrapped.FontMetrics.t) => float; let setTypeface: (t, Typeface.t) => unit; - let setLcdRenderText: (t, bool) => unit; - let setSubpixelText: (t, bool) => unit; let setTextSize: (t, float) => unit; - let setAlpha: (t, float) => unit; - let getFontMetrics: (t, FontMetrics.t, float) => float; - let measureText: (t, string, option(Rect.t)) => float; - let setTextEncoding: (t, TextEncoding.t) => unit; - let getTextEncoding: t => TextEncoding.t; + let setSubpixelText: (t, bool) => unit; - let setShader: (t, Shader.t) => unit; + let setAutohinted: (t, bool) => unit; + let isAutohinted: t => bool; + + let getHinting: t => Hinting.t; + let setHinting: (t, Hinting.t) => unit; }; module IRect: { @@ -448,7 +453,8 @@ module Canvas: { let drawCircle: (t, float, float, float, Paint.t) => unit; let drawRRect: (t, RRect.t, Paint.t) => unit; let drawPath: (t, Path.t, Paint.t) => unit; - let drawText: (t, string, float, float, Paint.t) => unit; + let drawText: + (t, string, TextEncoding.t, float, float, Font.t, Paint.t) => unit; let drawImage: (t, Image.t, float, float, option(Paint.t)) => unit; let drawImageRect: (t, Image.t, option(Rect.t), Rect.t, option(Paint.t)) => unit; diff --git a/src/reason-skia/config/discover.re b/src/reason-skia/config/discover.re index b743bb4c5..ceb6ffbcb 100644 --- a/src/reason-skia/config/discover.re +++ b/src/reason-skia/config/discover.re @@ -70,7 +70,7 @@ let () = { [] @ ["-I" ++ getenv("SDL2_INCLUDE_PATH")] @ ["-I" ++ getenv("SKIA_INCLUDE_PATH")] - @ ["-I" ++ getenv("SKIA_INCLUDE_PATH") ++ "/c"] + @ ["-I" ++ Filename.dirname(getenv("SKIA_INCLUDE_PATH"))] | Linux => [] @@ -78,7 +78,7 @@ let () = { @ ["-lskia"] @ ["-I" ++ getenv("SDL2_INCLUDE_PATH")] @ ["-I" ++ getenv("SKIA_INCLUDE_PATH")] - @ ["-I" ++ getenv("SKIA_INCLUDE_PATH") ++ "/c"] + @ ["-I" ++ Filename.dirname(getenv("SKIA_INCLUDE_PATH"))] @ ["-L" ++ getenv("SKIA_LIB_PATH")] @ ["-L" ++ getenv("SDL2_LIB_PATH")] @ ["-L" ++ getenv("JPEG_LIB_PATH")] @@ -90,7 +90,7 @@ let () = { @ ["-std=c++1y"] @ ["-I" ++ getenv("SDL2_INCLUDE_PATH")] @ ["-I" ++ getenv("SKIA_INCLUDE_PATH")] - @ ["-I" ++ getenv("SKIA_INCLUDE_PATH") ++ "/c"] + @ ["-I" ++ Filename.dirname(getenv("SKIA_INCLUDE_PATH"))] | _ => failwith("cflags: unknown platform") }; diff --git a/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re b/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re index d451a68e7..cbbcab407 100644 --- a/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re +++ b/src/reason-skia/wrapped/bindings/SkiaWrappedBindings.re @@ -79,7 +79,7 @@ module M = (F: FOREIGN) => { let makeFromName = foreign( - "sk_typeface_create_from_name_with_font_style", + "sk_typeface_create_from_name", string @-> FontStyle.t @-> returning(ptr_opt(SkiaTypes.Typeface.t)), ); @@ -136,6 +136,61 @@ module M = (F: FOREIGN) => { getf(!@metrics, SkiaTypes.FontMetrics.avgCharacterWidth); }; + module Font = { + type t = ptr(structure(SkiaTypes.Font.t)); + let t = ptr(SkiaTypes.Font.t); + + let makeDefault = foreign("sk_font_new", void @-> returning(t)); + let makeWidthValues = + foreign( + "sk_font_new_with_values", + ptr(SkiaTypes.Typeface.t) + @-> float + @-> float + @-> float + @-> returning(t), + ); + let getFontMetrics = + foreign( + "sk_font_get_metrics", + t @-> FontMetrics.t @-> returning(float), + ); + let measureText = + foreign( + "sk_font_measure_text", + t + @-> string + @-> int + @-> TextEncoding.t + @-> ptr_opt(SkiaTypes.Rect.t) + @-> ptr_opt(SkiaTypes.Paint.t) + @-> returning(float), + ); + + let setSubpixelText = + foreign("sk_font_set_subpixel", t @-> bool @-> returning(void)); + + let setTypeface = + foreign("sk_font_set_typeface", t @-> Typeface.t @-> returning(void)); + let setTextSize = + foreign("sk_font_set_size", t @-> float @-> returning(void)); + + let isAutohinted = + foreign("sk_font_is_force_auto_hinting", t @-> returning(bool)); + let setAutohinted = + foreign( + "sk_font_set_force_auto_hinting", + t @-> bool @-> returning(void), + ); + + let getHinting = + foreign("sk_font_get_hinting", t @-> returning(Hinting.t)); + let setHinting = + foreign("sk_font_set_hinting", t @-> Hinting.t @-> returning(void)); + + let delete = foreign("sk_font_delete", t @-> returning(void)); + }; + module ImageFilter = { type t = ptr(structure(SkiaTypes.ImageFilter.t)); let t = ptr(SkiaTypes.ImageFilter.t); @@ -247,67 +302,12 @@ module M = (F: FOREIGN) => { let setStrokeWidth = foreign("sk_paint_set_stroke_width", t @-> float @-> returning(void)); - let setTypeface = - foreign("sk_paint_set_typeface", t @-> Typeface.t @-> returning(void)); - - let setLcdRenderText = - foreign( - "sk_paint_set_lcd_render_text", - t @-> bool @-> returning(void), - ); - - let setSubpixelText = - foreign("sk_paint_set_subpixel_text", t @-> bool @-> returning(void)); - - let setTextSize = - foreign("sk_paint_set_textsize", t @-> float @-> returning(void)); - - let getFontMetrics = - foreign( - "sk_paint_get_fontmetrics", - t @-> ptr(SkiaTypes.FontMetrics.t) @-> float @-> returning(float), - ); - - let isAutohinted = - foreign("sk_paint_is_autohinted", t @-> returning(bool)); - - let setAutohinted = - foreign("sk_paint_set_autohinted", t @-> bool @-> returning(void)); - - let isAutohinted = - foreign("sk_paint_is_autohinted", t @-> returning(bool)); - - let getHinting = - foreign("sk_paint_get_hinting", t @-> returning(Hinting.t)); - - let setHinting = - foreign("sk_paint_set_hinting", t @-> Hinting.t @-> returning(void)); - - let measureText = - foreign( - "sk_paint_measure_text", - t - @-> string - @-> int - @-> ptr_opt(SkiaTypes.Rect.t) - @-> returning(float), - ); - let setImageFilter = foreign( "sk_paint_set_imagefilter", t @-> ImageFilter.t @-> returning(void), ); - let getTextEncoding = - foreign("sk_paint_get_text_encoding", t @-> returning(TextEncoding.t)); - - let setTextEncoding = - foreign( - "sk_paint_set_text_encoding", - t @-> TextEncoding.t @-> returning(void), - ); - let setShader = foreign("sk_paint_set_shader", t @-> Shader.t @-> returning(void)); }; @@ -406,25 +406,49 @@ module M = (F: FOREIGN) => { perspective1, perspective2, ) => { - let mat = getf(!@matrix, SkiaTypes.Matrix.mat); - CArray.set(mat, 0, scaleX); - CArray.set(mat, 1, skewX); - CArray.set(mat, 2, translateX); - CArray.set(mat, 3, skewY); - CArray.set(mat, 4, scaleY); - CArray.set(mat, 5, translateY); - CArray.set(mat, 6, perspective0); - CArray.set(mat, 7, perspective1); - CArray.set(mat, 8, perspective2); + let mat = !@matrix; + setf(mat, SkiaTypes.Matrix.scaleX, scaleX); + setf(mat, SkiaTypes.Matrix.skewX, skewX); + setf(mat, SkiaTypes.Matrix.transX, translateX); + setf(mat, SkiaTypes.Matrix.skewY, skewY); + setf(mat, SkiaTypes.Matrix.scaleY, scaleY); + setf(mat, SkiaTypes.Matrix.transY, translateY); + setf(mat, SkiaTypes.Matrix.persp0, perspective0); + setf(mat, SkiaTypes.Matrix.persp1, perspective1); + setf(mat, SkiaTypes.Matrix.persp2, perspective2); }; + //TODO: prevent out of bound with variant ? + let get = (matrix, index) => { - let mat = getf(!@matrix, SkiaTypes.Matrix.mat); - CArray.get(mat, index); + let mat = !@matrix; + switch (index) { + | 0 => getf(mat, SkiaTypes.Matrix.scaleX) + | 1 => getf(mat, SkiaTypes.Matrix.skewX) + | 2 => getf(mat, SkiaTypes.Matrix.transX) + | 3 => getf(mat, SkiaTypes.Matrix.skewY) + | 4 => getf(mat, SkiaTypes.Matrix.scaleY) + | 5 => getf(mat, SkiaTypes.Matrix.transY) + | 6 => getf(mat, SkiaTypes.Matrix.persp0) + | 7 => getf(mat, SkiaTypes.Matrix.persp1) + | 8 => getf(mat, SkiaTypes.Matrix.persp2) + | _ => assert(false) + }; }; let set = (matrix, index, value) => { - let mat = getf(!@matrix, SkiaTypes.Matrix.mat); - CArray.set(mat, index, value); + let mat = !@matrix; + switch (index) { + | 0 => setf(mat, SkiaTypes.Matrix.scaleX, value) + | 1 => setf(mat, SkiaTypes.Matrix.skewX, value) + | 2 => setf(mat, SkiaTypes.Matrix.transX, value) + | 3 => setf(mat, SkiaTypes.Matrix.skewY, value) + | 4 => setf(mat, SkiaTypes.Matrix.scaleY, value) + | 5 => setf(mat, SkiaTypes.Matrix.transY, value) + | 6 => setf(mat, SkiaTypes.Matrix.persp0, value) + | 7 => setf(mat, SkiaTypes.Matrix.persp1, value) + | 8 => setf(mat, SkiaTypes.Matrix.persp2, value) + | _ => assert(false) + }; }; let invert = @@ -864,12 +888,14 @@ module M = (F: FOREIGN) => { let drawText = foreign( - "sk_canvas_draw_text", + "sk_canvas_draw_simple_text", t @-> string - @-> int + @-> size_t + @-> TextEncoding.t @-> float @-> float + @-> Font.t @-> Paint.t @-> returning(void), ); diff --git a/src/reason-skia/wrapped/c/c_stubs.h b/src/reason-skia/wrapped/c/c_stubs.h index cef32f7e4..aaba61fde 100644 --- a/src/reason-skia/wrapped/c/c_stubs.h +++ b/src/reason-skia/wrapped/c/c_stubs.h @@ -1,8 +1,8 @@ -#include "gr_context.h" -#include "sk_canvas.h" -#include "sk_paint.h" -#include "sk_shader.h" -#include "sk_types.h" +#include "include/c/gr_context.h" +#include "include/c/sk_canvas.h" +#include "include/c/sk_paint.h" +#include "include/c/sk_shader.h" +#include "include/c/sk_types.h" #include diff --git a/src/reason-skia/wrapped/lib/raw_bindings.c b/src/reason-skia/wrapped/lib/raw_bindings.c index e5db19cd4..d91afe15a 100644 --- a/src/reason-skia/wrapped/lib/raw_bindings.c +++ b/src/reason-skia/wrapped/lib/raw_bindings.c @@ -5,13 +5,13 @@ */ #include "c_stubs.h" -#include "sk_canvas.h" -#include "sk_matrix.h" -#include "sk_paint.h" -#include "sk_types.h" -#include "sk_typeface.h" -#include "sk_data.h" -#include "sk_stream.h" +#include "include/c/sk_canvas.h" +#include "include/c/sk_matrix.h" +#include "include/c/sk_paint.h" +#include "include/c/sk_types.h" +#include "include/c/sk_typeface.h" +#include "include/c/sk_data.h" +#include "include/c/sk_stream.h" #include #include diff --git a/src/reason-skia/wrapped/stubgen/stubgen.ml b/src/reason-skia/wrapped/stubgen/stubgen.ml index ca3cfa9fb..a4d0af1d6 100644 --- a/src/reason-skia/wrapped/stubgen/stubgen.ml +++ b/src/reason-skia/wrapped/stubgen/stubgen.ml @@ -2,18 +2,19 @@ let prefix = "skia_wrapped_stub" let prologue = " #include \"c_stubs.h\" -#include \"gr_context.h\" -#include \"sk_canvas.h\" -#include \"sk_data.h\" -#include \"sk_image.h\" -#include \"sk_imagefilter.h\" -#include \"sk_paint.h\" -#include \"sk_path.h\" -#include \"sk_surface.h\" -#include \"sk_rrect.h\" -#include \"sk_matrix.h\" -#include \"sk_typeface.h\" -#include \"sk_stream.h\" +#include \"include/c/gr_context.h\" +#include \"include/c/sk_canvas.h\" +#include \"include/c/sk_data.h\" +#include \"include/c/sk_image.h\" +#include \"include/c/sk_imagefilter.h\" +#include \"include/c/sk_paint.h\" +#include \"include/c/sk_path.h\" +#include \"include/c/sk_surface.h\" +#include \"include/c/sk_rrect.h\" +#include \"include/c/sk_matrix.h\" +#include \"include/c/sk_typeface.h\" +#include \"include/c/sk_font.h\" +#include \"include/c/sk_stream.h\" " let () = diff --git a/src/reason-skia/wrapped/stubgen/types_stubgen.ml b/src/reason-skia/wrapped/stubgen/types_stubgen.ml index 71656aa5f..58eae50f0 100644 --- a/src/reason-skia/wrapped/stubgen/types_stubgen.ml +++ b/src/reason-skia/wrapped/stubgen/types_stubgen.ml @@ -1,7 +1,7 @@ let prefix = "skia_wrapped_stub" let prologue = " -#include \"sk_types.h\" +#include \"include/c/sk_types.h\" " let () = diff --git a/src/reason-skia/wrapped/types/SkiaWrappedTypes.re b/src/reason-skia/wrapped/types/SkiaWrappedTypes.re index aa911db33..dd15b164f 100644 --- a/src/reason-skia/wrapped/types/SkiaWrappedTypes.re +++ b/src/reason-skia/wrapped/types/SkiaWrappedTypes.re @@ -25,12 +25,12 @@ module M = (T: TYPE) => { let t = skiaCEnum( - "sk_paint_hinting_t", + "sk_font_hinting_t", [ - (NoHinting, "NO_HINTING_SK_PAINT_HINTING"), - (SlightHinting, "SLIGHT_HINTING_SK_PAINT_HINTING"), - (NormalHinting, "NORMAL_HINTING_SK_PAINT_HINTING"), - (FullHinting, "FULL_HINTING_SK_PAINT_HINTING"), + (NoHinting, "NONE_SK_FONT_HINTING"), + (SlightHinting, "SLIGHT_SK_FONT_HINTING"), + (NormalHinting, "NORMAL_SK_FONT_HINTING"), + (FullHinting, "FULL_SK_FONT_HINTING"), ], ); }; @@ -85,6 +85,12 @@ module M = (T: TYPE) => { type t; let t: typ(structure(t)) = structure("sk_stream_t"); let t = typedef(t, "sk_stream_t"); + + module Asset = { + type t; + let t: typ(structure(t)) = structure("sk_stream_asset_t"); + let t = typedef(t, "sk_stream_asset_t"); + }; }; module Typeface = { @@ -93,6 +99,13 @@ module M = (T: TYPE) => { let t = typedef(t, "sk_typeface_t"); }; + module Font = { + type t; + + let t: typ(structure(t)) = structure("sk_font_t"); + let t = typedef(t, "sk_font_t"); + }; + module FontManager = { type t; @@ -209,7 +222,15 @@ module M = (T: TYPE) => { module Matrix = { type t; let t: typ(structure(t)) = structure("sk_matrix_t"); - let mat = field(t, "mat", array(9, float)); + let scaleX = field(t, "scaleX", float); + let skewX = field(t, "skewX", float); + let transX = field(t, "transX", float); + let skewY = field(t, "skewY", float); + let scaleY = field(t, "scaleY", float); + let transY = field(t, "transY", float); + let persp0 = field(t, "persp0", float); + let persp1 = field(t, "persp1", float); + let persp2 = field(t, "persp2", float); seal(t); let t = typedef(t, "sk_matrix_t"); }; diff --git a/test/reason-skia/PaintTest.re b/test/reason-skia/PaintTest.re index 6bc9fa7de..1e6ae1ec8 100644 --- a/test/reason-skia/PaintTest.re +++ b/test/reason-skia/PaintTest.re @@ -4,24 +4,22 @@ open TestFramework; describe("Paint", ({describe, _}) => { describe("hinting", ({test, _}) => { test("get / set isAutohinted", ({expect, _}) => { - let paint = Paint.make(); + let font = Font.makeDefault(); - Paint.setAutohinted(paint, true); - expect.equal(paint |> Paint.isAutohinted, true); + Font.setAutohinted(font, true); + expect.equal(font |> Font.isAutohinted, true); - Paint.setAutohinted(paint, false); - expect.equal(paint |> Paint.isAutohinted, false); + Font.setAutohinted(font, false); + expect.equal(font |> Font.isAutohinted, false); }); test("get / set hinting", ({expect, _}) => { - let paint = Paint.make(); + let font = Font.makeDefault(); - Paint.setTextEncoding(paint, Utf8); + Font.setHinting(font, FullHinting); + expect.equal(font |> Font.getHinting, FullHinting); - Paint.setHinting(paint, FullHinting); - expect.equal(paint |> Paint.getHinting, FullHinting); - - Paint.setHinting(paint, NoHinting); - expect.equal(paint |> Paint.getHinting, NoHinting); + Font.setHinting(font, NoHinting); + expect.equal(font |> Font.getHinting, NoHinting); }); }) });