Skip to content

Commit

Permalink
feat: init bitmap font for msdf
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoiver committed Jan 5, 2025
1 parent cb2ed7b commit 4d52538
Show file tree
Hide file tree
Showing 20 changed files with 842 additions and 20 deletions.
107 changes: 107 additions & 0 deletions packages/core/examples/DimboR.fnt
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?xml version="1.0"?>
<font>
<info face="DimboR" size="42" bold="0" italic="0" charset="" unicode="1" stretchH="100" smooth="1" aa="1" padding="0,0,0,0" spacing="0,0"/>
<common lineHeight="41" base="32" scaleW="512" scaleH="512" pages="1" packed="0" alphaChnl="0" redChnl="0" greenChnl="0" blueChnl="0"/>
<pages>
<page id="0" file="atlas.png"/>
</pages>
<distanceField fieldType="msdf" distanceRange="5"/>
<chars count="95">
<char id="93" index="62" char="]" width="13" height="43" xoffset="-1" yoffset="-3" xadvance="11" chnl="15" x="372" y="414" page="0"/>
<char id="91" index="60" char="[" width="13" height="43" xoffset="-1" yoffset="-3" xadvance="11" chnl="15" x="380" y="458" page="0"/>
<char id="124" index="93" char="|" width="9" height="43" xoffset="-1" yoffset="-3" xadvance="7" chnl="15" x="190" y="0" page="0"/>
<char id="40" index="9" char="(" width="13" height="43" xoffset="-1" yoffset="-3" xadvance="11" chnl="15" x="372" y="215" page="0"/>
<char id="41" index="10" char=")" width="13" height="43" xoffset="-1" yoffset="-3" xadvance="11" chnl="15" x="375" y="259" page="0"/>
<char id="123" index="92" char="{" width="19" height="43" xoffset="-1" yoffset="-3" xadvance="17" chnl="15" x="386" y="215" page="0"/>
<char id="125" index="94" char="}" width="19" height="43" xoffset="-1" yoffset="-3" xadvance="17" chnl="15" x="380" y="303" page="0"/>
<char id="36" index="5" char="$" width="21" height="43" xoffset="-1" yoffset="-3" xadvance="19" chnl="15" x="389" y="259" page="0"/>
<char id="106" index="75" char="j" width="14" height="42" xoffset="-6" yoffset="2" xadvance="7" chnl="15" x="385" y="347" page="0"/>
<char id="92" index="61" char="\" width="17" height="41" xoffset="-2" yoffset="-2" xadvance="12" chnl="15" x="386" y="390" page="0"/>
<char id="47" index="16" char="/" width="17" height="41" xoffset="-2" yoffset="-2" xadvance="12" chnl="15" x="394" y="432" page="0"/>
<char id="64" index="33" char="@" width="32" height="39" xoffset="-1" yoffset="3" xadvance="30" chnl="15" x="400" y="303" page="0"/>
<char id="37" index="6" char="%" width="37" height="36" xoffset="-1" yoffset="-1" xadvance="35" chnl="15" x="394" y="474" page="0"/>
<char id="81" index="50" char="Q" width="23" height="36" xoffset="-1" yoffset="1" xadvance="20" chnl="15" x="400" y="343" page="0"/>
<char id="82" index="51" char="R" width="20" height="36" xoffset="-1" yoffset="0" xadvance="18" chnl="15" x="404" y="380" page="0"/>
<char id="83" index="52" char="S" width="21" height="36" xoffset="-1" yoffset="0" xadvance="19" chnl="15" x="424" y="343" page="0"/>
<char id="57" index="26" char="9" width="21" height="35" xoffset="-1" yoffset="0" xadvance="18" chnl="15" x="412" y="417" page="0"/>
<char id="77" index="46" char="M" width="29" height="35" xoffset="-1" yoffset="1" xadvance="27" chnl="15" x="425" y="380" page="0"/>
<char id="113" index="82" char="q" width="19" height="35" xoffset="-1" yoffset="10" xadvance="17" chnl="15" x="432" y="453" page="0"/>
<char id="103" index="72" char="g" width="19" height="35" xoffset="-1" yoffset="9" xadvance="17" chnl="15" x="434" y="416" page="0"/>
<char id="54" index="23" char="6" width="20" height="35" xoffset="-1" yoffset="0" xadvance="18" chnl="15" x="452" y="452" page="0"/>
<char id="65" index="34" char="A" width="24" height="35" xoffset="-2" yoffset="0" xadvance="20" chnl="15" x="454" y="416" page="0"/>
<char id="102" index="71" char="f" width="17" height="35" xoffset="-1" yoffset="0" xadvance="14" chnl="15" x="473" y="452" page="0"/>
<char id="121" index="90" char="y" width="19" height="34" xoffset="-1" yoffset="9" xadvance="16" chnl="15" x="491" y="0" page="0"/>
<char id="108" index="77" char="l" width="9" height="34" xoffset="-1" yoffset="1" xadvance="8" chnl="15" x="126" y="275" page="0"/>
<char id="63" index="32" char="?" width="19" height="34" xoffset="-1" yoffset="1" xadvance="18" chnl="15" x="491" y="35" page="0"/>
<char id="38" index="7" char="&amp;" width="22" height="34" xoffset="-1" yoffset="1" xadvance="19" chnl="15" x="357" y="70" page="0"/>
<char id="48" index="17" char="0" width="21" height="34" xoffset="-1" yoffset="0" xadvance="18" chnl="15" x="380" y="70" page="0"/>
<char id="66" index="35" char="B" width="21" height="34" xoffset="-1" yoffset="0" xadvance="19" chnl="15" x="390" y="105" page="0"/>
<char id="67" index="36" char="C" width="21" height="34" xoffset="-1" yoffset="1" xadvance="18" chnl="15" x="402" y="70" page="0"/>
<char id="68" index="37" char="D" width="20" height="34" xoffset="-1" yoffset="1" xadvance="18" chnl="15" x="390" y="140" page="0"/>
<char id="71" index="40" char="G" width="23" height="34" xoffset="-1" yoffset="1" xadvance="20" chnl="15" x="393" y="175" page="0"/>
<char id="72" index="41" char="H" width="21" height="34" xoffset="-1" yoffset="1" xadvance="19" chnl="15" x="411" y="140" page="0"/>
<char id="51" index="20" char="3" width="20" height="34" xoffset="-1" yoffset="0" xadvance="17" chnl="15" x="412" y="105" page="0"/>
<char id="76" index="45" char="L" width="19" height="34" xoffset="-1" yoffset="0" xadvance="17" chnl="15" x="424" y="70" page="0"/>
<char id="52" index="21" char="4" width="22" height="34" xoffset="-2" yoffset="0" xadvance="19" chnl="15" x="406" y="210" page="0"/>
<char id="79" index="48" char="O" width="22" height="34" xoffset="-1" yoffset="1" xadvance="20" chnl="15" x="417" y="175" page="0"/>
<char id="53" index="22" char="5" width="20" height="34" xoffset="-1" yoffset="0" xadvance="17" chnl="15" x="433" y="105" page="0"/>
<char id="78" index="47" char="N" width="21" height="34" xoffset="-1" yoffset="1" xadvance="19" chnl="15" x="444" y="70" page="0"/>
<char id="56" index="25" char="8" width="20" height="34" xoffset="-1" yoffset="0" xadvance="17" chnl="15" x="433" y="140" page="0"/>
<char id="85" index="54" char="U" width="21" height="34" xoffset="-1" yoffset="1" xadvance="19" chnl="15" x="411" y="245" page="0"/>
<char id="86" index="55" char="V" width="24" height="34" xoffset="-3" yoffset="1" xadvance="19" chnl="15" x="429" y="210" page="0"/>
<char id="88" index="57" char="X" width="23" height="34" xoffset="-2" yoffset="1" xadvance="19" chnl="15" x="440" y="175" page="0"/>
<char id="89" index="58" char="Y" width="24" height="34" xoffset="-3" yoffset="0" xadvance="17" chnl="15" x="454" y="105" page="0"/>
<char id="35" index="4" char="#" width="29" height="34" xoffset="-1" yoffset="2" xadvance="27" chnl="15" x="466" y="70" page="0"/>
<char id="112" index="81" char="p" width="19" height="34" xoffset="-1" yoffset="10" xadvance="17" chnl="15" x="454" y="140" page="0"/>
<char id="104" index="73" char="h" width="19" height="34" xoffset="-1" yoffset="2" xadvance="16" chnl="15" x="433" y="245" page="0"/>
<char id="80" index="49" char="P" width="20" height="33" xoffset="-1" yoffset="1" xadvance="18" chnl="15" x="357" y="105" page="0"/>
<char id="70" index="39" char="F" width="17" height="33" xoffset="-1" yoffset="1" xadvance="15" chnl="15" x="433" y="280" page="0"/>
<char id="75" index="44" char="K" width="21" height="33" xoffset="-1" yoffset="2" xadvance="19" chnl="15" x="446" y="314" page="0"/>
<char id="105" index="74" char="i" width="10" height="33" xoffset="-1" yoffset="2" xadvance="7" chnl="15" x="378" y="105" page="0"/>
<char id="84" index="53" char="T" width="19" height="33" xoffset="-1" yoffset="1" xadvance="17" chnl="15" x="451" y="280" page="0"/>
<char id="73" index="42" char="I" width="10" height="33" xoffset="-1" yoffset="1" xadvance="8" chnl="15" x="340" y="0" page="0"/>
<char id="74" index="43" char="J" width="20" height="33" xoffset="-1" yoffset="1" xadvance="19" chnl="15" x="453" y="245" page="0"/>
<char id="87" index="56" char="W" width="33" height="33" xoffset="-3" yoffset="1" xadvance="27" chnl="15" x="454" y="210" page="0"/>
<char id="107" index="76" char="k" width="19" height="33" xoffset="-1" yoffset="2" xadvance="17" chnl="15" x="464" y="175" page="0"/>
<char id="49" index="18" char="1" width="15" height="33" xoffset="-2" yoffset="1" xadvance="12" chnl="15" x="340" y="34" page="0"/>
<char id="90" index="59" char="Z" width="19" height="33" xoffset="-1" yoffset="1" xadvance="17" chnl="15" x="474" y="140" page="0"/>
<char id="50" index="19" char="2" width="20" height="33" xoffset="-1" yoffset="0" xadvance="18" chnl="15" x="484" y="174" page="0"/>
<char id="33" index="2" char="!" width="10" height="33" xoffset="-1" yoffset="2" xadvance="7" chnl="15" x="479" y="105" page="0"/>
<char id="69" index="38" char="E" width="18" height="33" xoffset="-1" yoffset="1" xadvance="16" chnl="15" x="490" y="105" page="0"/>
<char id="100" index="69" char="d" width="19" height="33" xoffset="-1" yoffset="2" xadvance="17" chnl="15" x="455" y="348" page="0"/>
<char id="98" index="67" char="b" width="19" height="33" xoffset="-1" yoffset="2" xadvance="17" chnl="15" x="468" y="314" page="0"/>
<char id="55" index="24" char="7" width="19" height="32" xoffset="-1" yoffset="1" xadvance="17" chnl="15" x="471" y="279" page="0"/>
<char id="116" index="85" char="t" width="16" height="32" xoffset="-1" yoffset="3" xadvance="14" chnl="15" x="496" y="70" page="0"/>
<char id="59" index="28" char=";" width="10" height="30" xoffset="-1" yoffset="9" xadvance="8" chnl="15" x="494" y="139" page="0"/>
<char id="119" index="88" char="w" width="29" height="25" xoffset="-2" yoffset="9" xadvance="24" chnl="15" x="474" y="244" page="0"/>
<char id="62" index="31" char=">" width="18" height="27" xoffset="-1" yoffset="4" xadvance="16" chnl="15" x="140" y="482" page="0"/>
<char id="60" index="29" char="&lt;" width="18" height="27" xoffset="-1" yoffset="4" xadvance="16" chnl="15" x="488" y="208" page="0"/>
<char id="109" index="78" char="m" width="27" height="26" xoffset="-2" yoffset="9" xadvance="23" chnl="15" x="83" y="484" page="0"/>
<char id="114" index="83" char="r" width="18" height="26" xoffset="-1" yoffset="10" xadvance="16" chnl="15" x="111" y="484" page="0"/>
<char id="110" index="79" char="n" width="18" height="26" xoffset="-1" yoffset="9" xadvance="16" chnl="15" x="455" y="382" page="0"/>
<char id="58" index="27" char=":" width="10" height="26" xoffset="-1" yoffset="9" xadvance="8" chnl="15" x="433" y="314" page="0"/>
<char id="117" index="86" char="u" width="18" height="26" xoffset="-1" yoffset="9" xadvance="16" chnl="15" x="474" y="382" page="0"/>
<char id="120" index="89" char="x" width="19" height="25" xoffset="-2" yoffset="9" xadvance="17" chnl="15" x="475" y="348" page="0"/>
<char id="118" index="87" char="v" width="20" height="25" xoffset="-2" yoffset="9" xadvance="15" chnl="15" x="488" y="312" page="0"/>
<char id="111" index="80" char="o" width="18" height="25" xoffset="-1" yoffset="10" xadvance="15" chnl="15" x="491" y="270" page="0"/>
<char id="122" index="91" char="z" width="17" height="25" xoffset="-1" yoffset="10" xadvance="14" chnl="15" x="479" y="409" page="0"/>
<char id="101" index="70" char="e" width="18" height="25" xoffset="-1" yoffset="10" xadvance="15" chnl="15" x="493" y="374" page="0"/>
<char id="115" index="84" char="s" width="17" height="25" xoffset="-1" yoffset="10" xadvance="15" chnl="15" x="495" y="338" page="0"/>
<char id="99" index="68" char="c" width="17" height="25" xoffset="-1" yoffset="9" xadvance="15" chnl="15" x="491" y="435" page="0"/>
<char id="97" index="66" char="a" width="19" height="25" xoffset="-1" yoffset="9" xadvance="16" chnl="15" x="491" y="461" page="0"/>
<char id="94" index="63" char="^" width="22" height="16" xoffset="-1" yoffset="-3" xadvance="20" chnl="15" x="294" y="372" page="0"/>
<char id="43" index="12" char="+" width="21" height="21" xoffset="-1" yoffset="8" xadvance="19" chnl="15" x="411" y="280" page="0"/>
<char id="61" index="30" char="=" width="20" height="19" xoffset="-1" yoffset="8" xadvance="18" chnl="15" x="491" y="487" page="0"/>
<char id="126" index="95" char="~" width="20" height="12" xoffset="-1" yoffset="12" xadvance="18" chnl="15" x="299" y="96" page="0"/>
<char id="95" index="64" char="_" width="18" height="8" xoffset="-2" yoffset="35" xadvance="14" chnl="15" x="493" y="400" page="0"/>
<char id="34" index="3" char="&quot;" width="17" height="15" xoffset="-1" yoffset="-2" xadvance="15" chnl="15" x="491" y="296" page="0"/>
<char id="42" index="11" char="*" width="15" height="15" xoffset="-1" yoffset="-1" xadvance="13" chnl="15" x="100" y="275" page="0"/>
<char id="45" index="14" char="-" width="14" height="9" xoffset="-1" yoffset="14" xadvance="12" chnl="15" x="495" y="364" page="0"/>
<char id="44" index="13" char="," width="10" height="14" xoffset="-1" yoffset="25" xadvance="8" chnl="15" x="126" y="310" page="0"/>
<char id="39" index="8" char="'" width="10" height="14" xoffset="-1" yoffset="-2" xadvance="8" chnl="15" x="479" y="435" page="0"/>
<char id="96" index="65" char="`" width="11" height="12" xoffset="-2" yoffset="0" xadvance="8" chnl="15" x="356" y="414" page="0"/>
<char id="46" index="15" char="." width="10" height="10" xoffset="-1" yoffset="25" xadvance="8" chnl="15" x="75" y="53" page="0"/>
<char id="32" index="1" char=" " width="0" height="0" xoffset="-2" yoffset="32" xadvance="8" chnl="15" x="160" y="220" page="0"/>
</chars>
<kernings count="0"/>
</font>
Binary file added packages/core/examples/atlas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 34 additions & 13 deletions packages/core/examples/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
deserializeNode,
serializeNode,
toSVGElement,
loadBitmapFont,
} from '../src';

