MCPcopy Create free account
hub / github.com/cursorless-dev/cursorless / processSvg

Method processSvg

src/core/Decorations.ts:251–308  ·  view source on GitHub ↗

* Creates an SVG from the hat SVG that pads, offsets and scales it to end up * in the right size / place relative to the character it will be placed over. * [This image](../images/svg-calculations.png) may or may not be helpful. * * @param fontMeasurements Info about the user's font *

(
    fontMeasurements: FontMeasurements,
    shape: HatShape,
    scaleFactor: number,
    hatVerticalOffsetEm: number
  )

Source from the content-addressed store, hash-verified

249 * @returns An object with the new SVG and its measurements
250 */
251 private processSvg(
252 fontMeasurements: FontMeasurements,
253 shape: HatShape,
254 scaleFactor: number,
255 hatVerticalOffsetEm: number
256 ) {
257 const iconPath = join(
258 this.graph.extensionContext.extensionPath,
259 "images",
260 "hats",
261 `${shape}.svg`
262 );
263 const rawSvg = readFileSync(iconPath, "utf8");
264 const { characterWidth, characterHeight, fontSize } = fontMeasurements;
265
266 const { originalViewBoxHeight, originalViewBoxWidth } =
267 this.getViewBoxDimensions(rawSvg);
268
269 const defaultHatHeightPx = DEFAULT_HAT_HEIGHT_EM * fontSize;
270 const defaultHatWidthPx =
271 (originalViewBoxWidth / originalViewBoxHeight) * defaultHatHeightPx;
272
273 const hatHeightPx = defaultHatHeightPx * scaleFactor;
274 const hatWidthPx = defaultHatWidthPx * scaleFactor;
275
276 const hatVerticalOffsetPx =
277 (DEFAULT_VERTICAL_OFFSET_EM + hatVerticalOffsetEm) * fontSize -
278 hatHeightPx / 2;
279
280 const svgWidthPx = Math.ceil(characterWidth);
281 const svgHeightPx = characterHeight + hatHeightPx + hatVerticalOffsetPx;
282
283 const newViewBoxWidth = originalViewBoxWidth * (svgWidthPx / hatWidthPx);
284 const newViewBoxHeight = newViewBoxWidth * (svgHeightPx / svgWidthPx);
285 const newViewBoxX =
286 (-(characterWidth - hatWidthPx) * (newViewBoxWidth / svgWidthPx)) / 2;
287 const newViewBoxY = 0;
288
289 const newViewBoxString = `${newViewBoxX} ${newViewBoxY} ${newViewBoxWidth} ${newViewBoxHeight}`;
290
291 if (
292 rawSvg.match(/width="[^"]+"/) == null ||
293 rawSvg.match(/height="[^"]+"/) == null
294 ) {
295 throw Error("Raw svg doesn't have height or width");
296 }
297
298 const svg = rawSvg
299 .replace(/width="[^"]+"/, `width="${svgWidthPx}px"`)
300 .replace(/height="[^"]+"/, `height="${svgHeightPx}px"`)
301 .replace(/viewBox="([^"]+)"/, `viewBox="${newViewBoxString}"`);
302
303 return {
304 svg,
305 svgHeightPx,
306 svgWidthPx,
307 };
308 }

Callers 1

constructDecorationsMethod · 0.95

Calls 1

getViewBoxDimensionsMethod · 0.95

Tested by

no test coverage detected