diff options
Diffstat (limited to 'firmware/drivers/lcd-16bit.c')
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 347 |
1 files changed, 1 insertions, 346 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 882bfa0854..7238d7a923 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -638,70 +638,6 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
638 | while (dst < dst_end); | 638 | while (dst < dst_end); |
639 | } | 639 | } |
640 | 640 | ||
641 | /* Fill a rectangle with a gradient */ | ||
642 | static void lcd_gradient_rect(int x1, int x2, int y, int h) | ||
643 | { | ||
644 | int old_pattern = current_vp->fg_pattern; | ||
645 | |||
646 | if (h == 0) return; | ||
647 | |||
648 | int h_r = RGB_UNPACK_RED(current_vp->lss_pattern) << 16; | ||
649 | int h_b = RGB_UNPACK_BLUE(current_vp->lss_pattern) << 16; | ||
650 | int h_g = RGB_UNPACK_GREEN(current_vp->lss_pattern) << 16; | ||
651 | int rstep = (h_r - ((signed)RGB_UNPACK_RED(current_vp->lse_pattern) << 16)) / h; | ||
652 | int gstep = (h_g - ((signed)RGB_UNPACK_GREEN(current_vp->lse_pattern) << 16)) / h; | ||
653 | int bstep = (h_b - ((signed)RGB_UNPACK_BLUE(current_vp->lse_pattern) << 16)) / h; | ||
654 | int count; | ||
655 | |||
656 | current_vp->fg_pattern = current_vp->lss_pattern; | ||
657 | for(count = 0; count < h; count++) { | ||
658 | lcd_hline(x1, x2, y + count); | ||
659 | h_r -= rstep; | ||
660 | h_g -= gstep; | ||
661 | h_b -= bstep; | ||
662 | current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); | ||
663 | } | ||
664 | |||
665 | current_vp->fg_pattern = old_pattern; | ||
666 | } | ||
667 | |||
668 | #define H_COLOR(lss, lse, cur_line, max_line) \ | ||
669 | (((lse) - (lss)) * (cur_line) / (max_line) + (lss)) | ||
670 | |||
671 | /* Fill a rectangle with a gradient for scrolling line. To draw a gradient that | ||
672 | covers several lines, we need to know how many lines will be covered | ||
673 | (the num_lines arg), and which one is the current line within the selection | ||
674 | (the cur_line arg). */ | ||
675 | static void lcd_gradient_rect_scroll(int x1, int x2, int y, int h, | ||
676 | unsigned char num_lines, unsigned char cur_line) | ||
677 | { | ||
678 | if (h == 0 || num_lines == 0) return; | ||
679 | |||
680 | unsigned tmp_lss = current_vp->lss_pattern; | ||
681 | unsigned tmp_lse = current_vp->lse_pattern; | ||
682 | int lss_r = (signed)RGB_UNPACK_RED(current_vp->lss_pattern); | ||
683 | int lss_b = (signed)RGB_UNPACK_BLUE(current_vp->lss_pattern); | ||
684 | int lss_g = (signed)RGB_UNPACK_GREEN(current_vp->lss_pattern); | ||
685 | int lse_r = (signed)RGB_UNPACK_RED(current_vp->lse_pattern); | ||
686 | int lse_b = (signed)RGB_UNPACK_BLUE(current_vp->lse_pattern); | ||
687 | int lse_g = (signed)RGB_UNPACK_GREEN(current_vp->lse_pattern); | ||
688 | |||
689 | int h_r = H_COLOR(lss_r, lse_r, cur_line, num_lines); | ||
690 | int h_g = H_COLOR(lss_g, lse_g, cur_line, num_lines); | ||
691 | int h_b = H_COLOR(lss_b, lse_b, cur_line, num_lines); | ||
692 | lcd_set_selector_start(LCD_RGBPACK(h_r, h_g, h_b)); | ||
693 | |||
694 | int l_r = H_COLOR(lss_r, lse_r, cur_line+1, num_lines); | ||
695 | int l_g = H_COLOR(lss_g, lse_g, cur_line+1, num_lines); | ||
696 | int l_b = H_COLOR(lss_b, lse_b, cur_line+1, num_lines); | ||
697 | lcd_set_selector_end(LCD_RGBPACK(l_r, l_g, l_b)); | ||
698 | |||
699 | lcd_gradient_rect(x1, x2, y, h); | ||
700 | |||
701 | current_vp->lss_pattern = tmp_lss; | ||
702 | current_vp->lse_pattern = tmp_lse; | ||
703 | } | ||
704 | |||
705 | /* About Rockbox' internal monochrome bitmap format: | 641 | /* About Rockbox' internal monochrome bitmap format: |
706 | * | 642 | * |
707 | * A bitmap contains one bit for every pixel that defines if that pixel is | 643 | * A bitmap contains one bit for every pixel that defines if that pixel is |
@@ -977,285 +913,4 @@ void lcd_bitmap_transparent(const fb_data *src, int x, int y, | |||
977 | lcd_bitmap_transparent_part(src, 0, 0, width, x, y, width, height); | 913 | lcd_bitmap_transparent_part(src, 0, 0, width, x, y, width, height); |
978 | } | 914 | } |
979 | 915 | ||
980 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 916 | #include "lcd-bitmap-common.c" |
981 | static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | ||
982 | { | ||
983 | unsigned short ch; | ||
984 | unsigned short *ucs; | ||
985 | struct font* pf = font_get(current_vp->font); | ||
986 | |||
987 | ucs = bidi_l2v(str, 1); | ||
988 | |||
989 | while ((ch = *ucs++) != 0 && x < current_vp->width) | ||
990 | { | ||
991 | int width; | ||
992 | const unsigned char *bits; | ||
993 | |||
994 | /* get proportional width and glyph bits */ | ||
995 | width = font_get_width(pf,ch); | ||
996 | |||
997 | if (ofs > width) | ||
998 | { | ||
999 | ofs -= width; | ||
1000 | continue; | ||
1001 | } | ||
1002 | |||
1003 | bits = font_get_bits(pf, ch); | ||
1004 | |||
1005 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); | ||
1006 | |||
1007 | x += width - ofs; | ||
1008 | ofs = 0; | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | /* put a string at a given pixel position */ | ||
1013 | void lcd_putsxy(int x, int y, const unsigned char *str) | ||
1014 | { | ||
1015 | lcd_putsxyofs(x, y, 0, str); | ||
1016 | } | ||
1017 | |||
1018 | /*** line oriented text output ***/ | ||
1019 | |||
1020 | /* put a string at a given char position */ | ||
1021 | void lcd_puts(int x, int y, const unsigned char *str) | ||
1022 | { | ||
1023 | lcd_puts_style_offset(x, y, str, STYLE_DEFAULT, 0); | ||
1024 | } | ||
1025 | |||
1026 | void lcd_puts_style(int x, int y, const unsigned char *str, int style) | ||
1027 | { | ||
1028 | lcd_puts_style_offset(x, y, str, style, 0); | ||
1029 | } | ||
1030 | |||
1031 | void lcd_puts_offset(int x, int y, const unsigned char *str, int offset) | ||
1032 | { | ||
1033 | lcd_puts_style_offset(x, y, str, STYLE_DEFAULT, offset); | ||
1034 | } | ||
1035 | |||
1036 | /* put a string at a given char position, style, and pixel position, | ||
1037 | * skipping first offset pixel columns */ | ||
1038 | void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, | ||
1039 | int offset) | ||
1040 | { | ||
1041 | int xpos,ypos,w,h,xrect; | ||
1042 | int lastmode = current_vp->drawmode; | ||
1043 | int oldfgcolor = current_vp->fg_pattern; | ||
1044 | int oldbgcolor = current_vp->bg_pattern; | ||
1045 | |||
1046 | /* make sure scrolling is turned off on the line we are updating */ | ||
1047 | lcd_scroll_stop_line(current_vp, y); | ||
1048 | |||
1049 | if(!str || !str[0]) | ||
1050 | return; | ||
1051 | |||
1052 | lcd_getstringsize(str, &w, &h); | ||
1053 | xpos = x*w / utf8length(str); | ||
1054 | ypos = y*h; | ||
1055 | current_vp->drawmode = (style & STYLE_INVERT) ? | ||
1056 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
1057 | if (style & STYLE_COLORED) { | ||
1058 | if (current_vp->drawmode == DRMODE_SOLID) | ||
1059 | current_vp->fg_pattern = style & STYLE_COLOR_MASK; | ||
1060 | else | ||
1061 | current_vp->bg_pattern = style & STYLE_COLOR_MASK; | ||
1062 | } | ||
1063 | current_vp->drawmode ^= DRMODE_INVERSEVID; | ||
1064 | xrect = xpos + MAX(w - offset, 0); | ||
1065 | |||
1066 | if (style & STYLE_GRADIENT) { | ||
1067 | current_vp->drawmode = DRMODE_FG; | ||
1068 | if (CURLN_UNPACK(style) == 0) | ||
1069 | lcd_gradient_rect(xpos, current_vp->width, ypos, h*NUMLN_UNPACK(style)); | ||
1070 | current_vp->fg_pattern = current_vp->lst_pattern; | ||
1071 | } | ||
1072 | else if (style & STYLE_COLORBAR) { | ||
1073 | current_vp->drawmode = DRMODE_FG; | ||
1074 | current_vp->fg_pattern = current_vp->lss_pattern; | ||
1075 | lcd_fillrect(xpos, ypos, current_vp->width - xpos, h); | ||
1076 | current_vp->fg_pattern = current_vp->lst_pattern; | ||
1077 | } | ||
1078 | else { | ||
1079 | lcd_fillrect(xrect, ypos, current_vp->width - xrect, h); | ||
1080 | current_vp->drawmode = (style & STYLE_INVERT) ? | ||
1081 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
1082 | } | ||
1083 | lcd_putsxyofs(xpos, ypos, offset, str); | ||
1084 | current_vp->drawmode = lastmode; | ||
1085 | current_vp->fg_pattern = oldfgcolor; | ||
1086 | current_vp->bg_pattern = oldbgcolor; | ||
1087 | } | ||
1088 | |||
1089 | /*** scrolling ***/ | ||
1090 | void lcd_puts_scroll(int x, int y, const unsigned char *string) | ||
1091 | { | ||
1092 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); | ||
1093 | } | ||
1094 | |||
1095 | void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) | ||
1096 | { | ||
1097 | lcd_puts_scroll_style_offset(x, y, string, style, 0); | ||
1098 | } | ||
1099 | |||
1100 | void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offset) | ||
1101 | { | ||
1102 | lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); | ||
1103 | } | ||
1104 | |||
1105 | /* Initialise a scrolling line at (x,y) in current viewport */ | ||
1106 | |||
1107 | void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | ||
1108 | int style, int offset) | ||
1109 | { | ||
1110 | struct scrollinfo* s; | ||
1111 | int w, h; | ||
1112 | |||
1113 | if ((unsigned)y >= (unsigned)current_vp->height) | ||
1114 | return; | ||
1115 | |||
1116 | /* remove any previously scrolling line at the same location */ | ||
1117 | lcd_scroll_stop_line(current_vp, y); | ||
1118 | |||
1119 | if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return; | ||
1120 | |||
1121 | s = &lcd_scroll_info.scroll[lcd_scroll_info.lines]; | ||
1122 | |||
1123 | s->start_tick = current_tick + lcd_scroll_info.delay; | ||
1124 | s->style = style; | ||
1125 | lcd_puts_style_offset(x,y,string,style,offset); | ||
1126 | |||
1127 | lcd_getstringsize(string, &w, &h); | ||
1128 | |||
1129 | if (current_vp->width - x * 8 < w) { | ||
1130 | /* prepare scroll line */ | ||
1131 | char *end; | ||
1132 | |||
1133 | memset(s->line, 0, sizeof s->line); | ||
1134 | strcpy(s->line, string); | ||
1135 | |||
1136 | /* get width */ | ||
1137 | s->width = lcd_getstringsize(s->line, &w, &h); | ||
1138 | |||
1139 | /* scroll bidirectional or forward only depending on the string | ||
1140 | width */ | ||
1141 | if ( lcd_scroll_info.bidir_limit ) { | ||
1142 | s->bidir = s->width < (current_vp->width) * | ||
1143 | (100 + lcd_scroll_info.bidir_limit) / 100; | ||
1144 | } | ||
1145 | else | ||
1146 | s->bidir = false; | ||
1147 | |||
1148 | if (!s->bidir) { /* add spaces if scrolling in the round */ | ||
1149 | strcat(s->line, " "); | ||
1150 | /* get new width incl. spaces */ | ||
1151 | s->width = lcd_getstringsize(s->line, &w, &h); | ||
1152 | } | ||
1153 | |||
1154 | end = strchr(s->line, '\0'); | ||
1155 | strlcpy(end, string, current_vp->width/2); | ||
1156 | |||
1157 | s->vp = current_vp; | ||
1158 | s->y = y; | ||
1159 | s->len = utf8length(string); | ||
1160 | s->offset = offset; | ||
1161 | s->startx = x * s->width / s->len; | ||
1162 | s->backward = false; | ||
1163 | lcd_scroll_info.lines++; | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | void lcd_scroll_fn(void) | ||
1168 | { | ||
1169 | struct font* pf; | ||
1170 | struct scrollinfo* s; | ||
1171 | int index; | ||
1172 | int xpos, ypos; | ||
1173 | int lastmode; | ||
1174 | unsigned old_fgcolor; | ||
1175 | unsigned old_bgcolor; | ||
1176 | struct viewport* old_vp = current_vp; | ||
1177 | |||
1178 | for ( index = 0; index < lcd_scroll_info.lines; index++ ) { | ||
1179 | s = &lcd_scroll_info.scroll[index]; | ||
1180 | |||
1181 | /* check pause */ | ||
1182 | if (TIME_BEFORE(current_tick, s->start_tick)) | ||
1183 | continue; | ||
1184 | |||
1185 | lcd_set_viewport(s->vp); | ||
1186 | old_fgcolor = current_vp->fg_pattern; | ||
1187 | old_bgcolor = current_vp->bg_pattern; | ||
1188 | |||
1189 | if (s->style&STYLE_COLORED) { | ||
1190 | if (s->style&STYLE_MODE_MASK) { | ||
1191 | current_vp->fg_pattern = old_fgcolor; | ||
1192 | current_vp->bg_pattern = s->style&STYLE_COLOR_MASK; | ||
1193 | } | ||
1194 | else { | ||
1195 | current_vp->fg_pattern = s->style&STYLE_COLOR_MASK; | ||
1196 | current_vp->bg_pattern = old_bgcolor; | ||
1197 | } | ||
1198 | } | ||
1199 | |||
1200 | if (s->backward) | ||
1201 | s->offset -= lcd_scroll_info.step; | ||
1202 | else | ||
1203 | s->offset += lcd_scroll_info.step; | ||
1204 | |||
1205 | pf = font_get(current_vp->font); | ||
1206 | xpos = s->startx; | ||
1207 | ypos = s->y * pf->height; | ||
1208 | |||
1209 | if (s->bidir) { /* scroll bidirectional */ | ||
1210 | if (s->offset <= 0) { | ||
1211 | /* at beginning of line */ | ||
1212 | s->offset = 0; | ||
1213 | s->backward = false; | ||
1214 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
1215 | } | ||
1216 | if (s->offset >= s->width - (current_vp->width - xpos)) { | ||
1217 | /* at end of line */ | ||
1218 | s->offset = s->width - (current_vp->width - xpos); | ||
1219 | s->backward = true; | ||
1220 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
1221 | } | ||
1222 | } | ||
1223 | else { | ||
1224 | /* scroll forward the whole time */ | ||
1225 | if (s->offset >= s->width) | ||
1226 | s->offset %= s->width; | ||
1227 | } | ||
1228 | |||
1229 | lastmode = current_vp->drawmode; | ||
1230 | switch (s->style&STYLE_MODE_MASK) { | ||
1231 | case STYLE_INVERT: | ||
1232 | current_vp->drawmode = DRMODE_SOLID|DRMODE_INVERSEVID; | ||
1233 | break; | ||
1234 | case STYLE_COLORBAR: | ||
1235 | /* Solid colour line selector */ | ||
1236 | current_vp->drawmode = DRMODE_FG; | ||
1237 | current_vp->fg_pattern = current_vp->lss_pattern; | ||
1238 | lcd_fillrect(xpos, ypos, current_vp->width - xpos, pf->height); | ||
1239 | current_vp->fg_pattern = current_vp->lst_pattern; | ||
1240 | break; | ||
1241 | case STYLE_GRADIENT: | ||
1242 | /* Gradient line selector */ | ||
1243 | current_vp->drawmode = DRMODE_FG; | ||
1244 | lcd_gradient_rect_scroll(xpos, current_vp->width, ypos, (signed)pf->height, | ||
1245 | NUMLN_UNPACK(s->style), | ||
1246 | CURLN_UNPACK(s->style)); | ||
1247 | current_vp->fg_pattern = current_vp->lst_pattern; | ||
1248 | break; | ||
1249 | default: | ||
1250 | current_vp->drawmode = DRMODE_SOLID; | ||
1251 | break; | ||
1252 | } | ||
1253 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | ||
1254 | current_vp->drawmode = lastmode; | ||
1255 | current_vp->fg_pattern = old_fgcolor; | ||
1256 | current_vp->bg_pattern = old_bgcolor; | ||
1257 | lcd_update_viewport_rect(xpos, ypos, current_vp->width - xpos, pf->height); | ||
1258 | } | ||
1259 | |||
1260 | lcd_set_viewport(old_vp); | ||
1261 | } | ||