Skip to content

Commit

Permalink
Merge pull request #1063 from ZeLonewolf/zlw-shield-ts
Browse files Browse the repository at this point in the history
Convert shield.js to typescript
  • Loading branch information
ZeLonewolf authored May 15, 2024
2 parents 13bd5bb + bd0993f commit 7488b82
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 92 deletions.
78 changes: 41 additions & 37 deletions shieldlib/src/shield.js → shieldlib/src/shield.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import * as ShieldText from "./shield_text";
import * as ShieldDraw from "./shield_canvas_draw";
import * as Gfx from "./screen_gfx";
import { drawBanners, drawBannerHalos, getBannerCount } from "./shield_banner";
import { ShieldRenderingContext } from "./shield_renderer";
import { Dimension, RouteDefinition, ShieldDefinition, ShieldDefinitions } from "./types";
import { TextPlacement } from "./shield_text";
import { StyleImage } from "maplibre-gl";

function compoundShieldSize(r, dimension, bannerCount) {
function compoundShieldSize(r: ShieldRenderingContext, dimension: Dimension, bannerCount: number): Dimension {
return {
width: dimension.width,
height:
Expand All @@ -14,7 +18,7 @@ function compoundShieldSize(r, dimension, bannerCount) {
};
}

export function isValidRef(ref) {
export function isValidRef(ref: string): boolean {
return ref !== null && ref.length !== 0 && ref.length <= 6;
}

Expand All @@ -27,24 +31,24 @@ export function isValidRef(ref) {
* @param {*} routeDef - route tagging from OSM
* @returns shield blank or null if no shield exists
*/
function getRasterShieldBlank(r, shieldDef, routeDef) {
var shieldArtwork = null;
var textLayout;
var bannerCount = 0;
var bounds;
function getRasterShieldBlank(r: ShieldRenderingContext, shieldDef: ShieldDefinition, routeDef: RouteDefinition): StyleImage {
let shieldArtwork = null;
let textPlacement: TextPlacement;
let bannerCount: number = 0;
let bounds: Dimension;

if (Array.isArray(shieldDef.spriteBlank)) {
for (var i = 0; i < shieldDef.spriteBlank.length; i++) {
shieldArtwork = r.spriteRepo.getSprite(shieldDef.spriteBlank[i]);

bounds = compoundShieldSize(r, shieldArtwork.data, bannerCount);
textLayout = ShieldText.layoutShieldTextFromDef(
textPlacement = ShieldText.layoutShieldTextFromDef(
r,
routeDef.ref,
shieldDef,
bounds
);
if (textLayout.fontPx > r.px(Gfx.fontSizeThreshold)) {
if (textPlacement.fontPx > r.px(Gfx.fontSizeThreshold)) {
break;
}
}
Expand All @@ -55,16 +59,16 @@ function getRasterShieldBlank(r, shieldDef, routeDef) {
return shieldArtwork;
}

function textColor(shieldDef) {
function textColor(shieldDef: ShieldDefinition): string {
if (shieldDef != null && typeof shieldDef.textColor != "undefined") {
return shieldDef.textColor;
}
return "black";
}

function getDrawFunc(shieldDef) {
function getDrawFunc(shieldDef: ShieldDefinition): (r: ShieldRenderingContext, ctx: CanvasRenderingContext2D, ref: string) => void {
if (typeof shieldDef.shapeBlank != "undefined") {
return (r, ctx, ref) =>
return (r: ShieldRenderingContext, ctx: CanvasRenderingContext2D, ref: string) =>
ShieldDraw.draw(
r,
shieldDef.shapeBlank.drawFunc,
Expand All @@ -73,17 +77,18 @@ function getDrawFunc(shieldDef) {
ref
);
}
return ShieldDraw.blank;
console.warn(`Draw function not defined in:\n${shieldDef}`);
return (r: ShieldRenderingContext, ctx: CanvasRenderingContext2D, ref: string) => {};
}

function getDrawHeight(r, shieldDef) {
function getDrawHeight(r: ShieldRenderingContext, shieldDef: ShieldDefinition): number {
if (typeof shieldDef.shapeBlank != "undefined") {
return ShieldDraw.shapeHeight(r, shieldDef.shapeBlank.drawFunc);
}
return r.shieldSize();
}

function drawShieldText(r, ctx, shieldDef, routeDef, shieldBounds) {
function drawShieldText(r: ShieldRenderingContext, ctx: CanvasRenderingContext2D, shieldDef: ShieldDefinition, routeDef: RouteDefinition, shieldBounds: Dimension): CanvasRenderingContext2D {
if (shieldDef.notext) {
//If the shield definition says not to draw a ref, ignore ref
return ctx;
Expand All @@ -97,8 +102,8 @@ function drawShieldText(r, ctx, shieldDef, routeDef, shieldBounds) {
shieldBounds
);

if (typeof r.options.SHIELD_TEXT_HALO_COLOR_OVERRIDE !== "undefined") {
ctx.strokeStyle = options.SHIELD_TEXT_HALO_COLOR_OVERRIDE;
if (typeof r.debugOptions?.shieldTextHaloColor !== "undefined") {
ctx.strokeStyle = r.debugOptions.shieldTextHaloColor;
ShieldText.drawShieldHaloText(r, ctx, routeDef.ref, textLayout);
} else if (shieldDef.textHaloColor) {
ctx.strokeStyle = shieldDef.textHaloColor;
Expand All @@ -108,23 +113,23 @@ function drawShieldText(r, ctx, shieldDef, routeDef, shieldBounds) {
ctx.fillStyle = textColor(shieldDef);
ShieldText.renderShieldText(r, ctx, routeDef.ref, textLayout);

if (r.options.SHIELD_TEXT_BBOX_COLOR) {
ctx.strokeStyle = r.options.SHIELD_TEXT_BBOX_COLOR; //TODO move to debugOptions
if (r.debugOptions?.shieldTextBboxColor) {
ctx.strokeStyle = r.debugOptions.shieldTextBboxColor;
ctx.lineWidth = r.px(1);
ctx.strokeRect(
r.px(shieldDef.padding.left - 0.5),
r.px(shieldDef.padding.top - 0.5),
shieldBounds.width -
r.px(shieldDef.padding.left + shieldDef.padding.right - 1),
r.px(shieldDef.padding.left + shieldDef.padding.right - 1),
shieldBounds.height -
r.px(shieldDef.padding.top + shieldDef.padding.bottom - 1)
r.px(shieldDef.padding.top + shieldDef.padding.bottom - 1)
);
}

return ctx;
}

export function missingIconLoader(r, routeDef, spriteID, update) {
export function missingIconLoader(r: ShieldRenderingContext, routeDef: RouteDefinition, spriteID: string, update: boolean): void {
let ctx = generateShieldCtx(r, routeDef);
if (ctx == null) {
// Want to return null here, but that gives a corrupted display. See #243
Expand All @@ -134,7 +139,7 @@ export function missingIconLoader(r, routeDef, spriteID, update) {
storeSprite(r, spriteID, ctx, update);
}

function storeSprite(r, id, ctx, update) {
function storeSprite(r: ShieldRenderingContext, id: string, ctx: CanvasRenderingContext2D, update: boolean): void {
const imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
r.spriteRepo.putSprite(
id,
Expand All @@ -148,11 +153,11 @@ function storeSprite(r, id, ctx, update) {
);
}

export function storeNoShield(r, id) {
storeSprite(r, id, r.emptySprite());
export function storeNoShield(r: ShieldRenderingContext, id: string): void {
storeSprite(r, id, r.emptySprite(), false);
}

function refForDefs(routeDef, shieldDef) {
function refForDefs(routeDef: RouteDefinition, shieldDef: ShieldDefinition) {
// Handle special case for manually-applied abbreviations
if (
shieldDef.refsByName &&
Expand All @@ -164,7 +169,7 @@ function refForDefs(routeDef, shieldDef) {
return routeDef.ref;
}

function getShieldDef(shields, routeDef) {
function getShieldDef(shields: ShieldDefinitions, routeDef: RouteDefinition): ShieldDefinition {
if (!shields) {
//This occurs if the ShieldJSON is loaded from the network and hasn't loaded yet.
return null;
Expand All @@ -179,7 +184,8 @@ function getShieldDef(shields, routeDef) {
if (shieldDef == null) {
// Default to plain black text with halo and no background shield
console.debug("Generic shield for", JSON.stringify(routeDef));
return isValidRef(routeDef.ref) ? shields.default : null;

return isValidRef(routeDef.ref) ? shields["default"] : null;
}

var ref = refForDefs(routeDef, shieldDef);
Expand Down Expand Up @@ -222,7 +228,7 @@ function getShieldDef(shields, routeDef) {
* Reformats an alphanumeric ref as Roman numerals, preserving any alphabetic
* suffix.
*/
export function romanizeRef(ref) {
export function romanizeRef(ref: string): string {
let number = parseInt(ref, 10);
if (isNaN(number)) {
return ref;
Expand All @@ -246,7 +252,7 @@ export function romanizeRef(ref) {
return roman + ref.slice(number.toString().length);
}

function getDrawnShieldBounds(r, shieldDef, ref) {
function getDrawnShieldBounds(r: ShieldRenderingContext, shieldDef: ShieldDefinition, ref: string): Dimension {
let width = Math.max(
r.shieldSize(),
ShieldDraw.computeWidth(
Expand All @@ -261,19 +267,17 @@ function getDrawnShieldBounds(r, shieldDef, ref) {
return { width, height };
}

function bannerAreaHeight(r, bannerCount) {
function bannerAreaHeight(r: ShieldRenderingContext, bannerCount: number): number {
if (bannerCount === 0) {
return 0;
}
return (
bannerCount * r.px(r.options.bannerHeight) +
return bannerCount * r.px(r.options.bannerHeight) +
//No padding after last banner
(bannerCount - 1) * r.px(r.options.bannerPadding)
);
(bannerCount - 1) * r.px(r.options.bannerPadding);
}

export function generateShieldCtx(r, routeDef) {
let shieldDef = getShieldDef(r.shieldDef, routeDef);
export function generateShieldCtx(r: ShieldRenderingContext, routeDef: RouteDefinition): CanvasRenderingContext2D {
let shieldDef: ShieldDefinition = getShieldDef(r.shieldDef, routeDef);

if (shieldDef == null) {
return null;
Expand Down
14 changes: 0 additions & 14 deletions shieldlib/src/shield_canvas_draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,6 @@ function ellipse(
return width;
}

export function blank(r: ShieldRenderingContext, ref: string) {
var shieldWidth =
ShieldText.calculateTextWidth(r, ref, r.px(genericShieldFontSize)) +
r.px(2);
var width = Math.max(
r.px(minGenericShieldWidth),
Math.min(r.px(maxGenericShieldWidth), shieldWidth)
);
return r.gfxFactory.createGraphics({
width: width,
height: r.shieldSize(),
});
}

export function roundedRectangle(
r: ShieldRenderingContext,
ctx: CanvasRenderingContext2D,
Expand Down
Loading

0 comments on commit 7488b82

Please sign in to comment.