From 8a719c214e7258a8e7cea9b79909a4185ce9893d Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 11 Jun 2024 14:39:06 +0100 Subject: [PATCH] PicoVector: C++ basic bringup. --- .gitmodules | 3 - examples/pico_display_2/CMakeLists.txt | 15 +- .../pico_display_2/pico_display_2_demo.cmake | 10 ++ .../pico_display_2_vector.cmake | 41 ++++++ .../pico_display_2/pico_display_2_vector.cpp | 66 +++++++++ .../pico_display_2/vector/DynaPuff-Medium.af | Bin 0 -> 9688 bytes libraries/pico_vector/af-file-io.c | 36 +++++ libraries/pico_vector/af-file-io.h | 6 +- libraries/pico_vector/af-memory.c | 24 ++++ libraries/pico_vector/af-memory.h | 8 +- libraries/pico_vector/alright_fonts.cpp | 136 ------------------ libraries/pico_vector/alright_fonts.hpp | 74 ---------- libraries/pico_vector/pico_vector.cmake | 3 +- libraries/pico_vector/pico_vector.hpp | 15 +- 14 files changed, 207 insertions(+), 230 deletions(-) create mode 100644 examples/pico_display_2/pico_display_2_demo.cmake create mode 100644 examples/pico_display_2/pico_display_2_vector.cmake create mode 100644 examples/pico_display_2/pico_display_2_vector.cpp create mode 100644 examples/pico_display_2/vector/DynaPuff-Medium.af create mode 100644 libraries/pico_vector/af-file-io.c create mode 100644 libraries/pico_vector/af-memory.c delete mode 100644 libraries/pico_vector/alright_fonts.cpp delete mode 100644 libraries/pico_vector/alright_fonts.hpp diff --git a/.gitmodules b/.gitmodules index 4861dad5..b1f258d2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,6 +25,3 @@ [submodule "drivers/mlx90640/src"] path = drivers/mlx90640/src url = https://github.com/melexis/mlx90640-library -[submodule "libraries/pico_vector/pretty_poly"] - path = libraries/pico_vector/pretty_poly - url = https://github.com/lowfatcode/pretty-poly/ diff --git a/examples/pico_display_2/CMakeLists.txt b/examples/pico_display_2/CMakeLists.txt index d40b117e..8c72a375 100644 --- a/examples/pico_display_2/CMakeLists.txt +++ b/examples/pico_display_2/CMakeLists.txt @@ -1,14 +1,3 @@ add_subdirectory(mandelbrot) - -set(OUTPUT_NAME pico_display2_demo) - -add_executable( - ${OUTPUT_NAME} - pico_display_2_demo.cpp -) - -# Pull in pico libraries that we need -target_link_libraries(${OUTPUT_NAME} pico_stdlib hardware_spi hardware_pwm hardware_dma rgbled button pico_display_2 st7789 pico_graphics) - -# create map/bin/hex file etc. -pico_add_extra_outputs(${OUTPUT_NAME}) \ No newline at end of file +include(pico_display_2_demo.cmake) +include(pico_display_2_vector.cmake) \ No newline at end of file diff --git a/examples/pico_display_2/pico_display_2_demo.cmake b/examples/pico_display_2/pico_display_2_demo.cmake new file mode 100644 index 00000000..a975866b --- /dev/null +++ b/examples/pico_display_2/pico_display_2_demo.cmake @@ -0,0 +1,10 @@ +add_executable( + pico_display_2_demo + pico_display_2_demo.cpp +) + +# Pull in pico libraries that we need +target_link_libraries(pico_display_2_demo pico_stdlib hardware_spi hardware_pwm hardware_dma rgbled button pico_display_2 st7789 pico_graphics) + +# create map/bin/hex file etc. +pico_add_extra_outputs(pico_display_2_demo) \ No newline at end of file diff --git a/examples/pico_display_2/pico_display_2_vector.cmake b/examples/pico_display_2/pico_display_2_vector.cmake new file mode 100644 index 00000000..1459902b --- /dev/null +++ b/examples/pico_display_2/pico_display_2_vector.cmake @@ -0,0 +1,41 @@ +function(static_asset NAME PATH) + get_filename_component(PATH ${PATH} ABSOLUTE) + get_filename_component(ASSET ${PATH} NAME) + get_filename_component(PATH ${PATH} DIRECTORY) + set(OBJNAME ${ASSET}.o) + add_custom_command(OUTPUT ${OBJNAME} + DEPENDS ${PATH}/${ASSET} + COMMENT "Building ${OBJNAME}" + WORKING_DIRECTORY "${PATH}" + COMMAND ${CMAKE_LINKER} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/${OBJNAME} ${ASSET} + COMMAND ${CMAKE_OBJDUMP} -t ${CMAKE_CURRENT_BINARY_DIR}/${OBJNAME} + ) + # TODO figure out how to make static resources work + ## COMMAND ${CMAKE_OBJCOPY} --rename-section .data=.rodata,alloc,load,readonly,data,contents ${CMAKE_CURRENT_BINARY_DIR}/${OBJNAME} ${CMAKE_CURRENT_BINARY_DIR}/${OBJNAME}) + target_sources(${NAME} PRIVATE ${OBJNAME}) +endfunction() + +add_executable( + pico_display_2_vector + pico_display_2_vector.cpp +) + +# Pull in pico libraries that we need +target_link_libraries(pico_display_2_vector + pico_stdlib + hardware_spi + hardware_pwm + hardware_dma + pico_display_2 + st7789 + pico_graphics + pico_vector + ) + +static_asset(pico_display_2_vector ${CMAKE_CURRENT_LIST_DIR}/vector/DynaPuff-Medium.af) + +pico_enable_stdio_usb(pico_display_2_vector 0) +pico_enable_stdio_uart(pico_display_2_vector 1) + +# create map/bin/hex file etc. +pico_add_extra_outputs(pico_display_2_vector) \ No newline at end of file diff --git a/examples/pico_display_2/pico_display_2_vector.cpp b/examples/pico_display_2/pico_display_2_vector.cpp new file mode 100644 index 00000000..68e91554 --- /dev/null +++ b/examples/pico_display_2/pico_display_2_vector.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#include "libraries/pico_display_2/pico_display_2.hpp" +#include "drivers/st7789/st7789.hpp" +#include "libraries/pico_graphics/pico_graphics.hpp" +#include "libraries/pico_vector/pico_vector.hpp" + + +using namespace pimoroni; + +ST7789 st7789(320, 240, ROTATE_180, false, get_spi_pins(BG_SPI_FRONT)); +PicoGraphics_PenRGB332 graphics(st7789.width, st7789.height, nullptr); + +uint8_t vector_mem[PicoVector::pretty_poly_buffer_size()]; + +PicoVector vector(&graphics); + +extern char _binary_DynaPuff_Medium_af_start[]; +extern size_t _binary_DynaPuff_Medium_af_size; + +int main() { + stdio_init_all(); + + Pen BG = graphics.create_pen(120, 40, 60); + Pen TEXT = graphics.create_pen(255, 255, 255); + + st7789.set_backlight(255); + + vector.set_font(_binary_DynaPuff_Medium_af_start, 30); + + unsigned int a = 0; + + while (true) { + Point text_location(0, 0); + graphics.set_pen(BG); + graphics.clear(); + graphics.set_pen(TEXT); + graphics.text("Hello World", text_location, 320); + + pp_point_t outline[] = {{-64, -64}, {64, -64}, {64, 64}, {-64, 64}}; + pp_point_t hole[] = {{ -32, 32}, { 32, 32}, { 32, -32}, { -32, -32}}; + pp_path_t paths[] = { + {.points = outline, .count = 4}, + {.points = hole, .count = 4} + }; + pp_poly_t poly = {.paths = paths, .count = 2}; + + pp_mat3_t pos = pp_mat3_identity(); + pp_mat3_translate(&pos, 50, 50); + pp_mat3_rotate(&pos, a); + vector.draw(&poly); + vector.text("Hello World", &pos); + + // update screen + st7789.update(&graphics); + a += 1; + if (a > 359) { + a = 0; + } + } + + return 0; +} diff --git a/examples/pico_display_2/vector/DynaPuff-Medium.af b/examples/pico_display_2/vector/DynaPuff-Medium.af new file mode 100644 index 0000000000000000000000000000000000000000..5a935f3fa34df238fb51d6e8bd62edf6db4b3478 GIT binary patch literal 9688 zcma)hXL~AXnqE~wkuz0A&N+hsp?qSWb9#Dudg9KmckT7A?R8$~9Daa*&UBxkoDo?F z5d{(m1j+>E04l%g8L$0mFJF8>RjBHH-zVMob3cFaSGpGv1pPVmzl0`83;u${5Trv$ z@z+uW(j!)b)`CC=gnawqJpvh#yTC6;D3A#uU%h*aLS_m%_5L*lvLIHzRt!T{^ji1F zRv5Cu;M)vCc3A0fx?#wHupBNA3^|c&Oe=*U7a}tYZ7}3UNK68*J@B>XkB4B$OM%DU zyh0!!Ose0SU}y*-J#YOmPM-eFad=2goBV^#K5d;dsr0cC0hDIpl z@K+NQX!H;F$H4n1!8yjky6?gF1kAFzoiH?s@EjHo0!{tl`UOlnzjh(eOUmW1fBUBh z^a>$IK1?FeYZMB8n4~~&DCF3?7cle|d3y2nTLk(FC4C=8VCWq>aD4##cuyf;egOAB zpy0XJF!VJ_!M;+%&`)4;?D;+4pycp}Nf`PmN_yW9!_c=VIrZTK4E+oxM?buQq3o;E`(9cma@NNu&enENq`olL==$Fs$dx=25LZHBVu->m>GW1~#hJJ&R!S`T4e}sVN zr(o!}DEZZgpTW={BjoE3?_lUpU~=LE`2Fu7U|sP4e~RAdertiDKl_87|1SLd>%WH> z%nk<({W)?H+`gHvGN{|O=APksYK{~0F7r@;OHf}D?hHvvQc73_Nw z*zLbjZ(P3xe){i>Gr?bKVCaAR;rf442)oD&bH#k#pRt2XCdR-R;ul;t-(>QcMSPw_ zi)q|JJI`69+Gwua94yzG#nj{hi=hpf_~meQ-b7Av0-uFkjhDtZh?A+f{ZY zZRwe`C%Go>@xGYUH4RN`!&$MHECoYOU67Y$Rarwezz2dp>w$Jhxkh@FHtmdaqBzr> z8IE;_>XxJ-*k@H~WonkXP1|I~*b%`xv8q_sFPWDeE1tEX@Nhhs97;Pgri^k+n!$2- zQByYWI`@6ez^T7I)bm_AZ)|s_M{QrhkkJVghb0f%dp)e9s%eTf*_>=z`C0qX@YytN znKP{lb~roCA}vqdMiNMrx=veRE(+$v^O8mRigH~OS8pma^1P%d+!Af!aq)(5jTh#` zxoJP-ft*jazUAI@Vd_{;ZAZ?QzcG9;)|xzear(OV>iWgqWPj`_a2vWA?TxepC%!XJ z&wC?;IS{+gxfAqMyOy|n$u}RI9ho0n8VLuI?!39KJChD@QU>FY2;x1l9~pPFYw88% zlyZnR7*$RMD`FL4nOEfGSP52)y}?}*EEDtE8RM*N-nHag4aEE@-eH*W!t{{ z&~fB!`u0Y4M$41CFKSbb@gsl7e>U8ixO(~UVlY9DLc@@6V83zR*zYZUe{L?$C1dG&9Z# z^OlA4*o@?}_IuqA#!u#H)0}o$5tbydZSk(SiJ!}^w0%8krkYR#L(P^k#i$SlR(N1u z(>t_dLrve*ooGAiE5*I^35P{gKApj)u_z1}g%QSpeb2uXpW^%2jxfWG(O0NT$PDrs z{mA;B_fb4e%*&P)>*|;`t;=fv_j-0IlLsSu@C4CT8&=e4ql zB*xg_M~Nhs62*i|!g=uw@kKf{eOwd<_f>&62`Ls?g~G;Q^T;#zt`+=wm(=Yk{A zzPKT1GFxbq(m<+|3a!K{a7g+SsjCh8D3*pmq5(^+gfgN|~Z*oTZm zY7?nZcUdKIQB}|sjU~&jxoT`^n#3XJgm)@x6W92iXdw8pYEhq%o8P~W#zvUHelYEd zb;{qz^0I_}&M;&7vJxI?#0uU31%d>No^;C^>T0 zjCoU+P$w0evJCLWE?$=$%1#w+;H^c~sye30YIijU>NC}q@=*qSE+F|2yc_Nbx5?Y( z=R^r{LYU%YXjw`Y-b51A2xE=A%wLo(s27dPwslw3x8==wiq49yW@>7W73abWQCHU0 z_RN=#YtOxFV1*2@6cR$LC)xnm_y)N`yR0+Ofn;B?t1fACnyhL|l463oio_}4?Yw3A zymrB|Y+rMQJyBoEn|aPPOGRB%SM~drhNI~|@^w7du3P(qrEefLkObyKOcL!=ZmE~d zE^#5h(44E!lqXnA(B#y(dxA1vk`**t%9JF*Owm%52xWt|##t6GXc09mC#Cn&8%0~u zA-e1yt&5z)$H)P7m!9Lqc@fbXu_Ry6&zk0}3yvk%iYMYuJ9iv)`@W|Z*dI9xodnwM zuB`(;m-buRgPFwYL|s+`X9Fv$lFGO&L8QbPL6N^J*!OODKrEX#MM*r4ZHbGb3V%ns zqbeJAtu^O?_sr9AgW77pH}?%s|L?gdSF{UOS8^e{Q1!HD>J#}P(c-q4En0(CrR8WT zMwq$6SrpFe7OjiU<)Kw?*d4Q_j2TH0FRBZ=qN!vnyLP>`p?aV-d>ZToE_^rcdq>~$ zWQ0_}I~c@&V)q&M=ndr(IRnVI$IJ`k#D;Q3zi6Lx%zGA94M|gUBs>Lq(NkWiFAQDF ziTT*jJS2l^HJOk9=a^>IT|vdP_~rQi*C zow7<_)XbUY?Tg-(KzL*`v>nX*cf7myefyrP=Boz|h7U*Eq07Ln_t8!&VF}>ne3CO@ zJOWJXQqIw1Mw3&=_wc%KpIc?^(o5(Tnxe&-8=N)%ig;17VBNB$jY)M}n#4B68F3ab zD2wW%F|TeaTEvm~4C_cQR2P~HQ`dHCIX1MYKQa$)SJG8vsXB18(`66FO&_6}o*S^#V&L5W8@PwZ_I$a>iYyTYhYcaR)4!%Fc|SkjQN zBpqp2#+kJjO*`7Mtip^4VqmSbF>l$i?^*XvP4%g?E4pOd&~7MKa2IK#r|ctPQ(M*6 zq4<*O^Q`QNy#jXo?i5*2wwWZvY#Mud2 z9Ered$TDr7J;Qil+yQ2HDe7StQh;poM+y1N5|~deu9ahCYglqR4sekB#Js0nQ9G0- zWuIE1=UH3axF}4lC>C_H<}cn)fzP8~re>Rt0+$bJ210&>web6{L1)8>3v?<0IYnbgk_nZzL1*?Iwui(i!3-%rBp5?%D zY&&BCP7ToMnsQEU(kskuUR1b>FUV)L(}o%IoPEKyJQN9}L*>!d_~qE`=tF1_Bz>?O zvOig_EOp1R`BZxckO#h24qzd`P>e-!oV21#8xnG{m$KRSe*FnkY)jiai;G zLqZa;j6VIAc8MOKWm<+2Wv_6S_zT#aY}PpKnDxyMuK<>u7~TwI93@A|y)#q^Rzvl% zqtVmhp6|x~XdqRWh6_u_acpZD8|r;o18-p`*tw*q%4u_ktYyodu*QrV+OTRv8pTt1 zTC#11wUC^|`+|G+6{CxuP-*~6^NchnCR`_$l?#?x=bUe0cxh~PDmIxMO9!^y8RMoV zt=N_nKy_&Vq&!ic8QSKy|15Yu3K-q^-N<8b;3dTf_s7nJ@<@3=?^su&3&AzN%RAy# zd0T>rJVHcyF?I}%AgjnSy2zO4&Pu1%Gsd~+iZ{Fg{Jr&R=VkRpV*()e^Z8u&R=~?t zkiKJT+fJQLPsNpYWUMJ;To={ERVmfBs;p{i&dt;I8TYJj&c86c5?uFhcq6WuDUQYP zD87Xi#RXZxlC$SMMSsOtbJk4_Q5~yc2lz1#Vg5+u8B;g4cojp}uEehIEh| zCO~y%f-IqR(S5W?OVcB)72YB?rvR+i0_wkeVQ9_wj9qbSLYu^rcnmLM1!+-LGM8Od zU&C|gJhq3wOrUQ++A;b=*U+W zPK#!UIoXOdEJF7H6z7mf7?CFJQHK>9TC+ zxqHJN_ydp)pxOZLzDZwUEU;(vF)S%c@&JeDtcvHQbJ`i}v}ek;*U9_ z4#2lODc`og6s!jh{b#x?fu5AZV$jVnAE?*x3DTri8D(yfR}z)6s`%(RM-s&>_7W6ja>o(8+4ccFgZ_cj@r9`rYWYo8Mh@HxeM*sb_c_#}DW z8OeA)>j_!~aj*tDzydbiJJo20jod>%9OW*A?KhZ-f zXao*I{wLp~_tJal+x5r%G4GbU;HX&l4F}qWa!*zO(I3S(iMpgqT;cbkKBzTM%s%}A z?Sj~=(6$&Lp1Jd)8GKH@q~0)Qjaf_FvFZUQ8=e`Tf3f~D`KtK3@uvIw`qll5{v;`! z#Xx_mSl6Y@CD)1j#MyA<91&psg`w%-%-F*C#$;})K6yHRHToDJy`-yey)||B-W&SNys0y^*e9b;yFpK%^Ocrkq}c16RsNEAK{}@?=}N|;E$c|x;^v4xtlp5vBuOG8 z$;(TBbBbH`|LIqD&>Ulv6BPpPte7{?*k)aGpbK9bU6}~KjJ^g6$h+K!^1H^HvzNWG z+t9uL(ed;Sc?C@jMs8nr-d+CW_S?sA$gd&and8{fH1At>9c5R=R}CGS&u!n z8QL8#1#-SESJE8QCKQ{JEM5V;`%r!QH|IEc_B}nzNCCFAB3hKpD`rigdU~ICvNoBV z*c!`@6oX~ouB&R>*YE4=)|Tfua6a0byq$O$9rz(PX?f6INDhbt;zujt1E9DRj0J1X zvF%DZ6SjzcUG;2J^vE}@GVwvA;|!_qTfo9+#L9bnEfNJ4^rKZq_w zZSf(tM{LVt@`ND8NikE@1RO?I(M9GQZ&nRBws63?V?0-bJm@Ianadz!X7PFHl6)1f z;Rm3qpUBU(ZGGE(VmY+ctVQ#xdBHtBG#gwTSskm5wnhL_`>#C@j)8^rgFFd6SLBVc z#AtT7;%|D|_G?pL3n@XrA?^$BxtGjSS{*RO3=&1clofQ5KF^uq%?jp4i{ceLD#^*J z>Ylo%J+f@t!;U4-EDCrxZH=+~W1X7E7Kv49l&BG>l2chtl?S;Ru|#cg*OspwIvqI; z)rL2QS4S4cW?xLdnt3z#)#CfruM;1#@2l^Qzq)??I7N=ZAt=!I-Z>E;L*LLIsm~P`(p&sNG`BU5Ps4W9g1;S5RbTfX~+973ua04eN$cXq4a=%)J_r=Y@x{s2iST%IG%=hW+IHt{CEc#RY(BPLS?DhmNi_cK4f;H9P6{H_HshTG{(Y|eX=l+|Q8xuW!3Ew^whia5 zQ{Q>88@e36@q;c+4~bwN!~$I(^^sul87!26&`I>>8C}pgz_>-$Ecc7>ll*(lN8=as ztZ81qtXLJTh?hVgyeB*tkUYTDR1ca*L*EP;DLR^(;bdDF28y~*w1o{$k&!~zkp=h* z@)7->`H4R#T*NozTiUX*W$QZc-H;dc(1qV)Kgd35<}{1Ch+#*6sOxAS)ua-Up*Wq( zqB9VnW5E!0zfE(lngb+iV4H2Ro$97Y>&9(flM$T zs*QF=ZiWFm0j2TEcxi2$&veJCBgwJ&Ow<;2@yloYr#(`8)CQWQFEVD>pZGrrKVn}b zi$oO9it|`Tnp6S(%@%dXhtk8jvHIvC=xacRd+(in8)<+vkn%~^C+@`;*p=u}Kx!^^ zmxi9H4Yb;ZwPx8h?HCH0tTHDn0F19-4eSsaQoM}3Sj_Vw7xL)9D=+51@k`iDq z?tpoZUV_eT4+UAmO-iE5xB+yrmW(NGoHI^aKG}b80<|r;6x59|V6 zjrGcYWd(Y+exN4Rmq3^8n$N5UmVNV{v8*qt^NND3Bq`&2UR0pDT}|7e=~#UtI}xKq6AqWpK-E2G8#McT5u|UKY(77m+Mr9*1iVD#| zM$$a6-B`Q!uJy`vtG`!2s=C^);T%+@eaoJC$5_wey0vEB(dRV<6;N7ad(x)# zNPZ)`mplQT8{&|F6<*Q0)B-g{jnI}EbF9z&PlC_bv}A!;!ocK#9j33L3$$6*7k*rj z5N%@Hco8swGyGC~5AYFYK@5QL=neG**y+Ffih2<=7N2Q0Yeop^Vc}f zx!I>SsC#IdzC>SOeG!1%#J@1Jm&{i2UzzW|Beh_~m zW+bc91X02dMAzIa-le!JYb(3z3+=V$R`nnqV9-$3pAID^qHn?h^W-?ZH>ox4W-PQ~9w{Xm7X~JPzCqJvyI&j?gz< zgDO_i=G9p+`zZqyzrr4XMgXx$VBKr#0h*yDSP|YjKP-v@Hk1W?Xj77qM*(|Zv#dKd z+%a#;pA)PJ*D;`x5!(dNkY#Zdn3-5sZEMc3Co&Wd09|pU2$)H84Ee8n{RY zX&qQ@EnT376m{ER{i38s9D}~$Ry^Q7<5wTOr}of2Fi}Z?>DY!El0!Ht>;ng1(|Xi% z$^oTDEz=9E3^yf=5fSyeK5ULSVxE*gGn^kOk2l7Sp6le$wfo-QH$Q25x}LEED$23F zZmU|$W}rf9wv|~Kn0eu4td6ztW67DU1C-0KIF4_Lx3M&ll*LpL<2tD48!nK^{&X-K zDvs`t90$8YH|_`1lkQ11kU!#A#1-)z1myYyy)*kJur!@vJN>#eU_uvH_0pTni;I26TJw z^NbAWHb56^J?mn$JR`$S@?ye>WL*xl7H!m!0CjfDlCniWMFW-}He1w@bY;OrW7k%*Gz?8$Q`1maR7J(MG)L@8+p-(UBSs2;pW`>Q9(t?+&so-g zv|!4Uc5U0TifvgI&xwmzS+c9#)mLqGcgxrIT)F_SHatl|Zm^!vN6Izj3hl8v@}8=v zJAc;OC5OU8_5rO%DN?iaO-@|6frrIl8Uwn-FUpUa&$?;DoPJ3g)`V?qj&;w5KQXlF z*|z2YFU#n54JXDc!<}xRAr*l8;!mP`;kB?MJQUTi3;~dqU7+QWZ8(L*Xd9gMA<{!S z`}TYLrTx-!Ykbs@QbR$JT1JTgd za3NUrA9_2^YwLsI$L@h3#RJYI;~YJp>>!(z7;POXAvsDKP0*uY+PEQziBjTiaT{yn z$3#QACogF-rlfV#ne*+2&cP=gN{&TduDxD=yYVjiKJoSThn@G0cc))ny}5fa7=;7m z&;U${t^q2XnyaQN@au`Dqq>scNx<}7S^+znBj z*pe4@N4g_@%~Y_aoiYDfV0~m`EIGOrD*6vRXZ9P@la{JrNqCei$_3hCoU#uE4SY|r zW8OArYlibl@H^2D*k@vnSdqk~bxDVKA{ZD?D8jxceo%e_bIlD?!BVglT|3^Y zXWw;TZ5dmJw&77nsu2Y$q4NPa(&5nh^A;?Q0KMS$BYx8pEM~4XpOPU GD*tatPE3mc literal 0 HcmV?d00001 diff --git a/libraries/pico_vector/af-file-io.c b/libraries/pico_vector/af-file-io.c new file mode 100644 index 00000000..718f528a --- /dev/null +++ b/libraries/pico_vector/af-file-io.c @@ -0,0 +1,36 @@ +#include "af-file-io.h" +#include "string.h" + +static size_t ptr = 0; + +void* fileio_open(const char* filename) { + ptr = 0; + return NULL; +} + +void fileio_close(void* fhandle) { + ptr = 0; + return; +} + +size_t fileio_read(void* fhandle, void *buf, size_t len) { + memcpy(buf, fhandle + ptr, len); + ptr += len; + return len; +} + +int fileio_getc(void* fhandle) { + uint8_t *f = fhandle; + int c = f[ptr]; + ptr += 1; + return c; +} + +size_t fileio_tell(void* fhandle) { + return ptr; +} + +size_t fileio_seek(void* fhandle, size_t pos) { + ptr = pos; + return ptr; +} \ No newline at end of file diff --git a/libraries/pico_vector/af-file-io.h b/libraries/pico_vector/af-file-io.h index eb5a413b..3070f7ae 100644 --- a/libraries/pico_vector/af-file-io.h +++ b/libraries/pico_vector/af-file-io.h @@ -1,7 +1,9 @@ #include #include +#ifdef __cplusplus extern "C" { +#endif void* fileio_open(const char* filename); void fileio_close(void* fhandle); @@ -13,4 +15,6 @@ int fileio_getc(void* fhandle); size_t fileio_tell(void* fhandle); size_t fileio_seek(void* fhandle, size_t pos); -} \ No newline at end of file +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libraries/pico_vector/af-memory.c b/libraries/pico_vector/af-memory.c new file mode 100644 index 00000000..5aa20aa2 --- /dev/null +++ b/libraries/pico_vector/af-memory.c @@ -0,0 +1,24 @@ +#include "af-memory.h" +#include +#include +#include + +void *af_malloc(size_t size) { + return malloc(size); +} + +void *af_realloc(void *p, size_t size) { + return realloc(p, size); +} + +void af_free(void *p) { + free(p); +} + +void af_debug(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int ret = printf(fmt, ap); + va_end(ap); + (void)ret; +} \ No newline at end of file diff --git a/libraries/pico_vector/af-memory.h b/libraries/pico_vector/af-memory.h index 22e01c90..f522d2cc 100644 --- a/libraries/pico_vector/af-memory.h +++ b/libraries/pico_vector/af-memory.h @@ -1,6 +1,12 @@ +#include + +#ifdef __cplusplus extern "C" { +#endif void *af_malloc(size_t size); void *af_realloc(void *p, size_t size); void af_free(void *p); void af_debug(const char *fmt, ...); -} \ No newline at end of file +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libraries/pico_vector/alright_fonts.cpp b/libraries/pico_vector/alright_fonts.cpp deleted file mode 100644 index b276b1ee..00000000 --- a/libraries/pico_vector/alright_fonts.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "alright_fonts.hpp" - -namespace alright_fonts { - /* - utility functions - */ - pp_rect_t measure_character(text_metrics_t &tm, uint16_t codepoint) { - if(tm.face.glyphs.count(codepoint) == 1) { - glyph_t glyph = tm.face.glyphs[codepoint]; - - return {0, 0, ((glyph.advance * tm.size) / 128), tm.size}; - } - - return {0, 0, 0, 0}; - } - - /* - render functions - */ - - void render_character(text_metrics_t &tm, uint16_t codepoint, pp_point_t origin, pp_mat3_t *transform) { - if(tm.face.glyphs.count(codepoint) == 1) { - glyph_t glyph = tm.face.glyphs[codepoint]; - pp_transform(transform); - pp_render(&glyph.contours); - } - } - /* - load functions - */ - - // big endian stream value helpers - uint16_t ru16(file_io &ifs) {uint8_t w[2]; ifs.read((char *)w, 2); return w[0] << 8 | w[1];} - int16_t rs16(file_io &ifs) {uint8_t w[2]; ifs.read((char *)w, 2); return w[0] << 8 | w[1];} - uint32_t ru32(file_io &ifs) {uint8_t dw[4]; ifs.read((char *)dw, 4); return dw[0] << 24 | dw[1] << 16 | dw[2] << 8 | dw[3];} - uint8_t ru8(file_io &ifs) {uint8_t w; ifs.read(&w, 1); return w;} - int8_t rs8(file_io &ifs) {int8_t w; ifs.read(&w, 1); return w;} - - bool face_t::load(file_io &ifs) { - char marker[4]; - ifs.read(marker, sizeof(marker)); - - // check header magic bytes are present - if(memcmp(marker, "af!?", 4) != 0) { - // doesn't start with magic marker - return false; - } - - // number of glyphs embedded in font file - this->glyph_count = ru16(ifs); - - // extract flags and ensure none set - this->flags = ru16(ifs); - if(this->flags != 0) { - // unknown flags set - return false; - } - - // extract glyph dictionary - uint16_t glyph_entry_size = 9; - uint32_t contour_data_offset = 8 + this->glyph_count * glyph_entry_size; - for(auto i = 0; i < this->glyph_count; i++) { - glyph_t g; - g.codepoint = ru16(ifs); - g.bounds.x = rs8(ifs); - g.bounds.y = rs8(ifs); - g.bounds.w = ru8(ifs); - g.bounds.h = ru8(ifs); - g.advance = ru8(ifs); - - g.contours.paths = (pp_path_t *)malloc(sizeof(pp_path_t) * 10); - - if(ifs.fail()) { - // could not read glyph dictionary entry - return false; - } - - // allocate space for the contour data and read it from the font file - uint16_t contour_data_length = ru16(ifs); - - // remember where we are in the dictionary - int pos = ifs.tell(); - - // read contour data - ifs.seek(contour_data_offset); - while(true) { - // get number of points in contour - uint16_t count = ru16(ifs); - - // if count is zero then this is the end of contour marker - if(count == 0) { - break; - } - - // allocate space to store point data for contour and read - // from file - g.contours.paths[g.contours.count].points = (pp_point_t *)malloc(sizeof(pp_point_t) * count); - - ifs.read((char *)g.contours.paths[g.contours.count].points, sizeof(pp_point_t) * count); - - g.contours.count ++; - } - - // return back to position in dictionary - ifs.seek(pos); - contour_data_offset += contour_data_length; - - if(ifs.fail()) { - // could not read glyph contour data - return false; - } - - this->glyphs[g.codepoint] = g; - } - - return true; - } - - bool face_t::load(std::string_view path) { - file_io ifs(path); - if(ifs.fail()) { - // could not open file - return false; - } - return load(ifs); - } - -} \ No newline at end of file diff --git a/libraries/pico_vector/alright_fonts.hpp b/libraries/pico_vector/alright_fonts.hpp deleted file mode 100644 index 2bd83b65..00000000 --- a/libraries/pico_vector/alright_fonts.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "pretty-poly.h" -#include "file_io.hpp" - -namespace alright_fonts { - - struct glyph_t { - uint16_t codepoint; - pp_rect_t bounds; - uint8_t advance; - pp_poly_t contours; - }; - - struct face_t { - uint16_t glyph_count; - uint16_t flags; - std::map glyphs; - - face_t() {}; - face_t(file_io &ifs) {load(ifs);} - face_t(std::string_view path) {load(path);} - - bool load(file_io &ifs); - bool load(std::string_view path); - }; - - enum alignment_t { - left = 0, - center = 1, - right = 2, - justify = 4, - top = 8, - bottom = 16 - }; - - struct text_metrics_t { - face_t face; // font to write in - int size; // text size in pixels - uint scroll; // vertical scroll offset - int line_height; // spacing between lines (%) - int letter_spacing; // spacing between characters - int word_spacing; // spacing between words - alignment_t align; // horizontal and vertical alignment - //optional transform; // arbitrary transformation - pp_antialias_t antialiasing = PP_AA_X4; // level of antialiasing to apply - - void set_size(int s) { - size = s; - line_height = size; - letter_spacing = 0; - word_spacing = size / 2; - } - - text_metrics_t() {}; - }; - - /* - utility functions - */ - pp_rect_t measure_character(text_metrics_t &tm, uint16_t codepoint); - - /* - render functions - */ - - void render_character(text_metrics_t &tm, uint16_t codepoint, pp_point_t origin, pp_mat3_t *transform); -} \ No newline at end of file diff --git a/libraries/pico_vector/pico_vector.cmake b/libraries/pico_vector/pico_vector.cmake index 73f17c5f..3a3af2d5 100644 --- a/libraries/pico_vector/pico_vector.cmake +++ b/libraries/pico_vector/pico_vector.cmake @@ -4,7 +4,8 @@ endif() add_library(pico_vector ${CMAKE_CURRENT_LIST_DIR}/pico_vector.cpp - ${CMAKE_CURRENT_LIST_DIR}/alright_fonts.cpp + ${CMAKE_CURRENT_LIST_DIR}/af-file-io.c + ${CMAKE_CURRENT_LIST_DIR}/af-memory.c ) target_include_directories(pico_vector INTERFACE ${CMAKE_CURRENT_LIST_DIR}) diff --git a/libraries/pico_vector/pico_vector.hpp b/libraries/pico_vector/pico_vector.hpp index 1d96aabd..d76904d5 100644 --- a/libraries/pico_vector/pico_vector.hpp +++ b/libraries/pico_vector/pico_vector.hpp @@ -112,7 +112,20 @@ namespace pimoroni { return result; } - pp_point_t text(std::string_view text, pp_mat3_t *t); + bool set_font(void* font, unsigned int font_size) { + if(text_metrics.face) { + af_free(text_metrics.face->glyphs); + af_free(text_metrics.face); + } + text_metrics.face = (af_face_t *)af_malloc(sizeof(af_face_t)); + bool result = af_load_font_file(font, text_metrics.face); + + set_font_size(font_size); + + return result; + } + + pp_point_t text(std::string_view text, pp_mat3_t *t=nullptr); void transform(pp_path_t *path, pp_mat3_t *t); void transform(pp_poly_t *poly, pp_mat3_t *t);