diff --git a/Cargo.lock b/Cargo.lock index d3b708d5cf91e6b6c7e6307d8772a58bf627cc5f..91cc95ecef83d8f44bf15749d14e39b793495a37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1898,6 +1898,7 @@ dependencies = [ name = "kayak_font" version = "0.1.0" dependencies = [ + "anyhow", "bevy", "serde", "serde_json", diff --git a/assets/roboto.json.old b/assets/roboto.json.old deleted file mode 100644 index 875af49e5db852469951736f27ca09844079dbcb..0000000000000000000000000000000000000000 --- a/assets/roboto.json.old +++ /dev/null @@ -1 +0,0 @@ -{"atlas":{"type":"msdf","distanceRange":2,"size":151.375,"width":1024,"height":720,"yOrigin":"bottom"},"metrics":{"emSize":1,"lineHeight":1.171875,"ascender":0.927734375,"descender":-0.244140625,"underlineY":-0.09765625,"underlineThickness":0.048828125},"glyphs":[{"unicode":32,"advance":0.24755859375},{"unicode":33,"advance":0.25732421875,"planeBounds":{"left":0.06883374567764243,"bottom":-0.013855938080615242,"right":0.19434984807235753,"top":0.71942234433061514},"atlasBounds":{"left":697.5,"bottom":331.5,"right":716.5,"top":442.5}},{"unicode":34,"advance":0.31982421875,"planeBounds":{"left":0.057747221111168451,"bottom":0.50057537352910819,"right":0.27574887263883152,"top":0.75821368897089192},"atlasBounds":{"left":899.5,"bottom":178.5,"right":932.5,"top":217.5}},{"unicode":35,"advance":0.61572265625,"planeBounds":{"left":0.049806703524979304,"bottom":-0.0078673358794385286,"right":0.6113261089750206,"top":0.71880483587943844},"atlasBounds":{"left":858.5,"bottom":332.5,"right":943.5,"top":442.5}},{"unicode":36,"advance":0.5615234375,"planeBounds":{"left":0.046488931216453339,"bottom":-0.11003222414327002,"right":0.51552278753354663,"top":0.83464159914326996},"atlasBounds":{"left":278.5,"bottom":576.5,"right":349.5,"top":719.5}},{"unicode":37,"advance":0.732421875,"planeBounds":{"left":0.043114710208505325,"bottom":-0.017776501857968668,"right":0.69711966479149456,"top":0.72871400185796853},"atlasBounds":{"left":438.5,"bottom":446.5,"right":537.5,"top":559.5}},{"unicode":38,"advance":0.62158203125,"planeBounds":{"left":0.040012450970272451,"bottom":-0.017776501857968668,"right":0.62795629902972738,"top":0.72871400185796853},"atlasBounds":{"left":538.5,"bottom":446.5,"right":627.5,"top":559.5}},{"unicode":39,"advance":0.17431640625,"planeBounds":{"left":0.040671287933526007,"bottom":0.50754053823028489,"right":0.13315683706647397,"top":0.75857274301971511},"atlasBounds":{"left":994.5,"bottom":27.5,"right":1008.5,"top":65.5}},{"unicode":40,"advance":0.341796875,"planeBounds":{"left":0.055119332550578062,"bottom":-0.23880884373709743,"right":0.33257597994942201,"top":0.81156274998709732},"atlasBounds":{"left":0.5,"bottom":560.5,"right":42.5,"top":719.5}},{"unicode":41,"advance":0.34765625,"planeBounds":{"left":0.0089767544255780589,"bottom":-0.23880884373709743,"right":0.28643340182442201,"top":0.81156274998709732},"atlasBounds":{"left":43.5,"bottom":560.5,"right":85.5,"top":719.5}},{"unicode":42,"advance":0.4306640625,"planeBounds":{"left":0.0069954050758670762,"bottom":0.2894517944235136,"right":0.42318037617413296,"top":0.71884898682648635},"atlasBounds":{"left":713.5,"bottom":152.5,"right":776.5,"top":217.5}},{"unicode":43,"advance":0.56689453125,"planeBounds":{"left":0.03070607646056973,"bottom":0.062530643579686171,"right":0.53277048603943011,"top":0.5976256064203137},"atlasBounds":{"left":505.5,"bottom":136.5,"right":581.5,"top":217.5}},{"unicode":44,"advance":0.1962890625,"planeBounds":{"left":0.0063051181229355786,"bottom":-0.14945619742206853,"right":0.15824566312706437,"top":0.1147882286720685},"atlasBounds":{"left":994.5,"bottom":66.5,"right":1017.5,"top":106.5}},{"unicode":45,"advance":0.27587890625,"planeBounds":{"left":0.0083878735291081988,"bottom":0.25575917855852598,"right":0.26602618897089186,"top":0.34824472769147397},"atlasBounds":{"left":144.5,"bottom":6.5,"right":183.5,"top":20.5}},{"unicode":46,"advance":0.26318359375,"planeBounds":{"left":0.06040373722646572,"bottom":-0.014418207447357567,"right":0.19252595027353425,"top":0.11109789494735753},"atlasBounds":{"left":472.5,"bottom":115.5,"right":492.5,"top":134.5}},{"unicode":47,"advance":0.412109375,"planeBounds":{"left":0.00092051700557392938,"bottom":-0.068112411940028941,"right":0.39068104549442606,"top":0.71801475569002882},"atlasBounds":{"left":578.5,"bottom":600.5,"right":637.5,"top":719.5}},{"unicode":48,"advance":0.5615234375,"planeBounds":{"left":0.049303705292630062,"bottom":-0.017776501857968668,"right":0.51173145095736994,"top":0.72871400185796853},"atlasBounds":{"left":628.5,"bottom":446.5,"right":698.5,"top":559.5}},{"unicode":49,"advance":0.5615234375,"planeBounds":{"left":0.074147987523224629,"bottom":-0.0094614068306152418,"right":0.3648168562267754,"top":0.72381687558061514},"atlasBounds":{"left":717.5,"bottom":331.5,"right":761.5,"top":442.5}},{"unicode":50,"advance":0.5615234375,"planeBounds":{"left":0.037427100536746485,"bottom":-0.0095906340317919551,"right":0.53288539946325342,"top":0.73029375903179183},"atlasBounds":{"left":172.5,"bottom":330.5,"right":247.5,"top":442.5}},{"unicode":51,"advance":0.5615234375,"planeBounds":{"left":0.036723306216453339,"bottom":-0.017776501857968668,"right":0.50575716253354663,"top":0.72871400185796853},"atlasBounds":{"left":699.5,"bottom":446.5,"right":770.5,"top":559.5}},{"unicode":52,"advance":0.5615234375,"planeBounds":{"left":0.018226277030862877,"bottom":-0.0078673358794385286,"right":0.54671512921913701,"top":0.71880483587943844},"atlasBounds":{"left":602.5,"bottom":218.5,"right":682.5,"top":328.5}},{"unicode":53,"advance":0.5615234375,"planeBounds":{"left":0.067370111542630021,"bottom":-0.019356259031791955,"right":0.52979785720736983,"top":0.72052813403179183},"atlasBounds":{"left":248.5,"bottom":330.5,"right":318.5,"top":442.5}},{"unicode":54,"advance":0.5615234375,"planeBounds":{"left":0.054545571841453339,"bottom":-0.019112118406791955,"right":0.52357942815854663,"top":0.72077227465679183},"atlasBounds":{"left":319.5,"bottom":330.5,"right":390.5,"top":442.5}},{"unicode":55,"advance":0.5615234375,"planeBounds":{"left":0.030102881786746489,"bottom":-0.0078673358794385286,"right":0.52556118071325342,"top":0.71880483587943844},"atlasBounds":{"left":944.5,"bottom":332.5,"right":1019.5,"top":442.5}},{"unicode":56,"advance":0.5615234375,"planeBounds":{"left":0.046244790591453339,"bottom":-0.017776501857968668,"right":0.51527864690854663,"top":0.72871400185796853},"atlasBounds":{"left":771.5,"bottom":446.5,"right":842.5,"top":559.5}},{"unicode":57,"advance":0.5615234375,"planeBounds":{"left":0.041247064667630062,"bottom":-0.0098347746567919551,"right":0.50367481033236994,"top":0.73004961840679183},"atlasBounds":{"left":411.5,"bottom":330.5,"right":481.5,"top":442.5}},{"unicode":58,"advance":0.2421875,"planeBounds":{"left":0.05576506535146572,"bottom":-0.013540631773843976,"right":0.18788727839853425,"top":0.54137266302384379},"atlasBounds":{"left":428.5,"bottom":22.5,"right":448.5,"top":106.5}},{"unicode":59,"advance":0.21142578125,"planeBounds":{"left":0.010685335595582152,"bottom":-0.15102002799855493,"right":0.17583810190441782,"top":0.54262159049855485},"atlasBounds":{"left":0.5,"bottom":1.5,"right":25.5,"top":106.5}},{"unicode":60,"advance":0.50830078125,"planeBounds":{"left":0.026770795700867076,"bottom":0.08776301061880673,"right":0.44295576679913296,"top":0.54358464563119313},"atlasBounds":{"left":582.5,"bottom":148.5,"right":645.5,"top":217.5}},{"unicode":61,"advance":0.548828125,"planeBounds":{"left":0.066436490374690363,"bottom":0.18681172907204793,"right":0.48922757212530965,"top":0.48408670842795209},"atlasBounds":{"left":834.5,"bottom":172.5,"right":898.5,"top":217.5}},{"unicode":62,"advance":0.5224609375,"planeBounds":{"left":0.055924129722336915,"bottom":0.08825129186880673,"right":0.4919274327776631,"top":0.54407292688119313},"atlasBounds":{"left":646.5,"bottom":148.5,"right":712.5,"top":217.5}},{"unicode":63,"advance":0.47216796875,"planeBounds":{"left":0.029829710402043789,"bottom":-0.012276180906791955,"right":0.43940857084795626,"top":0.72760821215679183},"atlasBounds":{"left":482.5,"bottom":330.5,"right":544.5,"top":442.5}},{"unicode":64,"advance":0.89794921875,"planeBounds":{"left":0.05015928215963629,"bottom":-0.2302643250670933,"right":0.85610478174675431,"top":0.70780338756709327},"atlasBounds":{"left":350.5,"bottom":577.5,"right":472.5,"top":719.5}},{"unicode":65,"advance":0.65234375,"planeBounds":{"left":0.0060196489858587478,"bottom":-0.0078673358794385286,"right":0.64681238226414106,"top":0.71880483587943844},"atlasBounds":{"left":250.5,"bottom":107.5,"right":347.5,"top":217.5}},{"unicode":66,"advance":0.62255859375,"planeBounds":{"left":0.073430685835569734,"bottom":-0.0078673358794385286,"right":0.57549509541443022,"top":0.71880483587943844},"atlasBounds":{"left":173.5,"bottom":107.5,"right":249.5,"top":217.5}},{"unicode":67,"advance":0.65087890625,"planeBounds":{"left":0.051027406649979304,"bottom":-0.017776501857968668,"right":0.6125468121000206,"top":0.72871400185796853},"atlasBounds":{"left":843.5,"bottom":446.5,"right":928.5,"top":559.5}},{"unicode":68,"advance":0.65576171875,"planeBounds":{"left":0.075355183280862881,"bottom":-0.0078673358794385286,"right":0.60384403546913701,"top":0.71880483587943844},"atlasBounds":{"left":0.5,"bottom":107.5,"right":80.5,"top":217.5}},{"unicode":69,"advance":0.568359375,"planeBounds":{"left":0.073832681216453297,"bottom":-0.0078673358794385286,"right":0.54286653753354663,"top":0.71880483587943844},"atlasBounds":{"left":939.5,"bottom":218.5,"right":1010.5,"top":328.5}},{"unicode":70,"advance":0.552734375,"planeBounds":{"left":0.07482355749380673,"bottom":-0.0078673358794385286,"right":0.53064519250619313,"top":0.71880483587943844},"atlasBounds":{"left":869.5,"bottom":218.5,"right":938.5,"top":328.5}},{"unicode":71,"advance":0.68115234375,"planeBounds":{"left":0.052736391024979304,"bottom":-0.017776501857968668,"right":0.6142557964750206,"top":0.72871400185796853},"atlasBounds":{"left":929.5,"bottom":446.5,"right":1014.5,"top":559.5}},{"unicode":72,"advance":0.712890625,"planeBounds":{"left":0.074953187899979318,"bottom":-0.0078673358794385286,"right":0.6364725933500206,"top":0.71880483587943844},"atlasBounds":{"left":701.5,"bottom":218.5,"right":786.5,"top":328.5}},{"unicode":73,"advance":0.27197265625,"planeBounds":{"left":0.080078528204995864,"bottom":-0.0078673358794385286,"right":0.19238240929500411,"top":0.71880483587943844},"atlasBounds":{"left":683.5,"bottom":218.5,"right":700.5,"top":328.5}},{"unicode":74,"advance":0.5517578125,"planeBounds":{"left":0.019030267792630059,"bottom":-0.019356259031791955,"right":0.48145801345736994,"top":0.72052813403179183},"atlasBounds":{"left":545.5,"bottom":330.5,"right":615.5,"top":442.5}},{"unicode":75,"advance":0.626953125,"planeBounds":{"left":0.074220766024979318,"bottom":-0.0078673358794385286,"right":0.6357401714750206,"top":0.71880483587943844},"atlasBounds":{"left":516.5,"bottom":218.5,"right":601.5,"top":328.5}},{"unicode":76,"advance":0.5380859375,"planeBounds":{"left":0.07348794094498344,"bottom":-0.0078673358794385286,"right":0.52270346530501643,"top":0.71880483587943844},"atlasBounds":{"left":447.5,"bottom":218.5,"right":515.5,"top":328.5}},{"unicode":77,"advance":0.873046875,"planeBounds":{"left":0.072943210995561475,"bottom":-0.0078673358794385286,"right":0.79961538275443844,"top":0.71880483587943844},"atlasBounds":{"left":336.5,"bottom":218.5,"right":446.5,"top":328.5}},{"unicode":78,"advance":0.712890625,"planeBounds":{"left":0.074953187899979318,"bottom":-0.0078673358794385286,"right":0.6364725933500206,"top":0.71880483587943844},"atlasBounds":{"left":250.5,"bottom":218.5,"right":335.5,"top":328.5}},{"unicode":79,"advance":0.6875,"planeBounds":{"left":0.049533935345272451,"bottom":-0.017776501857968668,"right":0.63747778340472738,"top":0.72871400185796853},"atlasBounds":{"left":0.5,"bottom":329.5,"right":89.5,"top":442.5}},{"unicode":80,"advance":0.630859375,"planeBounds":{"left":0.073890339530862881,"bottom":-0.0078673358794385286,"right":0.60237919171913701,"top":0.71880483587943844},"atlasBounds":{"left":82.5,"bottom":218.5,"right":162.5,"top":328.5}},{"unicode":81,"advance":0.6875,"planeBounds":{"left":0.046604247845272451,"bottom":-0.12910422365297272,"right":0.63454809590472738,"top":0.72969016115297269},"atlasBounds":{"left":473.5,"bottom":589.5,"right":562.5,"top":719.5}},{"unicode":82,"advance":0.61572265625,"planeBounds":{"left":0.072540409204686171,"bottom":-0.0078673358794385286,"right":0.6076353720453137,"top":0.71880483587943844},"atlasBounds":{"left":0.5,"bottom":218.5,"right":81.5,"top":328.5}},{"unicode":83,"advance":0.59326171875,"planeBounds":{"left":0.029815799829686164,"bottom":-0.017776501857968668,"right":0.5649107626703137,"top":0.72871400185796853},"atlasBounds":{"left":90.5,"bottom":329.5,"right":171.5,"top":442.5}},{"unicode":84,"advance":0.5966796875,"planeBounds":{"left":0.014765366948802596,"bottom":-0.0078673358794385286,"right":0.58289088305119729,"top":0.71880483587943844},"atlasBounds":{"left":163.5,"bottom":218.5,"right":249.5,"top":328.5}},{"unicode":85,"advance":0.6484375,"planeBounds":{"left":0.061439167655862881,"bottom":-0.019356259031791955,"right":0.58992801984413701,"top":0.72052813403179183},"atlasBounds":{"left":616.5,"bottom":330.5,"right":696.5,"top":442.5}},{"unicode":86,"advance":0.63623046875,"planeBounds":{"left":0.0048132596382121744,"bottom":-0.0078673358794385286,"right":0.63239377161178767,"top":0.71880483587943844},"atlasBounds":{"left":762.5,"bottom":332.5,"right":857.5,"top":442.5}},{"unicode":87,"advance":0.88720703125,"planeBounds":{"left":0.021659769173203964,"bottom":-0.0078673358794385286,"right":0.87384804332679589,"top":0.71880483587943844},"atlasBounds":{"left":893.5,"bottom":609.5,"right":1022.5,"top":719.5}},{"unicode":88,"advance":0.626953125,"planeBounds":{"left":0.020237060345272454,"bottom":-0.0078673358794385286,"right":0.60818090840472738,"top":0.71880483587943844},"atlasBounds":{"left":348.5,"bottom":107.5,"right":437.5,"top":217.5}},{"unicode":89,"advance":0.6005859375,"planeBounds":{"left":-0.0012616284320809716,"bottom":-0.0078673358794385286,"right":0.59989444093208089,"top":0.71880483587943844},"atlasBounds":{"left":81.5,"bottom":107.5,"right":172.5,"top":217.5}},{"unicode":90,"advance":0.5986328125,"planeBounds":{"left":0.033233768579686164,"bottom":-0.0078673358794385286,"right":0.5683287314203137,"top":0.71880483587943844},"atlasBounds":{"left":787.5,"bottom":218.5,"right":868.5,"top":328.5}},{"unicode":91,"advance":0.26513671875,"planeBounds":{"left":0.064238418339698608,"bottom":-0.16207711860033028,"right":0.26242173791030143,"top":0.82223336860033025},"atlasBounds":{"left":86.5,"bottom":570.5,"right":116.5,"top":719.5}},{"unicode":92,"advance":0.41015625,"planeBounds":{"left":0.012754180429397216,"bottom":-0.068112411940028941,"right":0.40912081957060281,"top":0.71801475569002882},"atlasBounds":{"left":638.5,"bottom":600.5,"right":698.5,"top":719.5}},{"unicode":93,"advance":0.26513671875,"planeBounds":{"left":-0.0024119722853014154,"bottom":-0.16207711860033028,"right":0.19577134728530138,"top":0.82223336860033025},"atlasBounds":{"left":117.5,"bottom":570.5,"right":147.5,"top":719.5}},{"unicode":94,"advance":0.41796875,"planeBounds":{"left":0.023036714234104069,"bottom":0.34847616735910403,"right":0.39297891076589592,"top":0.71841836389089586},"atlasBounds":{"left":777.5,"bottom":161.5,"right":833.5,"top":217.5}},{"unicode":95,"advance":0.451171875,"planeBounds":{"left":-0.0056279353323699412,"bottom":-0.083108008941473993,"right":0.45679981033236994,"top":0.0093775401914739792},"atlasBounds":{"left":73.5,"bottom":6.5,"right":143.5,"top":20.5}},{"unicode":96,"advance":0.30908203125,"planeBounds":{"left":0.020637846111168454,"bottom":0.59894932842175885,"right":0.23863949763883152,"top":0.75749598407824115},"atlasBounds":{"left":438.5,"bottom":110.5,"right":471.5,"top":134.5}},{"unicode":97,"advance":0.5439453125,"planeBounds":{"left":0.043329416868806772,"bottom":-0.016599546475020693,"right":0.49915105188119319,"top":0.5449198589750206},"atlasBounds":{"left":358.5,"bottom":21.5,"right":427.5,"top":106.5}},{"unicode":98,"advance":0.56103515625,"planeBounds":{"left":0.060778314667630062,"bottom":-0.019643340988852235,"right":0.52320606033236994,"top":0.75987771598885212},"atlasBounds":{"left":699.5,"bottom":601.5,"right":769.5,"top":719.5}},{"unicode":99,"advance":0.5234375,"planeBounds":{"left":0.036364252167630062,"bottom":-0.016599546475020693,"right":0.49879199783236994,"top":0.5449198589750206},"atlasBounds":{"left":287.5,"bottom":21.5,"right":357.5,"top":106.5}},{"unicode":100,"advance":0.56396484375,"planeBounds":{"left":0.038073236542630062,"bottom":-0.019643340988852235,"right":0.50050098220736994,"top":0.75987771598885212},"atlasBounds":{"left":770.5,"bottom":601.5,"right":840.5,"top":719.5}},{"unicode":101,"advance":0.52978515625,"planeBounds":{"left":0.038317377167630062,"bottom":-0.016599546475020693,"right":0.50074512283236994,"top":0.5449198589750206},"atlasBounds":{"left":149.5,"bottom":21.5,"right":219.5,"top":106.5}},{"unicode":102,"advance":0.34716796875,"planeBounds":{"left":0.020509022114987636,"bottom":-0.0096335753638522349,"right":0.35742066538501238,"top":0.76988748161385212},"atlasBounds":{"left":841.5,"bottom":601.5,"right":892.5,"top":719.5}},{"unicode":103,"advance":0.56103515625,"planeBounds":{"left":0.038805658417630062,"bottom":-0.21481230001032209,"right":0.50123340408236994,"top":0.54489042501032192},"atlasBounds":{"left":367.5,"bottom":444.5,"right":437.5,"top":559.5}},{"unicode":104,"advance":0.55078125,"planeBounds":{"left":0.061424450673513625,"bottom":-0.0081544178364988083,"right":0.49082164307648635,"top":0.75815441783649862},"atlasBounds":{"left":0.5,"bottom":443.5,"right":65.5,"top":559.5}},{"unicode":105,"advance":0.24267578125,"planeBounds":{"left":0.05955640192764243,"bottom":-0.0095906340317919551,"right":0.18507250432235753,"top":0.73029375903179183},"atlasBounds":{"left":391.5,"bottom":330.5,"right":410.5,"top":442.5}},{"unicode":106,"advance":0.23876953125,"planeBounds":{"left":-0.040641450763831549,"bottom":-0.22197785759444671,"right":0.17736020076383152,"top":0.72930207634444666},"atlasBounds":{"left":244.5,"bottom":575.5,"right":277.5,"top":719.5}},{"unicode":107,"advance":0.5068359375,"planeBounds":{"left":0.059442698118806772,"bottom":-0.0081544178364988083,"right":0.51526433313119313,"top":0.75815441783649862},"atlasBounds":{"left":66.5,"bottom":443.5,"right":135.5,"top":559.5}},{"unicode":108,"advance":0.24267578125,"planeBounds":{"left":0.068489005406172587,"bottom":-0.0081544178364988083,"right":0.17418677584382741,"top":0.75815441783649862},"atlasBounds":{"left":136.5,"bottom":443.5,"right":152.5,"top":559.5}},{"unicode":109,"advance":0.87646484375,"planeBounds":{"left":0.058381059364677898,"bottom":-0.0084136786488439776,"right":0.81808378438532192,"top":0.54649961614884379},"atlasBounds":{"left":515.5,"bottom":22.5,"right":630.5,"top":106.5}},{"unicode":110,"advance":0.5517578125,"planeBounds":{"left":0.061424450673513625,"bottom":-0.0084136786488439776,"right":0.49082164307648635,"top":0.54649961614884379},"atlasBounds":{"left":673.5,"bottom":22.5,"right":738.5,"top":106.5}},{"unicode":111,"advance":0.5703125,"planeBounds":{"left":0.037182959911746485,"bottom":-0.016599546475020693,"right":0.53264125883825342,"top":0.5449198589750206},"atlasBounds":{"left":73.5,"bottom":21.5,"right":148.5,"top":106.5}},{"unicode":112,"advance":0.56103515625,"planeBounds":{"left":0.060290033417630062,"bottom":-0.21237089376032209,"right":0.52271777908236994,"top":0.54733183126032192},"atlasBounds":{"left":296.5,"bottom":444.5,"right":366.5,"top":559.5}},{"unicode":113,"advance":0.568359375,"planeBounds":{"left":0.037829095917630062,"bottom":-0.21237089376032209,"right":0.50025684158236994,"top":0.54733183126032192},"atlasBounds":{"left":225.5,"bottom":444.5,"right":295.5,"top":559.5}},{"unicode":114,"advance":0.33837890625,"planeBounds":{"left":0.060619653501754772,"bottom":-0.0084136786488439776,"right":0.33147019024824526,"top":0.54649961614884379},"atlasBounds":{"left":631.5,"bottom":22.5,"right":672.5,"top":106.5}},{"unicode":115,"advance":0.515625,"planeBounds":{"left":0.038346004722336915,"bottom":-0.016599546475020693,"right":0.4743493077776631,"top":0.5449198589750206},"atlasBounds":{"left":220.5,"bottom":21.5,"right":286.5,"top":106.5}},{"unicode":116,"advance":0.32666015625,"planeBounds":{"left":-0.0037471856291287952,"bottom":-0.016972511096201532,"right":0.30013390437912885,"top":0.66345688609620135},"atlasBounds":{"left":26.5,"bottom":3.5,"right":72.5,"top":106.5}},{"unicode":117,"advance":0.55126953125,"planeBounds":{"left":0.059715466298513625,"bottom":-0.018179303648843976,"right":0.48911265870148635,"top":0.53673399114884379},"atlasBounds":{"left":449.5,"bottom":22.5,"right":514.5,"top":106.5}},{"unicode":118,"advance":0.484375,"planeBounds":{"left":0.0064498687164533447,"bottom":-0.006690380496490551,"right":0.47548372503354663,"top":0.5350106929964904},"atlasBounds":{"left":922.5,"bottom":24.5,"right":993.5,"top":106.5}},{"unicode":119,"advance":0.75146484375,"planeBounds":{"left":0.011175632870561471,"bottom":-0.006690380496490551,"right":0.73784780462943844,"top":0.5350106929964904},"atlasBounds":{"left":739.5,"bottom":24.5,"right":849.5,"top":106.5}},{"unicode":120,"advance":0.49560546875,"planeBounds":{"left":0.012309243716453346,"bottom":-0.006690380496490551,"right":0.48134310003354663,"top":0.5350106929964904},"atlasBounds":{"left":850.5,"bottom":24.5,"right":921.5,"top":106.5}},{"unicode":121,"advance":0.47314453125,"planeBounds":{"left":0.0013229155914533447,"bottom":-0.22238065938532209,"right":0.47035677190854663,"top":0.53732206563532192},"atlasBounds":{"left":153.5,"bottom":444.5,"right":224.5,"top":559.5}},{"unicode":122,"advance":0.49560546875,"planeBounds":{"left":0.034683895347336915,"bottom":-0.006690380496490551,"right":0.4706871984026631,"top":0.5350106929964904},"atlasBounds":{"left":438.5,"bottom":135.5,"right":504.5,"top":217.5}},{"unicode":123,"advance":0.33837890625,"planeBounds":{"left":0.023955618419694489,"bottom":-0.18831507889915358,"right":0.33444281908030554,"top":0.78938929764915344},"atlasBounds":{"left":196.5,"bottom":571.5,"right":243.5,"top":719.5}},{"unicode":124,"advance":0.24365234375,"planeBounds":{"left":0.075583397308526007,"bottom":-0.13984641115297272,"right":0.16806894644147397,"top":0.71894797365297269},"atlasBounds":{"left":563.5,"bottom":589.5,"right":577.5,"top":719.5}},{"unicode":125,"advance":0.33837890625,"planeBounds":{"left":0.0022271027946944911,"bottom":-0.18831507889915358,"right":0.31271430345530554,"top":0.78938929764915344},"atlasBounds":{"left":148.5,"bottom":571.5,"right":195.5,"top":719.5}},{"unicode":126,"advance":0.68017578125,"planeBounds":{"left":0.056269273198802594,"bottom":0.1882475420623452,"right":0.62439478930119729,"top":0.39964308293765483},"atlasBounds":{"left":933.5,"bottom":185.5,"right":1019.5,"top":217.5}}],"kerning":[]} diff --git a/assets/roboto.json b/assets/roboto.kayak_font similarity index 100% rename from assets/roboto.json rename to assets/roboto.kayak_font diff --git a/assets/roboto.png.old b/assets/roboto.png.old deleted file mode 100644 index 7f4e0f9128bb32bb381d5ae42d21ed7cc8177e5a..0000000000000000000000000000000000000000 Binary files a/assets/roboto.png.old and /dev/null differ diff --git a/bevy_kayak_ui/src/lib.rs b/bevy_kayak_ui/src/lib.rs index 1f1d45ff7c38e3add19967a1d7e743095733ed21..ddc7232708b49d8c924eb4628ef4154368b669f2 100644 --- a/bevy_kayak_ui/src/lib.rs +++ b/bevy_kayak_ui/src/lib.rs @@ -13,6 +13,7 @@ mod render; pub use bevy_context::BevyContext; pub use camera::*; use kayak_core::InputEvent; +pub use render::unified::font::FontMapping; pub use render::unified::image::ImageManager; #[derive(Default)] diff --git a/bevy_kayak_ui/src/render/unified/font/extract.rs b/bevy_kayak_ui/src/render/unified/font/extract.rs index feae2c49b39a6d9c38a1585a692b867e05552ed8..c4d7fbec89b1ee118d179263239c8c231bc155b5 100644 --- a/bevy_kayak_ui/src/render/unified/font/extract.rs +++ b/bevy_kayak_ui/src/render/unified/font/extract.rs @@ -44,7 +44,13 @@ pub fn extract_texts( }; let font_handle = font_mapping.get_handle(font).unwrap(); - let font = fonts.get(font_handle.clone()).unwrap(); + let font = fonts.get(font_handle.clone()); + + if font.is_none() { + continue; + } + + let font = font.unwrap(); let chars_layouts = font.get_layout(Vec2::new(layout.posx, layout.posy), content, font_size); diff --git a/bevy_kayak_ui/src/render/unified/font/font_mapping.rs b/bevy_kayak_ui/src/render/unified/font/font_mapping.rs index 743eedd5436a3e61d1e692e0f03c9b857b9f815c..2559243f9c5ce418e093cee72a515ac518c10d88 100644 --- a/bevy_kayak_ui/src/render/unified/font/font_mapping.rs +++ b/bevy_kayak_ui/src/render/unified/font/font_mapping.rs @@ -18,7 +18,7 @@ impl Default for FontMapping { } impl FontMapping { - pub(crate) fn add(&mut self, handle: Handle<KayakFont>) -> u16 { + pub fn add(&mut self, handle: Handle<KayakFont>) -> u16 { if !self.font_ids.contains_key(&handle) { let id = self.count; self.font_ids.insert(handle.clone(), id); @@ -31,7 +31,7 @@ impl FontMapping { } } - pub(crate) fn get_handle(&self, id: u16) -> Option<Handle<KayakFont>> { + pub fn get_handle(&self, id: u16) -> Option<Handle<KayakFont>> { self.font_handles .get(&id) .and_then(|item| Some(item.clone())) diff --git a/bevy_kayak_ui/src/render/unified/font/mod.rs b/bevy_kayak_ui/src/render/unified/font/mod.rs index f4cd0ba7c14701009e9d0d8d6d065876c542373e..82a6e943d8d8be0c3d2ef0409cc60df6c2c9fd2a 100644 --- a/bevy_kayak_ui/src/render/unified/font/mod.rs +++ b/bevy_kayak_ui/src/render/unified/font/mod.rs @@ -12,7 +12,7 @@ use bevy::{ }, utils::HashSet, }; -use kayak_font::{FontTextureCache, KayakFont, Sdf}; +use kayak_font::{FontTextureCache, KayakFont, KayakFontPlugin}; mod extract; mod font_mapping; @@ -26,132 +26,12 @@ pub struct TextRendererPlugin; impl Plugin for TextRendererPlugin { fn build(&self, app: &mut bevy::prelude::App) { - app.add_asset::<KayakFont>() - .init_resource::<FontMapping>() - .add_startup_system(load_fonts) - .add_system(set_font_texture); + app.add_plugin(KayakFontPlugin) + .init_resource::<FontMapping>(); let render_app = app.sub_app(RenderApp); render_app.add_system_to_stage(RenderStage::Extract, extract_texts); - - render_app - .init_resource::<FontTextureCache>() - .init_resource::<ExtractedFonts>() - .add_system_to_stage(RenderStage::Extract, extract_fonts) - .add_system_to_stage(RenderStage::Prepare, prepare_fonts) - .add_system_to_stage(RenderStage::Queue, create_and_update_font_cache_texture); - } -} - -#[derive(Default)] -pub struct ExtractedFonts { - pub fonts: Vec<(Handle<KayakFont>, KayakFont)>, -} - -fn load_fonts( - mut font_assets: ResMut<Assets<KayakFont>>, - mut font_mapping: ResMut<FontMapping>, - asset_server: Res<AssetServer>, -) { - let sdf = Sdf::from_string(include_str!("../../../../../assets/roboto.json").to_string()); - - let atlas_image: Handle<Image> = asset_server.load("roboto.png"); - - let mut font = KayakFont::new(sdf, atlas_image); - font.generate_char_ids(); - - let handle = font_assets.add(font); - font_mapping.add(handle); -} - -pub fn set_font_texture( - mut texture_events: EventReader<AssetEvent<Image>>, - mut textures: ResMut<Assets<Image>>, - asset_server: Res<AssetServer>, -) { - // quick and dirty, run this for all textures anytime a texture is created. - for event in texture_events.iter() { - match event { - AssetEvent::Created { handle } => { - if let Some(handle_path) = asset_server.get_handle_path(handle) { - if handle_path.path().to_str().unwrap().contains("roboto") { - if let Some(mut texture) = textures.get_mut(handle) { - texture.texture_descriptor.format = TextureFormat::Rgba8Unorm; - texture.sampler_descriptor.min_filter = FilterMode::Linear; - texture.sampler_descriptor.mipmap_filter = FilterMode::Linear; - texture.sampler_descriptor.mag_filter = FilterMode::Linear; - texture.texture_descriptor.usage = TextureUsages::TEXTURE_BINDING - | TextureUsages::COPY_DST - | TextureUsages::COPY_SRC; - } - } - } - } - _ => (), - } - } -} - -fn extract_fonts( - mut not_processed: Local<Vec<Handle<KayakFont>>>, - mut commands: Commands, - font_assets: Res<Assets<KayakFont>>, - mut events: EventReader<AssetEvent<KayakFont>>, - textures: Res<Assets<Image>>, -) { - let mut extracted_fonts = ExtractedFonts { fonts: Vec::new() }; - let mut changed_assets = HashSet::default(); - let mut removed = Vec::new(); - for event in events.iter() { - match event { - AssetEvent::Created { handle } => { - changed_assets.insert(handle.clone_weak()); - } - AssetEvent::Modified { handle } => { - changed_assets.insert(handle.clone_weak()); - } - AssetEvent::Removed { handle } => { - if !changed_assets.remove(handle) { - removed.push(handle.clone_weak()); - } - } - } - } - - for handle in not_processed.drain(..) { - changed_assets.insert(handle); - } - - for handle in changed_assets { - let font_asset = font_assets.get(&handle).unwrap(); - if let Some(image) = textures.get(&font_asset.atlas_image) { - if !image - .texture_descriptor - .usage - .contains(TextureUsages::COPY_SRC) - { - not_processed.push(handle); - continue; - } - } else { - not_processed.push(handle); - continue; - } - - let font = font_asset.clone(); - extracted_fonts.fonts.push((handle, font)); - } - - commands.insert_resource(extracted_fonts); -} - -fn prepare_fonts( - mut extracted_fonts: ResMut<ExtractedFonts>, - mut font_texture_cache: ResMut<FontTextureCache>, -) { - let fonts: Vec<_> = extracted_fonts.fonts.drain(..).collect(); - for (handle, font) in fonts { - font_texture_cache.add(handle, font); + render_app.add_system_to_stage(RenderStage::Queue, create_and_update_font_cache_texture); } } diff --git a/examples/bevy.rs b/examples/bevy.rs index 4895e2ad93c1d6f2513622bd4fc9766ed3ad913c..dc9c042deae3ec846a5b6af15b4de9f4bcc31f72 100644 --- a/examples/bevy.rs +++ b/examples/bevy.rs @@ -1,10 +1,10 @@ use bevy::{ math::Vec2, - prelude::{App as BevyApp, Commands, Res}, + prelude::{App as BevyApp, AssetServer, Commands, Res, ResMut}, window::{WindowDescriptor, Windows}, PipelinedDefaultPlugins, }; -use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, UICameraBundle}; +use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}; use kayak_components::Window; use kayak_core::Index; use kayak_ui::components::App; @@ -28,9 +28,16 @@ fn TestState() { } } -fn startup(mut commands: Commands, windows: Res<Windows>) { +fn startup( + mut commands: Commands, + windows: Res<Windows>, + mut font_mapping: ResMut<FontMapping>, + asset_server: Res<AssetServer>, +) { commands.spawn_bundle(UICameraBundle::new()); + font_mapping.add(asset_server.load("roboto.kayak_font")); + let window_size = if let Some(window) = windows.get_primary() { Vec2::new(window.width(), window.height()) } else { diff --git a/examples/counter.rs b/examples/counter.rs index 2d946636fd5a0c8df3f5ea2a756004935f95e975..9f924cf90431730869a9bb1cbb636e7b3f85be01 100644 --- a/examples/counter.rs +++ b/examples/counter.rs @@ -1,10 +1,10 @@ use bevy::{ math::Vec2, - prelude::{App as BevyApp, Commands, Res}, + prelude::{App as BevyApp, AssetServer, Commands, Res, ResMut}, window::{WindowDescriptor, Windows}, PipelinedDefaultPlugins, }; -use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, UICameraBundle}; +use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}; use kayak_components::{Button, Text, Window}; use kayak_core::{ context::KayakContext, @@ -50,9 +50,16 @@ fn Counter(context: &mut KayakContext) { } } -fn startup(mut commands: Commands, windows: Res<Windows>) { +fn startup( + mut commands: Commands, + windows: Res<Windows>, + mut font_mapping: ResMut<FontMapping>, + asset_server: Res<AssetServer>, +) { commands.spawn_bundle(UICameraBundle::new()); + font_mapping.add(asset_server.load("roboto.kayak_font")); + let window_size = if let Some(window) = windows.get_primary() { Vec2::new(window.width(), window.height()) } else { diff --git a/examples/full_ui.rs b/examples/full_ui.rs index 380f548b19ae54be19cd3bdd1ec069a05999745f..46eba9fd22d293499b1546f14a9ab7027c4c3a3e 100644 --- a/examples/full_ui.rs +++ b/examples/full_ui.rs @@ -4,7 +4,7 @@ use bevy::{ window::{WindowDescriptor, Windows}, PipelinedDefaultPlugins, }; -use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, ImageManager, UICameraBundle}; +use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, FontMapping, ImageManager, UICameraBundle}; use kayak_components::{NinePatch, Text}; use kayak_core::{ context::KayakContext, @@ -89,6 +89,7 @@ fn startup( windows: Res<Windows>, asset_server: Res<AssetServer>, mut image_manager: ResMut<ImageManager>, + mut font_mapping: ResMut<FontMapping>, ) { commands.spawn_bundle(UICameraBundle::new()); @@ -98,6 +99,8 @@ fn startup( panic!("Couldn't find primary window!"); }; + font_mapping.add(asset_server.load("roboto.kayak_font")); + let handle: Handle<bevy::render2::texture::Image> = asset_server.load("kenny/panel_brown.png"); let panel_brown_handle = image_manager.get(&handle); diff --git a/kayak_font/Cargo.toml b/kayak_font/Cargo.toml index f5ded9aef2a7f94113971945d39f0e85f8665262..4d787f23c6be0227b4cc403bdb348ca24e826b82 100644 --- a/kayak_font/Cargo.toml +++ b/kayak_font/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = { version = "1.0" } bevy = { git = "https://github.com/bevyengine/bevy", rev = "38c7d5eb9e81ab8e1aec03673599b25a9aa0c69c" } serde = "1.0" serde_json = "1.0" diff --git a/kayak_font/assets/roboto.json b/kayak_font/assets/roboto.kayak_font similarity index 100% rename from kayak_font/assets/roboto.json rename to kayak_font/assets/roboto.kayak_font diff --git a/kayak_font/examples/bevy.rs b/kayak_font/examples/bevy.rs new file mode 100644 index 0000000000000000000000000000000000000000..1521e46c3380ad132d082f1d92c3734196c1de71 --- /dev/null +++ b/kayak_font/examples/bevy.rs @@ -0,0 +1,26 @@ +use bevy::{ + prelude::{App as BevyApp, AssetServer, Commands, Handle, Res}, + window::WindowDescriptor, + PipelinedDefaultPlugins, +}; +use kayak_font::{KayakFont, KayakFontPlugin}; + +fn startup(mut commands: Commands, asset_server: Res<AssetServer>) { + let font_handle: Handle<KayakFont> = asset_server.load("roboto.kayak_font"); + + dbg!(font_handle); +} + +fn main() { + BevyApp::new() + .insert_resource(WindowDescriptor { + width: 1270.0, + height: 720.0, + title: String::from("UI Example"), + ..Default::default() + }) + .add_plugins(PipelinedDefaultPlugins) + .add_plugin(KayakFontPlugin) + .add_startup_system(startup) + .run(); +} diff --git a/kayak_font/src/font.rs b/kayak_font/src/font.rs index 69a5802edc92e924bf57db97e804a8b7e5421da7..74e73d1e4148deec2aff3dcab76f9d8e1e63abd3 100644 --- a/kayak_font/src/font.rs +++ b/kayak_font/src/font.rs @@ -1,6 +1,12 @@ -use std::collections::HashMap; +use std::{collections::HashMap, path::PathBuf}; -use bevy::{math::Vec2, prelude::Handle, reflect::TypeUuid, render2::texture::Image}; +use bevy::{ + asset::{AssetLoader, AssetPath, BoxedFuture, LoadContext, LoadedAsset}, + math::Vec2, + prelude::Handle, + reflect::TypeUuid, + render2::texture::Image, +}; use crate::Sdf; @@ -76,3 +82,36 @@ impl KayakFont { positions_and_size } } + +#[derive(Default)] +pub struct KayakFontLoader; + +impl AssetLoader for KayakFontLoader { + fn load<'a>( + &'a self, + bytes: &'a [u8], + load_context: &'a mut LoadContext, + ) -> BoxedFuture<'a, Result<(), anyhow::Error>> { + Box::pin(async move { + let path = load_context.path(); + let path = path.with_extension("png"); + let atlas_image_path = AssetPath::new(path, None); + let mut font = KayakFont::new( + Sdf::from_bytes(bytes), + load_context.get_handle(atlas_image_path.clone()), + ); + + font.generate_char_ids(); + + load_context + .set_default_asset(LoadedAsset::new(font).with_dependency(atlas_image_path)); + + Ok(()) + }) + } + + fn extensions(&self) -> &[&str] { + static EXTENSIONS: &[&str] = &["kayak_font"]; + EXTENSIONS + } +} diff --git a/kayak_font/src/lib.rs b/kayak_font/src/lib.rs index 3ffc49344dfbaccbf3cc3b7d34e8d43d20cbc774..23a4753158832f1ef4148a11e4938607e5e8852d 100644 --- a/kayak_font/src/lib.rs +++ b/kayak_font/src/lib.rs @@ -6,9 +6,132 @@ mod renderer; mod sdf; pub use atlas::*; +use bevy::{ + prelude::{ + AddAsset, AssetEvent, Assets, Commands, EventReader, Handle, Local, Plugin, Res, ResMut, + }, + render2::{ + render_resource::{FilterMode, TextureFormat, TextureUsages}, + renderer::{RenderDevice, RenderQueue}, + texture::Image, + RenderApp, RenderStage, + }, + utils::HashSet, +}; pub use font::*; pub use glyph::*; pub use metrics::*; pub use sdf::*; pub use renderer::*; + +pub struct KayakFontPlugin; + +impl Plugin for KayakFontPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.add_asset::<KayakFont>() + .add_asset_loader(KayakFontLoader) + .add_system(init_font_texture); + + let render_app = app.sub_app(RenderApp); + render_app + .init_resource::<FontTextureCache>() + .init_resource::<ExtractedFonts>() + .add_system_to_stage(RenderStage::Extract, extract_fonts) + .add_system_to_stage(RenderStage::Prepare, prepare_fonts); + } +} + +pub fn init_font_texture( + mut font_events: EventReader<AssetEvent<KayakFont>>, + mut images: ResMut<Assets<Image>>, + fonts: Res<Assets<KayakFont>>, +) { + // quick and dirty, run this for all textures anytime a texture is created. + for event in font_events.iter() { + match event { + AssetEvent::Created { handle } => { + if let Some(font) = fonts.get(handle) { + if let Some(mut texture) = images.get_mut(&font.atlas_image) { + texture.texture_descriptor.format = TextureFormat::Rgba8Unorm; + texture.sampler_descriptor.min_filter = FilterMode::Linear; + texture.sampler_descriptor.mipmap_filter = FilterMode::Linear; + texture.sampler_descriptor.mag_filter = FilterMode::Linear; + texture.texture_descriptor.usage = TextureUsages::TEXTURE_BINDING + | TextureUsages::COPY_DST + | TextureUsages::COPY_SRC; + } + } + } + _ => (), + } + } +} + +#[derive(Default)] +pub struct ExtractedFonts { + pub fonts: Vec<(Handle<KayakFont>, KayakFont)>, +} + +fn extract_fonts( + mut not_processed: Local<Vec<Handle<KayakFont>>>, + mut commands: Commands, + font_assets: Res<Assets<KayakFont>>, + mut events: EventReader<AssetEvent<KayakFont>>, + textures: Res<Assets<Image>>, +) { + let mut extracted_fonts = ExtractedFonts { fonts: Vec::new() }; + let mut changed_assets = HashSet::default(); + let mut removed = Vec::new(); + for event in events.iter() { + match event { + AssetEvent::Created { handle } => { + changed_assets.insert(handle.clone_weak()); + } + AssetEvent::Modified { handle } => { + changed_assets.insert(handle.clone_weak()); + } + AssetEvent::Removed { handle } => { + if !changed_assets.remove(handle) { + removed.push(handle.clone_weak()); + } + } + } + } + + for handle in not_processed.drain(..) { + changed_assets.insert(handle); + } + + for handle in changed_assets { + let font_asset = font_assets.get(&handle).unwrap(); + if let Some(image) = textures.get(&font_asset.atlas_image) { + if !image + .texture_descriptor + .usage + .contains(TextureUsages::COPY_SRC) + { + not_processed.push(handle); + continue; + } + } else { + not_processed.push(handle); + continue; + } + + let font = font_asset.clone(); + extracted_fonts.fonts.push((handle, font)); + } + + commands.insert_resource(extracted_fonts); +} + +fn prepare_fonts( + mut extracted_fonts: ResMut<ExtractedFonts>, + mut font_texture_cache: ResMut<FontTextureCache>, +) { + let fonts: Vec<_> = extracted_fonts.fonts.drain(..).collect(); + for (handle, font) in fonts { + font_texture_cache.add(handle, font); + } +} diff --git a/kayak_font/src/sdf.rs b/kayak_font/src/sdf.rs index 129efb18840e32148c6aa85973249ba62b5a6434..485e21398444669f41e9060575b43649917fccae 100644 --- a/kayak_font/src/sdf.rs +++ b/kayak_font/src/sdf.rs @@ -33,6 +33,21 @@ impl Sdf { value } + pub fn from_bytes(data: &[u8]) -> Sdf { + let value: Sdf = match serde_path_to_error::deserialize( + &mut serde_json::Deserializer::from_slice(&data), + ) { + Ok(v) => v, + Err(err) => { + let path = err.path().to_string(); + dbg!(err); + panic!("failed to deserialize json! path: {}", path); + } + }; + + value + } + pub fn max_glyph_size(&self) -> Vec2 { let mut size = Vec2::new(0.0, 0.0); self.glyphs.iter().for_each(|glyph| { @@ -53,7 +68,7 @@ impl Sdf { #[test] fn test_sdf_loader() { - let sdf = Sdf::from_string(include_str!("../assets/roboto.json").to_string()); + let sdf = Sdf::from_string(include_str!("../assets/roboto.kayak_font").to_string()); assert!(sdf.max_glyph_size() == Vec2::new(30.0, 36.0)); assert!(sdf.atlas.width == 212); assert!(sdf.atlas.height == 212);