From b893835866a7bddd87761d7707e97de8090a45ca Mon Sep 17 00:00:00 2001 From: lauchmelder Date: Thu, 6 Mar 2025 23:55:12 +0100 Subject: [PATCH] fix crash in json encoding --- client/src/components/glyphview.svelte | 65 ++++++++++++++++++++++++-- server/src/font/glyph_data.rs | 1 + server/src/writer.rs | 2 + server/src/writer/json.rs | 3 ++ 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/client/src/components/glyphview.svelte b/client/src/components/glyphview.svelte index 0ba018c..9147baa 100644 --- a/client/src/components/glyphview.svelte +++ b/client/src/components/glyphview.svelte @@ -8,7 +8,10 @@ interface ContourPoint { x: number, - y: number + y: number, + + on_curve: boolean, + is_virtual: boolean, }; interface ContourElement { @@ -26,13 +29,15 @@ contours: Contour[] }; - let glyphData: GlyphData= $state({ + let glyphData: GlyphData = $state({ bounding_box: { xmin: 0, xmax: 0, ymin: 0, ymax: 0 }, contours: [] }); + let pointTooltip: string = $state(""); + function getPathString(contour: Contour): string { - if (contour.elements?.length === 0) { + if (contour.elements?.length == 0 || contour.points?.length == 0) { return ""; } @@ -45,7 +50,11 @@ return ""; } - let result = `M${contour.points[firstPoint].x} -${contour.points[firstPoint].y} ` + if (firstPoint < 0 || firstPoint >= contour.points.length) { + return ""; + } + + let result = `M${contour.points[firstPoint].x} -${contour.points[firstPoint]?.y} ` contour.elements.forEach((element) => { if (element.Bezier) { let control = contour.points[element.Bezier[1]]; @@ -62,6 +71,31 @@ return result; } + function getViewBox(data: GlyphData): string { + const padding = 0.1; + let width = data.bounding_box.xmax - data.bounding_box.xmin; + let height = data.bounding_box.ymax - data.bounding_box.ymin; + + let bbox: BoundingBox = { + xmin: data.bounding_box.xmin - padding * width, + xmax: (data.bounding_box.xmax - data.bounding_box.xmin) + 2 * padding * width, + ymin: (-data.bounding_box.ymax) - padding * width, + ymax: (data.bounding_box.ymax - data.bounding_box.ymin) + 2 * padding * width + }; + + return `${bbox.xmin} ${bbox.ymin} ${bbox.xmax} ${bbox.ymax}`; + } + + function getFillColor(point: ContourPoint): string { + if (point.on_curve) { + return "blue"; + } else if (point.is_virtual) { + return "green"; + } + + return "red"; + } + let { selectedChar = "", loading = $bindable() } = $props(); $effect(() => { @@ -87,8 +121,10 @@
+

{ pointTooltip }

+ @@ -98,6 +134,15 @@ style="fill:none; stroke:black; stroke-width: 3" d="{getPathString(contour)}" /> + + {#each contour.points as point} + + {/each} {/each}
@@ -107,4 +152,14 @@ max-height: 50vh; max-width: 50vw; } + + .glyph-point { + r: 13; + transition: ease-out 0.2s r; + } + + .glyph-point:hover { + r: 20; + transition: ease-out 0.2s r; + } diff --git a/server/src/font/glyph_data.rs b/server/src/font/glyph_data.rs index 0344751..d126fb0 100644 --- a/server/src/font/glyph_data.rs +++ b/server/src/font/glyph_data.rs @@ -287,6 +287,7 @@ impl<'a> SplineIter<'a> { if point.on_curve { self.last_point = Some(IndexedGlyphPoint { point, index }); self.first_point = Some(IndexedGlyphPoint { point, index }); + self.final_control = None; return Ok(()); } else { self.final_control = Some(IndexedGlyphPoint { point, index }); diff --git a/server/src/writer.rs b/server/src/writer.rs index 4fcc696..8dfd101 100644 --- a/server/src/writer.rs +++ b/server/src/writer.rs @@ -24,6 +24,8 @@ pub trait Visitor: Sized { self.write_spline(&spline_element) }); + debug!("done writing splines"); + self.write_suffix(); } } diff --git a/server/src/writer/json.rs b/server/src/writer/json.rs index d98eb1c..e9c9801 100644 --- a/server/src/writer/json.rs +++ b/server/src/writer/json.rs @@ -1,5 +1,6 @@ use std::io::Write; +use log::debug; use serde::Serialize; use crate::font::{GlyphHeader, GlyphPoint, SplineElement, SplineElementData}; @@ -85,11 +86,13 @@ impl Visitor for JsonWriter { } fn write_spline(&mut self, spline: &SplineElement) { + debug!("index correction: {}", self.index_correction); let indexed_spline = match spline.data { SplineElementData::Line(start, end) => ContourElement::Line(start.index - self.index_correction, end.index - self.index_correction), SplineElementData::Bezier(start, control, end) => ContourElement::Bezier(start.index - self.index_correction, control.index - self.index_correction, end.index - self.index_correction) }; + debug!("pushing spline to contours array at position {}/{}", self.current_contour, self.body.contours.len()); self.body.contours[self.current_contour].elements.push(indexed_spline); if spline.is_last { self.index_correction = self.body.contours[self.current_contour].points.len();