more work
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { getImage } from "./draw.ts";
|
||||
import { parseFont, stringifyFont } from "./fonthelper.ts";
|
||||
|
||||
export type Piece =
|
||||
| { type: "text"; text: string; isBold?: boolean; isItalic?: boolean }
|
||||
@@ -18,6 +19,7 @@ type PieceMeasure = {
|
||||
type Line = {
|
||||
pieces: {
|
||||
piece: Piece;
|
||||
measure: PieceMeasure;
|
||||
xOffset: number;
|
||||
}[];
|
||||
width: number;
|
||||
@@ -108,10 +110,12 @@ const breakPiece = pieceDef({
|
||||
const coinPiece = pieceDef({
|
||||
type: "coin",
|
||||
measure(context, _piece) {
|
||||
context.save();
|
||||
const metrics = context.measureText(" ");
|
||||
const height =
|
||||
metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
|
||||
const coinImage = getImage("coin");
|
||||
context.restore();
|
||||
return {
|
||||
type: "content",
|
||||
width: coinImage.width * (height / coinImage.height),
|
||||
@@ -131,6 +135,12 @@ const coinPiece = pieceDef({
|
||||
measure.width,
|
||||
height
|
||||
);
|
||||
const fontInfo = parseFont(context.font);
|
||||
fontInfo.family = ["DominionSpecial"];
|
||||
fontInfo.weight = "bold";
|
||||
fontInfo.size = parseInt(fontInfo.size.toString()) * 1.2;
|
||||
const font = stringifyFont(fontInfo);
|
||||
context.font = font;
|
||||
context.fillStyle = "black";
|
||||
context.textAlign = "center";
|
||||
context.fillText(piece.text, x + measure.width / 2, y);
|
||||
@@ -140,7 +150,7 @@ const coinPiece = pieceDef({
|
||||
|
||||
const pieceDefs = [textPiece, spacePiece, breakPiece, coinPiece];
|
||||
|
||||
let tools: PieceTools = {} as any;
|
||||
const tools: PieceTools = {} as any;
|
||||
|
||||
const measurePiece = (context: CanvasRenderingContext2D, piece: Piece) => {
|
||||
const def = pieceDefs.find((def) => def.type === piece.type)!;
|
||||
@@ -188,7 +198,7 @@ export const measureDominionText = async (
|
||||
for (const pieceInfo of data) {
|
||||
const line = lines[lines.length - 1]!;
|
||||
if (pieceInfo.measure.type === "break") {
|
||||
line.pieces.push({ piece: pieceInfo.piece, xOffset: line.width });
|
||||
line.pieces.push({ ...pieceInfo, xOffset: line.width });
|
||||
line.width += pieceInfo.measure.width;
|
||||
line.ascent = Math.max(line.ascent, pieceInfo.measure.ascent);
|
||||
line.descent = Math.max(line.descent, pieceInfo.measure.descent);
|
||||
@@ -196,14 +206,14 @@ export const measureDominionText = async (
|
||||
} else {
|
||||
if (line.width + pieceInfo.measure.width > maxWidth) {
|
||||
lines.push({
|
||||
pieces: [{ piece: pieceInfo.piece, xOffset: 0 }],
|
||||
pieces: [{ ...pieceInfo, xOffset: 0 }],
|
||||
width: pieceInfo.measure.width,
|
||||
ascent: pieceInfo.measure.ascent,
|
||||
descent: pieceInfo.measure.descent,
|
||||
});
|
||||
} else {
|
||||
line.pieces.push({
|
||||
piece: pieceInfo.piece,
|
||||
...pieceInfo,
|
||||
xOffset: line.width,
|
||||
});
|
||||
line.width += pieceInfo.measure.width;
|
||||
@@ -216,7 +226,15 @@ export const measureDominionText = async (
|
||||
}
|
||||
}
|
||||
return {
|
||||
lines,
|
||||
lines: lines.map((line) => {
|
||||
while (
|
||||
line.pieces[line.pieces.length - 1] &&
|
||||
line.pieces[line.pieces.length - 1]!.measure.type === "space"
|
||||
) {
|
||||
line.pieces = line.pieces.slice(0, -1);
|
||||
}
|
||||
return line;
|
||||
}),
|
||||
width: Math.max(...lines.map((line) => line.width)),
|
||||
height: lines
|
||||
.map((line) => line.ascent + line.descent)
|
||||
@@ -224,6 +242,8 @@ export const measureDominionText = async (
|
||||
};
|
||||
};
|
||||
|
||||
const debug = false;
|
||||
|
||||
export const renderDominionText = async (
|
||||
context: CanvasRenderingContext2D,
|
||||
pieces: Piece[],
|
||||
@@ -246,6 +266,30 @@ export const renderDominionText = async (
|
||||
x - line.width / 2 + xOffset,
|
||||
y - height / 2 + yOffset
|
||||
);
|
||||
if (debug) {
|
||||
context.save();
|
||||
context.strokeStyle = "blue";
|
||||
context.lineWidth = 5;
|
||||
const pieceMeasure = await measurePiece(context, piece);
|
||||
context.strokeRect(
|
||||
x - line.width / 2 + xOffset,
|
||||
y - height / 2 - line.ascent + yOffset,
|
||||
pieceMeasure.width,
|
||||
pieceMeasure.ascent + pieceMeasure.descent
|
||||
);
|
||||
context.strokeStyle = "red";
|
||||
context.beginPath();
|
||||
context.moveTo(
|
||||
x - line.width / 2 + xOffset - 5,
|
||||
y - height / 2 + yOffset
|
||||
);
|
||||
context.lineTo(
|
||||
x - line.width / 2 + xOffset + 5,
|
||||
y - height / 2 + yOffset
|
||||
);
|
||||
context.stroke();
|
||||
context.restore();
|
||||
}
|
||||
}
|
||||
yOffset += line.descent;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user