445 |
433 |
446 |
434 |
447 |
435 |
448 |
436 |
449 //----------------------------------------------------------------------------------------------- |
437 //----------------------------------------------------------------------------------------------- |
450 static void _drawLineByAngle(int16_t x, int16_t y, int16_t angle, uint16_t length, color_t color) |
|
451 { |
|
452 _drawLine( |
|
453 x, |
|
454 y, |
|
455 x + length * cos((angle + _angleOffset) * DEG_TO_RAD), |
|
456 y + length * sin((angle + _angleOffset) * DEG_TO_RAD), color); |
|
457 } |
|
458 |
|
459 //--------------------------------------------------------------------------------------------------------------- |
|
460 static void _DrawLineByAngle(int16_t x, int16_t y, int16_t angle, uint16_t start, uint16_t length, color_t color) |
|
461 { |
|
462 _drawLine( |
|
463 x + start * cos((angle + _angleOffset) * DEG_TO_RAD), |
|
464 y + start * sin((angle + _angleOffset) * DEG_TO_RAD), |
|
465 x + (start + length) * cos((angle + _angleOffset) * DEG_TO_RAD), |
|
466 y + (start + length) * sin((angle + _angleOffset) * DEG_TO_RAD), color); |
|
467 } |
|
468 |
|
469 //=========================================================================================================== |
|
470 void TFT_drawLineByAngle(uint16_t x, uint16_t y, uint16_t start, uint16_t len, uint16_t angle, color_t color) |
|
471 { |
|
472 x += dispWin.x1; |
|
473 y += dispWin.y1; |
|
474 |
|
475 if (start == 0) _drawLineByAngle(x, y, angle, len, color); |
|
476 else _DrawLineByAngle(x, y, angle, start, len, color); |
|
477 } |
|
478 |
|
479 |
438 |
480 // Draw a triangle |
439 // Draw a triangle |
481 //-------------------------------------------------------------------------------------------------------------------- |
440 //-------------------------------------------------------------------------------------------------------------------- |
482 static void _drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, color_t color) |
441 static void _drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, color_t color) |
483 { |
442 { |
484 _drawLine(x0, y0, x1, y1, color); |
|
485 _drawLine(x1, y1, x2, y2, color); |
|
486 _drawLine(x2, y2, x0, y0, color); |
|
487 } |
|
488 |
|
489 //================================================================================================================ |
|
490 void TFT_drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, color_t color) |
|
491 { |
|
492 x0 += dispWin.x1; |
|
493 y0 += dispWin.y1; |
|
494 x1 += dispWin.x1; |
|
495 y1 += dispWin.y1; |
|
496 x2 += dispWin.x1; |
|
497 y2 += dispWin.y1; |
|
498 |
|
499 _drawLine(x0, y0, x1, y1, color); |
443 _drawLine(x0, y0, x1, y1, color); |
500 _drawLine(x1, y1, x2, y2, color); |
444 _drawLine(x1, y1, x2, y2, color); |
501 _drawLine(x2, y2, x0, y0, color); |
445 _drawLine(x2, y2, x0, y0, color); |
502 } |
446 } |
503 |
447 |
632 |
566 |
633 _drawFastVLine(x, y-radius, 2*radius+1, color); |
567 _drawFastVLine(x, y-radius, 2*radius+1, color); |
634 fillCircleHelper(x, y, radius, 3, 0, color); |
568 fillCircleHelper(x, y, radius, 3, 0, color); |
635 } |
569 } |
636 |
570 |
637 //---------------------------------------------------------------------------------------------------------------- |
|
638 static void _draw_ellipse_section(uint16_t x, uint16_t y, uint16_t x0, uint16_t y0, color_t color, uint8_t option) |
|
639 { |
|
640 disp_select(); |
|
641 // upper right |
|
642 if ( option & TFT_ELLIPSE_UPPER_RIGHT ) _drawPixel(x0 + x, y0 - y, color, 0); |
|
643 // upper left |
|
644 if ( option & TFT_ELLIPSE_UPPER_LEFT ) _drawPixel(x0 - x, y0 - y, color, 0); |
|
645 // lower right |
|
646 if ( option & TFT_ELLIPSE_LOWER_RIGHT ) _drawPixel(x0 + x, y0 + y, color, 0); |
|
647 // lower left |
|
648 if ( option & TFT_ELLIPSE_LOWER_LEFT ) _drawPixel(x0 - x, y0 + y, color, 0); |
|
649 disp_deselect(); |
|
650 } |
|
651 |
|
652 //===================================================================================================== |
|
653 void TFT_drawEllipse(uint16_t x0, uint16_t y0, uint16_t rx, uint16_t ry, color_t color, uint8_t option) |
|
654 { |
|
655 x0 += dispWin.x1; |
|
656 y0 += dispWin.y1; |
|
657 |
|
658 uint16_t x, y; |
|
659 int32_t xchg, ychg; |
|
660 int32_t err; |
|
661 int32_t rxrx2; |
|
662 int32_t ryry2; |
|
663 int32_t stopx, stopy; |
|
664 |
|
665 rxrx2 = rx; |
|
666 rxrx2 *= rx; |
|
667 rxrx2 *= 2; |
|
668 |
|
669 ryry2 = ry; |
|
670 ryry2 *= ry; |
|
671 ryry2 *= 2; |
|
672 |
|
673 x = rx; |
|
674 y = 0; |
|
675 |
|
676 xchg = 1; |
|
677 xchg -= rx; |
|
678 xchg -= rx; |
|
679 xchg *= ry; |
|
680 xchg *= ry; |
|
681 |
|
682 ychg = rx; |
|
683 ychg *= rx; |
|
684 |
|
685 err = 0; |
|
686 |
|
687 stopx = ryry2; |
|
688 stopx *= rx; |
|
689 stopy = 0; |
|
690 |
|
691 while( stopx >= stopy ) { |
|
692 _draw_ellipse_section(x, y, x0, y0, color, option); |
|
693 y++; |
|
694 stopy += rxrx2; |
|
695 err += ychg; |
|
696 ychg += rxrx2; |
|
697 if ( 2*err+xchg > 0 ) { |
|
698 x--; |
|
699 stopx -= ryry2; |
|
700 err += xchg; |
|
701 xchg += ryry2; |
|
702 } |
|
703 } |
|
704 |
|
705 x = 0; |
|
706 y = ry; |
|
707 |
|
708 xchg = ry; |
|
709 xchg *= ry; |
|
710 |
|
711 ychg = 1; |
|
712 ychg -= ry; |
|
713 ychg -= ry; |
|
714 ychg *= rx; |
|
715 ychg *= rx; |
|
716 |
|
717 err = 0; |
|
718 |
|
719 stopx = 0; |
|
720 |
|
721 stopy = rxrx2; |
|
722 stopy *= ry; |
|
723 |
|
724 while( stopx <= stopy ) { |
|
725 _draw_ellipse_section(x, y, x0, y0, color, option); |
|
726 x++; |
|
727 stopx += ryry2; |
|
728 err += xchg; |
|
729 xchg += ryry2; |
|
730 if ( 2*err+ychg > 0 ) { |
|
731 y--; |
|
732 stopy -= rxrx2; |
|
733 err += ychg; |
|
734 ychg += rxrx2; |
|
735 } |
|
736 } |
|
737 } |
|
738 |
|
739 //----------------------------------------------------------------------------------------------------------------------- |
|
740 static void _draw_filled_ellipse_section(uint16_t x, uint16_t y, uint16_t x0, uint16_t y0, color_t color, uint8_t option) |
|
741 { |
|
742 // upper right |
|
743 if ( option & TFT_ELLIPSE_UPPER_RIGHT ) _drawFastVLine(x0+x, y0-y, y+1, color); |
|
744 // upper left |
|
745 if ( option & TFT_ELLIPSE_UPPER_LEFT ) _drawFastVLine(x0-x, y0-y, y+1, color); |
|
746 // lower right |
|
747 if ( option & TFT_ELLIPSE_LOWER_RIGHT ) _drawFastVLine(x0+x, y0, y+1, color); |
|
748 // lower left |
|
749 if ( option & TFT_ELLIPSE_LOWER_LEFT ) _drawFastVLine(x0-x, y0, y+1, color); |
|
750 } |
|
751 |
|
752 //===================================================================================================== |
|
753 void TFT_fillEllipse(uint16_t x0, uint16_t y0, uint16_t rx, uint16_t ry, color_t color, uint8_t option) |
|
754 { |
|
755 x0 += dispWin.x1; |
|
756 y0 += dispWin.y1; |
|
757 |
|
758 uint16_t x, y; |
|
759 int32_t xchg, ychg; |
|
760 int32_t err; |
|
761 int32_t rxrx2; |
|
762 int32_t ryry2; |
|
763 int32_t stopx, stopy; |
|
764 |
|
765 rxrx2 = rx; |
|
766 rxrx2 *= rx; |
|
767 rxrx2 *= 2; |
|
768 |
|
769 ryry2 = ry; |
|
770 ryry2 *= ry; |
|
771 ryry2 *= 2; |
|
772 |
|
773 x = rx; |
|
774 y = 0; |
|
775 |
|
776 xchg = 1; |
|
777 xchg -= rx; |
|
778 xchg -= rx; |
|
779 xchg *= ry; |
|
780 xchg *= ry; |
|
781 |
|
782 ychg = rx; |
|
783 ychg *= rx; |
|
784 |
|
785 err = 0; |
|
786 |
|
787 stopx = ryry2; |
|
788 stopx *= rx; |
|
789 stopy = 0; |
|
790 |
|
791 while( stopx >= stopy ) { |
|
792 _draw_filled_ellipse_section(x, y, x0, y0, color, option); |
|
793 y++; |
|
794 stopy += rxrx2; |
|
795 err += ychg; |
|
796 ychg += rxrx2; |
|
797 if ( 2*err+xchg > 0 ) { |
|
798 x--; |
|
799 stopx -= ryry2; |
|
800 err += xchg; |
|
801 xchg += ryry2; |
|
802 } |
|
803 } |
|
804 |
|
805 x = 0; |
|
806 y = ry; |
|
807 |
|
808 xchg = ry; |
|
809 xchg *= ry; |
|
810 |
|
811 ychg = 1; |
|
812 ychg -= ry; |
|
813 ychg -= ry; |
|
814 ychg *= rx; |
|
815 ychg *= rx; |
|
816 |
|
817 err = 0; |
|
818 |
|
819 stopx = 0; |
|
820 |
|
821 stopy = rxrx2; |
|
822 stopy *= ry; |
|
823 |
|
824 while( stopx <= stopy ) { |
|
825 _draw_filled_ellipse_section(x, y, x0, y0, color, option); |
|
826 x++; |
|
827 stopx += ryry2; |
|
828 err += xchg; |
|
829 xchg += ryry2; |
|
830 if ( 2*err+ychg > 0 ) { |
|
831 y--; |
|
832 stopy -= rxrx2; |
|
833 err += ychg; |
|
834 ychg += rxrx2; |
|
835 } |
|
836 } |
|
837 } |
|
838 |
|
839 |
|
840 // ==== ARC DRAWING =================================================================== |
|
841 |
|
842 //--------------------------------------------------------------------------------------------------------------------------------- |
|
843 static void _fillArcOffsetted(uint16_t cx, uint16_t cy, uint16_t radius, uint16_t thickness, float start, float end, color_t color) |
|
844 { |
|
845 //float sslope = (float)cos_lookup(start) / (float)sin_lookup(start); |
|
846 //float eslope = (float)cos_lookup(end) / (float)sin_lookup(end); |
|
847 float sslope = (cos(start/_arcAngleMax * 2 * PI) * _arcAngleMax) / (sin(start/_arcAngleMax * 2 * PI) * _arcAngleMax) ; |
|
848 float eslope = (cos(end/_arcAngleMax * 2 * PI) * _arcAngleMax) / (sin(end/_arcAngleMax * 2 * PI) * _arcAngleMax); |
|
849 |
|
850 if (end == 360) eslope = -1000000; |
|
851 |
|
852 int ir2 = (radius - thickness) * (radius - thickness); |
|
853 int or2 = radius * radius; |
|
854 |
|
855 disp_select(); |
|
856 for (int x = -radius; x <= radius; x++) { |
|
857 for (int y = -radius; y <= radius; y++) { |
|
858 int x2 = x * x; |
|
859 int y2 = y * y; |
|
860 |
|
861 if ( |
|
862 (x2 + y2 < or2 && x2 + y2 >= ir2) && |
|
863 ( |
|
864 (y > 0 && start < 180 && x <= y * sslope) || |
|
865 (y < 0 && start > 180 && x >= y * sslope) || |
|
866 (y < 0 && start <= 180) || |
|
867 (y == 0 && start <= 180 && x < 0) || |
|
868 (y == 0 && start == 0 && x > 0) |
|
869 ) && |
|
870 ( |
|
871 (y > 0 && end < 180 && x >= y * eslope) || |
|
872 (y < 0 && end > 180 && x <= y * eslope) || |
|
873 (y > 0 && end >= 180) || |
|
874 (y == 0 && end >= 180 && x < 0) || |
|
875 (y == 0 && start == 0 && x > 0) |
|
876 ) |
|
877 ) |
|
878 _drawPixel(cx+x, cy+y, color, 0); |
|
879 } |
|
880 } |
|
881 disp_deselect(); |
|
882 } |
|
883 |
|
884 |
|
885 //=========================================================================================================================== |
|
886 void TFT_drawArc(uint16_t cx, uint16_t cy, uint16_t r, uint16_t th, float start, float end, color_t color, color_t fillcolor) |
|
887 { |
|
888 cx += dispWin.x1; |
|
889 cy += dispWin.y1; |
|
890 |
|
891 if (th < 1) th = 1; |
|
892 if (th > r) th = r; |
|
893 |
|
894 int f = TFT_compare_colors(fillcolor, color); |
|
895 |
|
896 float astart = fmodf(start, _arcAngleMax); |
|
897 float aend = fmodf(end, _arcAngleMax); |
|
898 |
|
899 astart += _angleOffset; |
|
900 aend += _angleOffset; |
|
901 |
|
902 if (astart < 0) astart += (float)360; |
|
903 if (aend < 0) aend += (float)360; |
|
904 |
|
905 if (aend == 0) aend = (float)360; |
|
906 |
|
907 if (astart > aend) { |
|
908 _fillArcOffsetted(cx, cy, r, th, astart, _arcAngleMax, fillcolor); |
|
909 _fillArcOffsetted(cx, cy, r, th, 0, aend, fillcolor); |
|
910 if (f) { |
|
911 _fillArcOffsetted(cx, cy, r, 1, astart, _arcAngleMax, color); |
|
912 _fillArcOffsetted(cx, cy, r, 1, 0, aend, color); |
|
913 _fillArcOffsetted(cx, cy, r-th, 1, astart, _arcAngleMax, color); |
|
914 _fillArcOffsetted(cx, cy, r-th, 1, 0, aend, color); |
|
915 } |
|
916 } |
|
917 else { |
|
918 _fillArcOffsetted(cx, cy, r, th, astart, aend, fillcolor); |
|
919 if (f) { |
|
920 _fillArcOffsetted(cx, cy, r, 1, astart, aend, color); |
|
921 _fillArcOffsetted(cx, cy, r-th, 1, astart, aend, color); |
|
922 } |
|
923 } |
|
924 if (f) { |
|
925 _drawLine(cx + (r-th) * cos(astart * DEG_TO_RAD), cy + (r-th) * sin(astart * DEG_TO_RAD), |
|
926 cx + (r-1) * cos(astart * DEG_TO_RAD), cy + (r-1) * sin(astart * DEG_TO_RAD), color); |
|
927 _drawLine(cx + (r-th) * cos(aend * DEG_TO_RAD), cy + (r-th) * sin(aend * DEG_TO_RAD), |
|
928 cx + (r-1) * cos(aend * DEG_TO_RAD), cy + (r-1) * sin(aend * DEG_TO_RAD), color); |
|
929 } |
|
930 } |
|
931 |
|
932 //============================================================================================================= |
|
933 void TFT_drawPolygon(int cx, int cy, int sides, int diameter, color_t color, color_t fill, int rot, uint8_t th) |
|
934 { |
|
935 cx += dispWin.x1; |
|
936 cy += dispWin.y1; |
|
937 |
|
938 int deg = rot - _angleOffset; |
|
939 int f = TFT_compare_colors(fill, color); |
|
940 |
|
941 if (sides < MIN_POLIGON_SIDES) sides = MIN_POLIGON_SIDES; // This ensures the minimum side number |
|
942 if (sides > MAX_POLIGON_SIDES) sides = MAX_POLIGON_SIDES; // This ensures the maximum side number |
|
943 |
|
944 int Xpoints[sides], Ypoints[sides]; // Set the arrays based on the number of sides entered |
|
945 int rads = 360 / sides; // This equally spaces the points. |
|
946 |
|
947 for (int idx = 0; idx < sides; idx++) { |
|
948 Xpoints[idx] = cx + sin((float)(idx*rads + deg) * deg_to_rad) * diameter; |
|
949 Ypoints[idx] = cy + cos((float)(idx*rads + deg) * deg_to_rad) * diameter; |
|
950 } |
|
951 |
|
952 // Draw the polygon on the screen. |
|
953 if (f) { |
|
954 for(int idx = 0; idx < sides; idx++) { |
|
955 if((idx+1) < sides) _fillTriangle(cx,cy,Xpoints[idx],Ypoints[idx],Xpoints[idx+1],Ypoints[idx+1], fill); |
|
956 else _fillTriangle(cx,cy,Xpoints[idx],Ypoints[idx],Xpoints[0],Ypoints[0], fill); |
|
957 } |
|
958 } |
|
959 |
|
960 if (th) { |
|
961 for (int n=0; n<th; n++) { |
|
962 if (n > 0) { |
|
963 for (int idx = 0; idx < sides; idx++) { |
|
964 Xpoints[idx] = cx + sin((float)(idx*rads + deg) * deg_to_rad) * (diameter-n); |
|
965 Ypoints[idx] = cy + cos((float)(idx*rads + deg) * deg_to_rad) * (diameter-n); |
|
966 } |
|
967 } |
|
968 for(int idx = 0; idx < sides; idx++) { |
|
969 if( (idx+1) < sides) |
|
970 _drawLine(Xpoints[idx],Ypoints[idx],Xpoints[idx+1],Ypoints[idx+1], color); // draw the lines |
|
971 else |
|
972 _drawLine(Xpoints[idx],Ypoints[idx],Xpoints[0],Ypoints[0], color); // finishes the last line to close up the polygon. |
|
973 } |
|
974 } |
|
975 } |
|
976 } |
|
977 |
|
978 /* |
|
979 // Similar to the Polygon function. |
|
980 //===================================================================================== |
|
981 void TFT_drawStar(int cx, int cy, int diameter, color_t color, bool fill, float factor) |
|
982 { |
|
983 cx += dispWin.x1; |
|
984 cy += dispWin.y1; |
|
985 |
|
986 factor = constrain(factor, 1.0, 4.0); |
|
987 uint8_t sides = 5; |
|
988 uint8_t rads = 360 / sides; |
|
989 |
|
990 int Xpoints_O[sides], Ypoints_O[sides], Xpoints_I[sides], Ypoints_I[sides];//Xpoints_T[5], Ypoints_T[5]; |
|
991 |
|
992 for(int idx = 0; idx < sides; idx++) { |
|
993 // makes the outer points |
|
994 Xpoints_O[idx] = cx + sin((float)(idx*rads + 72) * deg_to_rad) * diameter; |
|
995 Ypoints_O[idx] = cy + cos((float)(idx*rads + 72) * deg_to_rad) * diameter; |
|
996 // makes the inner points |
|
997 Xpoints_I[idx] = cx + sin((float)(idx*rads + 36) * deg_to_rad) * ((float)(diameter)/factor); |
|
998 // 36 is half of 72, and this will allow the inner and outer points to line up like a triangle. |
|
999 Ypoints_I[idx] = cy + cos((float)(idx*rads + 36) * deg_to_rad) * ((float)(diameter)/factor); |
|
1000 } |
|
1001 |
|
1002 for(int idx = 0; idx < sides; idx++) { |
|
1003 if((idx+1) < sides) { |
|
1004 if(fill) {// this part below should be self explanatory. It fills in the star. |
|
1005 _fillTriangle(cx,cy,Xpoints_I[idx],Ypoints_I[idx],Xpoints_O[idx],Ypoints_O[idx], color); |
|
1006 _fillTriangle(cx,cy,Xpoints_O[idx],Ypoints_O[idx],Xpoints_I[idx+1],Ypoints_I[idx+1], color); |
|
1007 } |
|
1008 else { |
|
1009 _drawLine(Xpoints_O[idx],Ypoints_O[idx],Xpoints_I[idx+1],Ypoints_I[idx+1], color); |
|
1010 _drawLine(Xpoints_I[idx],Ypoints_I[idx],Xpoints_O[idx],Ypoints_O[idx], color); |
|
1011 } |
|
1012 } |
|
1013 else { |
|
1014 if(fill) { |
|
1015 _fillTriangle(cx,cy,Xpoints_I[0],Ypoints_I[0],Xpoints_O[idx],Ypoints_O[idx], color); |
|
1016 _fillTriangle(cx,cy,Xpoints_O[idx],Ypoints_O[idx],Xpoints_I[idx],Ypoints_I[idx], color); |
|
1017 } |
|
1018 else { |
|
1019 _drawLine(Xpoints_O[idx],Ypoints_O[idx],Xpoints_I[idx],Ypoints_I[idx], color); |
|
1020 _drawLine(Xpoints_I[0],Ypoints_I[0],Xpoints_O[idx],Ypoints_O[idx], color); |
|
1021 } |
|
1022 } |
|
1023 } |
|
1024 } |
|
1025 */ |
|
1026 |
571 |
1027 // ================ Font and string functions ================================== |
572 // ================ Font and string functions ================================== |
1028 |
573 |
1029 //-------------------------------------------------------- |
574 //-------------------------------------------------------- |
1030 static int load_file_font(const char * fontfile, int info) |
575 static int load_file_font(const char * fontfile, int info) |
1152 free(userfont); |
697 free(userfont); |
1153 userfont = NULL; |
698 userfont = NULL; |
1154 } |
699 } |
1155 if (info) printf("Error: %d [%s]\r\n", err, err_msg); |
700 if (info) printf("Error: %d [%s]\r\n", err, err_msg); |
1156 } |
701 } |
1157 return err; |
|
1158 } |
|
1159 |
|
1160 //------------------------------------------------ |
|
1161 int compile_font_file(char *fontfile, uint8_t dbg) |
|
1162 { |
|
1163 int err = 0; |
|
1164 char err_msg[128] = {'\0'}; |
|
1165 char outfile[128] = {'\0'}; |
|
1166 size_t len; |
|
1167 struct stat sb; |
|
1168 FILE *ffd = NULL; |
|
1169 FILE *ffd_out = NULL; |
|
1170 char *sourcebuf = NULL; |
|
1171 |
|
1172 len = strlen(fontfile); |
|
1173 |
|
1174 // check here that filename end with ".c". |
|
1175 if ((len < 3) || (len > 125) || (strcmp(fontfile + len - 2, ".c") != 0)) { |
|
1176 sprintf(err_msg, "not a .c file"); |
|
1177 err = 1; |
|
1178 goto exit; |
|
1179 } |
|
1180 |
|
1181 sprintf(outfile, "%s", fontfile); |
|
1182 sprintf(outfile+strlen(outfile)-1, "fon"); |
|
1183 |
|
1184 // Open the source file |
|
1185 if (stat(fontfile, &sb) != 0) { |
|
1186 sprintf(err_msg, "Error opening source file '%s'", fontfile); |
|
1187 err = 2; |
|
1188 goto exit; |
|
1189 } |
|
1190 // Open the file |
|
1191 ffd = fopen(fontfile, "rb"); |
|
1192 if (!ffd) { |
|
1193 sprintf(err_msg, "Error opening source file '%s'", fontfile); |
|
1194 err = 3; |
|
1195 goto exit; |
|
1196 } |
|
1197 |
|
1198 // Open the font file |
|
1199 ffd_out= fopen(outfile, "wb"); |
|
1200 if (!ffd_out) { |
|
1201 sprintf(err_msg, "error opening destination file"); |
|
1202 err = 4; |
|
1203 goto exit; |
|
1204 } |
|
1205 |
|
1206 // Get file size |
|
1207 int fsize = sb.st_size; |
|
1208 if (fsize <= 0) { |
|
1209 sprintf(err_msg, "source file size error"); |
|
1210 err = 5; |
|
1211 goto exit; |
|
1212 } |
|
1213 |
|
1214 sourcebuf = malloc(fsize+4); |
|
1215 if (sourcebuf == NULL) { |
|
1216 sprintf(err_msg, "memory allocation error"); |
|
1217 err = 6; |
|
1218 goto exit; |
|
1219 } |
|
1220 char *fbuf = sourcebuf; |
|
1221 |
|
1222 int rdsize = fread(fbuf, 1, fsize, ffd); |
|
1223 fclose(ffd); |
|
1224 ffd = NULL; |
|
1225 |
|
1226 if (rdsize != fsize) { |
|
1227 sprintf(err_msg, "error reading from source file"); |
|
1228 err = 7; |
|
1229 goto exit; |
|
1230 } |
|
1231 |
|
1232 *(fbuf+rdsize) = '\0'; |
|
1233 |
|
1234 fbuf = strchr(fbuf, '{'); // beginning of font data |
|
1235 char *fend = strstr(fbuf, "};"); // end of font data |
|
1236 |
|
1237 if ((fbuf == NULL) || (fend == NULL) || ((fend-fbuf) < 22)) { |
|
1238 sprintf(err_msg, "wrong source file format"); |
|
1239 err = 8; |
|
1240 goto exit; |
|
1241 } |
|
1242 |
|
1243 fbuf++; |
|
1244 *fend = '\0'; |
|
1245 char hexstr[5] = {'\0'}; |
|
1246 int lastline = 0; |
|
1247 |
|
1248 fbuf = strstr(fbuf, "0x"); |
|
1249 int size = 0; |
|
1250 char *nextline; |
|
1251 char *numptr; |
|
1252 |
|
1253 int bptr = 0; |
|
1254 |
|
1255 while ((fbuf != NULL) && (fbuf < fend) && (lastline == 0)) { |
|
1256 nextline = strchr(fbuf, '\n'); // beginning of the next line |
|
1257 if (nextline == NULL) { |
|
1258 nextline = fend-1; |
|
1259 lastline++; |
|
1260 } |
|
1261 else nextline++; |
|
1262 |
|
1263 while (fbuf < nextline) { |
|
1264 numptr = strstr(fbuf, "0x"); |
|
1265 if ((numptr == NULL) || ((fbuf+4) > nextline)) numptr = strstr(fbuf, "0X"); |
|
1266 if ((numptr != NULL) && ((numptr+4) <= nextline)) { |
|
1267 fbuf = numptr; |
|
1268 if (bptr >= 128) { |
|
1269 // buffer full, write to file |
|
1270 if (fwrite(outfile, 1, 128, ffd_out) != 128) goto error; |
|
1271 bptr = 0; |
|
1272 size += 128; |
|
1273 } |
|
1274 memcpy(hexstr, fbuf, 4); |
|
1275 hexstr[4] = 0; |
|
1276 outfile[bptr++] = (uint8_t)strtol(hexstr, NULL, 0); |
|
1277 fbuf += 4; |
|
1278 } |
|
1279 else fbuf = nextline; |
|
1280 } |
|
1281 fbuf = nextline; |
|
1282 } |
|
1283 |
|
1284 if (bptr > 0) { |
|
1285 size += bptr; |
|
1286 if (fwrite(outfile, 1, bptr, ffd_out) != bptr) goto error; |
|
1287 } |
|
1288 |
|
1289 // write font ID |
|
1290 sprintf(outfile, "RPH_font"); |
|
1291 if (fwrite(outfile, 1, 8, ffd_out) != 8) goto error; |
|
1292 |
|
1293 fclose(ffd_out); |
|
1294 ffd_out = NULL; |
|
1295 |
|
1296 // === Test compiled font === |
|
1297 sprintf(outfile, "%s", fontfile); |
|
1298 sprintf(outfile+strlen(outfile)-1, "fon"); |
|
1299 |
|
1300 uint8_t *uf = userfont; // save userfont pointer |
|
1301 userfont = NULL; |
|
1302 if (load_file_font(outfile, 1) != 0) { |
|
1303 sprintf(err_msg, "Error compiling file!"); |
|
1304 err = 10; |
|
1305 } |
|
1306 else { |
|
1307 free(userfont); |
|
1308 sprintf(err_msg, "File compiled successfully."); |
|
1309 } |
|
1310 userfont = uf; // restore userfont |
|
1311 |
|
1312 goto exit; |
|
1313 |
|
1314 error: |
|
1315 sprintf(err_msg, "error writing to destination file"); |
|
1316 err = 9; |
|
1317 |
|
1318 exit: |
|
1319 if (sourcebuf) free(sourcebuf); |
|
1320 if (ffd) fclose(ffd); |
|
1321 if (ffd_out) fclose(ffd_out); |
|
1322 |
|
1323 if (dbg) printf("%s\r\n", err_msg); |
|
1324 |
|
1325 return err; |
702 return err; |
1326 } |
703 } |
1327 |
704 |
1328 |
705 |
1329 // ----------------------------------------------------------------------------------------- |
706 // ----------------------------------------------------------------------------------------- |