const $canvas = document.getElementById('canvas') as HTMLCanvasElement;
Expand All @@ -35,6 +36,26 @@ const canvas = await new Canvas({
// shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm',
}).initialized;

(async () => {
const res = await fetch('./DimboR.fnt');
const font = await loadBitmapFont.parse(await res.text());
console.log(font);

const text = new Text({
x: 150,
y: 150,
content: 'Hello, world',
fontSize: 48,
fill: '#F67676',
fontFamily: 'DimboR',
bitmapFont: font,
// wireframe: true,
// textAlign: 'right',
// letterSpacing: 10,
});
canvas.appendChild(text);
})();

// for (let i = 0; i < 2; i++) {
// const circle = new Circle({
// cx: i * 100,
Expand Down Expand Up @@ -117,25 +138,25 @@ const text = new Text({
content: 'Hello, world!\n你好,世界',
fontSize: 48,
fill: '#F67676',
wireframe: true,
// wireframe: true,
// textAlign: 'right',
// letterSpacing: 10,
});
canvas.appendChild(text);

const bounds = text.getBounds();
console.log(bounds);
// const bounds = text.getBounds();
// console.log(bounds);

const rect = new Rect({
x: bounds.minX,
y: bounds.minY,
width: bounds.maxX - bounds.minX,
height: bounds.maxY - bounds.minY,
fill: 'none',
stroke: 'blue',
strokeWidth: 1,
});
canvas.appendChild(rect);
// const rect = new Rect({
// x: bounds.minX,
// y: bounds.minY,
// width: bounds.maxX - bounds.minX,
// height: bounds.maxY - bounds.minY,
// fill: 'none',
// stroke: 'blue',
// strokeWidth: 1,
// });
// canvas.appendChild(rect);

