Skip to content

Commit

Permalink
Convert shield.js to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeLonewolf committed May 13, 2024
1 parent 9df8b99 commit d444123
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 65 deletions.
76 changes: 39 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,17 @@ function getDrawFunc(shieldDef) {
ref
);
}
return ShieldDraw.blank;
return () => ShieldDraw.blank;
}

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 +101,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 +112,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; //TODO move to debugOptions
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 +138,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 +152,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 +168,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 +183,7 @@ 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.shield["default"] : null;
}

var ref = refForDefs(routeDef, shieldDef);
Expand Down Expand Up @@ -222,7 +226,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 +250,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 +265,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
36 changes: 18 additions & 18 deletions shieldlib/src/shield_helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function ovalShield(
strokeColor: string,
textColor: string,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
return {
shapeBlank: {
Expand Down Expand Up @@ -74,7 +74,7 @@ export function circleShield(
fillColor: string,
strokeColor: string,
textColor: string
): ShieldDefinition {
): Partial<ShieldDefinition> {
return ovalShield(fillColor, strokeColor, textColor, 20);
}

Expand All @@ -94,7 +94,7 @@ export function roundedRectShield(
textColor: string,
rectWidth: number,
radius: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
radius = radius ?? 2;
return {
Expand Down Expand Up @@ -136,7 +136,7 @@ export function escutcheonDownShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
radius = radius ?? 0;
return {
Expand Down Expand Up @@ -176,7 +176,7 @@ export function fishheadDownShield(
strokeColor: string,
textColor: string,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
return {
shapeBlank: {
Expand Down Expand Up @@ -215,7 +215,7 @@ export function triangleDownShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
radius = radius ?? 2;

Expand Down Expand Up @@ -259,7 +259,7 @@ export function trapezoidDownShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
let angleInRadians = (sideAngle * Math.PI) / 180;
textColor = textColor ?? strokeColor;
radius = radius ?? 0;
Expand Down Expand Up @@ -304,7 +304,7 @@ export function trapezoidUpShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
let angleInRadians = (sideAngle * Math.PI) / 180;
textColor = textColor ?? strokeColor;
radius = radius ?? 0;
Expand Down Expand Up @@ -347,7 +347,7 @@ export function diamondShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
radius = radius ?? 2;
return {
Expand Down Expand Up @@ -393,7 +393,7 @@ export function pentagonUpShield(
radius1: number,
radius2: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
let angleInRadians = (sideAngle * Math.PI) / 180;
textColor = textColor ?? strokeColor;
radius1 = radius1 ?? 2;
Expand Down Expand Up @@ -444,7 +444,7 @@ export function homePlateDownShield(
radius1: number,
radius2: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
radius1 = radius1 ?? 2;
radius2 = radius2 ?? 2;
Expand Down Expand Up @@ -493,7 +493,7 @@ export function homePlateUpShield(
radius1: number,
radius2: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
radius1 = radius1 ?? 2;
radius2 = radius2 ?? 2;
Expand Down Expand Up @@ -540,7 +540,7 @@ export function hexagonVerticalShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
radius = radius ?? 2;
return {
Expand Down Expand Up @@ -583,7 +583,7 @@ export function hexagonHorizontalShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
let angleInRadians = (sideAngle * Math.PI) / 180;
textColor = textColor ?? strokeColor;
radius = radius ?? 2;
Expand Down Expand Up @@ -629,7 +629,7 @@ export function octagonVerticalShield(
textColor: string,
radius: number,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
let angleInRadians = (sideAngle * Math.PI) / 180;
textColor = textColor ?? strokeColor;
radius = radius ?? 2;
Expand Down Expand Up @@ -670,7 +670,7 @@ export function pillShield(
strokeColor: string,
textColor: string,
rectWidth: number
): ShieldDefinition {
): Partial<ShieldDefinition> {
textColor = textColor ?? strokeColor;
return {
shapeBlank: {
Expand Down Expand Up @@ -722,7 +722,7 @@ export function banneredShield(
export function paBeltShield(
fillColor: string,
strokeColor: string
): ShieldDefinition {
): Partial<ShieldDefinition> {
return {
notext: true,
shapeBlank: {
Expand All @@ -745,7 +745,7 @@ export function paBeltShield(
export function bransonRouteShield(
fillColor: string,
strokeColor: string
): ShieldDefinition {
): Partial<ShieldDefinition> {
return {
notext: true,
shapeBlank: {
Expand Down
Loading

0 comments on commit d444123

Please sign in to comment.