components/tft/tft.c

changeset 20
3fd5e0fc075f
parent 18
5d4a40fe9967
child 29
45647136ec95
equal deleted inserted replaced
19:49e2960d4642 20:3fd5e0fc075f
121 static dispWin_t dispWinTemp; 121 static dispWin_t dispWinTemp;
122 122
123 static uint8_t *userfont = NULL; 123 static uint8_t *userfont = NULL;
124 static int TFT_OFFSET = 0; 124 static int TFT_OFFSET = 0;
125 static propFont fontChar; 125 static propFont fontChar;
126 static float _arcAngleMax = DEFAULT_ARC_ANGLE_MAX;
127 126
128 127
129 // ========================================================================= 128 // =========================================================================
130 // ** All drawings are clipped to 'dispWin' ** 129 // ** All drawings are clipped to 'dispWin' **
131 // ** All x,y coordinates in public functions are relative to clip window ** 130 // ** All x,y coordinates in public functions are relative to clip window **
132 // =========== : Public functions 131 // =========== : Public functions
133 // ----------- : Local functions 132 // ----------- : Local functions
134 // ========================================================================= 133 // =========================================================================
135 134
136
137 // Compare two colors; return 0 if equal
138 //============================================
139 int TFT_compare_colors(color_t c1, color_t c2)
140 {
141 if ((c1.r & 0xFC) != (c2.r & 0xFC)) return 1;
142 if ((c1.g & 0xFC) != (c2.g & 0xFC)) return 1;
143 if ((c1.b & 0xFC) != (c2.b & 0xFC)) return 1;
144
145 return 0;
146 }
147 135
148 // draw color pixel on screen 136 // draw color pixel on screen
149 //------------------------------------------------------------------------ 137 //------------------------------------------------------------------------
150 static void _drawPixel(int16_t x, int16_t y, color_t color, uint8_t sel) { 138 static void _drawPixel(int16_t x, int16_t y, color_t color, uint8_t sel) {
151 139
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
577 if(a > b) swap(a,b); 521 if(a > b) swap(a,b);
578 _drawFastHLine(a, y, b-a+1, color); 522 _drawFastHLine(a, y, b-a+1, color);
579 } 523 }
580 } 524 }
581 525
582 //================================================================================================================
583 void TFT_fillTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, color_t color)
584 {
585 _fillTriangle(
586 x0 + dispWin.x1, y0 + dispWin.y1,
587 x1 + dispWin.x1, y1 + dispWin.y1,
588 x2 + dispWin.x1, y2 + dispWin.y1,
589 color);
590 }
591
592 //==================================================================== 526 //====================================================================
593 void TFT_drawCircle(int16_t x, int16_t y, int radius, color_t color) { 527 void TFT_drawCircle(int16_t x, int16_t y, int radius, color_t color) {
594 x += dispWin.x1; 528 x += dispWin.x1;
595 y += dispWin.y1; 529 y += dispWin.y1;
596 int f = 1 - radius; 530 int f = 1 - radius;
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 // -----------------------------------------------------------------------------------------
1342 // Character drawing rectangle is (0, 0) (xDelta-1, cfont.y_size-1) 719 // Character drawing rectangle is (0, 0) (xDelta-1, cfont.y_size-1)
1343 // Character visible pixels rectangle is (xOffset, yOffset) (xOffset+Width-1, yOffset+Height-1) 720 // Character visible pixels rectangle is (xOffset, yOffset) (xOffset+Width-1, yOffset+Height-1)
1344 //--------------------------------------------------------------------------------------------- 721 //---------------------------------------------------------------------------------------------
1345 722
1346 //---------------------------------- 723 //----------------------------------
1347 void getFontCharacters(uint8_t *buf)
1348 {
1349 if (cfont.bitmap == 2) {
1350 //For 7 segment font only characters 0,1,2,3,4,5,6,7,8,9, . , - , : , / are available.
1351 for (uint8_t n=0; n < 11; n++) {
1352 buf[n] = n + 0x30;
1353 }
1354 buf[11] = '.';
1355 buf[12] = '-';
1356 buf[13] = '/';
1357 buf[14] = '\0';
1358 return;
1359 }
1360
1361 if (cfont.x_size > 0) {
1362 for (uint8_t n=0; n < cfont.numchars; n++) {
1363 buf[n] = cfont.offset + n;
1364 }
1365 buf[cfont.numchars] = '\0';
1366 return;
1367 }
1368
1369 uint16_t tempPtr = 4; // point at first char data
1370 uint8_t cc, cw, ch, n;
1371
1372 n = 0;
1373 cc = cfont.font[tempPtr++];
1374 while (cc != 0xFF) {
1375 cfont.numchars++;
1376 tempPtr++;
1377 cw = cfont.font[tempPtr++];
1378 ch = cfont.font[tempPtr++];
1379 tempPtr++;
1380 tempPtr++;
1381 if (cw != 0) {
1382 // packed bits
1383 tempPtr += (((cw * ch)-1) / 8) + 1;
1384 }
1385 buf[n++] = cc;
1386 cc = cfont.font[tempPtr++];
1387 }
1388 buf[n] = '\0';
1389 }
1390 724
1391 // Set max width & height of the proportional font 725 // Set max width & height of the proportional font
1392 //----------------------------- 726 //-----------------------------
1393 static void getMaxWidthHeight() 727 static void getMaxWidthHeight()
1394 { 728 {
1455 else return 0; 789 else return 0;
1456 790
1457 return 1; 791 return 1;
1458 } 792 }
1459 793
1460 /*
1461 //-----------------------
1462 static void _testFont() {
1463 if (cfont.x_size) {
1464 printf("FONT TEST: fixed font\r\n");
1465 return;
1466 }
1467 uint16_t tempPtr = 4; // point at first char data
1468 uint8_t c = 0x20;
1469 for (c=0x20; c <0xFF; c++) {
1470 fontChar.charCode = cfont.font[tempPtr++];
1471 if (fontChar.charCode == 0xFF) break;
1472 if (fontChar.charCode != c) {
1473 printf("FONT TEST: last sequential char: %d, expected %d\r\n", fontChar.charCode, c);
1474 break;
1475 }
1476 c = fontChar.charCode;
1477 fontChar.adjYOffset = cfont.font[tempPtr++];
1478 fontChar.width = cfont.font[tempPtr++];
1479 fontChar.height = cfont.font[tempPtr++];
1480 fontChar.xOffset = cfont.font[tempPtr++];
1481 fontChar.xOffset = fontChar.xOffset < 0x80 ? fontChar.xOffset : -(0xFF - fontChar.xOffset);
1482 fontChar.xDelta = cfont.font[tempPtr++];
1483
1484 if (fontChar.charCode != 0xFF) {
1485 if (fontChar.width != 0) {
1486 // packed bits
1487 tempPtr += (((fontChar.width * fontChar.height)-1) / 8) + 1;
1488 }
1489 }
1490 }
1491 printf("FONT TEST: W=%d H=%d last char: %d [%c]; length: %d\r\n", cfont.max_x_size, cfont.y_size, c, c, tempPtr);
1492 }
1493 */
1494 794
1495 //=================================================== 795 //===================================================
1496 void TFT_setFont(uint8_t font, const char *font_file) 796 void TFT_setFont(uint8_t font, const char *font_file)
1497 { 797 {
1498 cfont.font = NULL; 798 cfont.font = NULL;
2091 dispWin.y2 = _height-1; 1391 dispWin.y2 = _height-1;
2092 1392
2093 TFT_fillScreen(_bg); 1393 TFT_fillScreen(_bg);
2094 } 1394 }
2095 1395
2096 // Send the command to invert all of the colors.
2097 // Input: i 0 to disable inversion; non-zero to enable inversion
2098 //==========================================
2099 void TFT_invertDisplay(const uint8_t mode) {
2100 if ( mode == INVERT_ON ) disp_spi_transfer_cmd(TFT_INVONN);
2101 else disp_spi_transfer_cmd(TFT_INVOFF);
2102 }
2103 1396
2104 // Select gamma curve 1397 // Select gamma curve
2105 // Input: gamma = 0~3 1398 // Input: gamma = 0~3
2106 //================================== 1399 //==================================
2107 void TFT_setGammaCurve(uint8_t gm) { 1400 void TFT_setGammaCurve(uint8_t gm) {
2108 uint8_t gamma_curve = 1 << (gm & 0x03); 1401 uint8_t gamma_curve = 1 << (gm & 0x03);
2109 disp_spi_transfer_cmd_data(TFT_CMD_GAMMASET, &gamma_curve, 1); 1402 disp_spi_transfer_cmd_data(TFT_CMD_GAMMASET, &gamma_curve, 1);
2110 } 1403 }
2111 1404
2112 //=========================================================== 1405
2113 color_t HSBtoRGB(float _hue, float _sat, float _brightness) {
2114 float red = 0.0;
2115 float green = 0.0;
2116 float blue = 0.0;
2117
2118 if (_sat == 0.0) {
2119 red = _brightness;
2120 green = _brightness;
2121 blue = _brightness;
2122 } else {
2123 if (_hue == 360.0) {
2124 _hue = 0;
2125 }
2126
2127 int slice = (int)(_hue / 60.0);
2128 float hue_frac = (_hue / 60.0) - slice;
2129
2130 float aa = _brightness * (1.0 - _sat);
2131 float bb = _brightness * (1.0 - _sat * hue_frac);
2132 float cc = _brightness * (1.0 - _sat * (1.0 - hue_frac));
2133
2134 switch(slice) {
2135 case 0:
2136 red = _brightness;
2137 green = cc;
2138 blue = aa;
2139 break;
2140 case 1:
2141 red = bb;
2142 green = _brightness;
2143 blue = aa;
2144 break;
2145 case 2:
2146 red = aa;
2147 green = _brightness;
2148 blue = cc;
2149 break;
2150 case 3:
2151 red = aa;
2152 green = bb;
2153 blue = _brightness;
2154 break;
2155 case 4:
2156 red = cc;
2157 green = aa;
2158 blue = _brightness;
2159 break;
2160 case 5:
2161 red = _brightness;
2162 green = aa;
2163 blue = bb;
2164 break;
2165 default:
2166 red = 0.0;
2167 green = 0.0;
2168 blue = 0.0;
2169 break;
2170 }
2171 }
2172
2173 color_t color;
2174 color.r = ((uint8_t)(red * 255.0)) & 0xFC;
2175 color.g = ((uint8_t)(green * 255.0)) & 0xFC;
2176 color.b = ((uint8_t)(blue * 255.0)) & 0xFC;
2177
2178 return color;
2179 }
2180 //===================================================================== 1406 //=====================================================================
2181 void TFT_setclipwin(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) 1407 void TFT_setclipwin(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
2182 { 1408 {
2183 dispWin.x1 = x1; 1409 dispWin.x1 = x1;
2184 dispWin.y1 = y1; 1410 dispWin.y1 = y1;

mercurial