canvas.render();

Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/drawcalls/SDFText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ export class SDFText extends Drawcall {
}

createGeometry(): void {
const { metrics, fontFamily, fontWeight, fontStyle } = this
const { metrics, fontFamily, fontWeight, fontStyle, bitmapFont } = this
.shapes[0] as Text;

if (bitmapFont) {
bitmapFont.init(this.device);
}

// scale current font size to base(24)
const fontScale = BASE_FONT_WIDTH / metrics.fontMetrics.fontSize;
const allText = this.shapes.map((text: Text) => text.content).join('');
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export {
parsePath,
fromSVGElement,
parseTransform,
loadBitmapFont,
} from './utils';
12 changes: 11 additions & 1 deletion packages/core/src/shapes/Text.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { canvasTextMetrics, TextMetrics } from '../utils';
import { BitmapFont } from '../utils/bitmap-font/BitmapFont';
import { AABB } from './AABB';
import { GConstructor } from './mixins';
import { Shape, ShapeAttributes, strokeOffset } from './Shape';
Expand Down Expand Up @@ -115,6 +116,13 @@ export interface TextAttributes extends ShapeAttributes {
* Sets the distance between lines in px.
*/
leading: number;

/**
* MSDF
* @see https://github.com/soimy/msdf-bmfont-xml
* @see https://pixijs.com/8.x/examples/text/bitmap-text
*/
bitmapFont: BitmapFont;
}

// @ts-ignore
Expand Down Expand Up @@ -142,7 +150,7 @@ export function TextWrapper<TBase extends GConstructor>(Base: TBase) {
#leading: number;
#textAlign: CanvasTextAlign;
#textBaseline: CanvasTextBaseline;

#bitmapFont: BitmapFont;
static getGeometryBounds(
attributes: Partial<TextAttributes> & { metrics: TextMetrics },
) {
Expand Down Expand Up @@ -198,6 +206,7 @@ export function TextWrapper<TBase extends GConstructor>(Base: TBase) {
maxLines,
lineHeight,
leading,
bitmapFont,
} = attributes;

this.#x = x ?? 0;
Expand All @@ -218,6 +227,7 @@ export function TextWrapper<TBase extends GConstructor>(Base: TBase) {
this.maxLines = maxLines ?? Infinity;
this.lineHeight = lineHeight ?? 0;
this.leading = leading ?? 0;
this.bitmapFont = bitmapFont ?? null;
}

containsPoint(x: number, y: number) {
Expand Down
Loading

0 comments on commit 4d52538

Please sign in to comment.