|  | 
| 3 | 3 | #include "../dspcore.h" | 
| 4 | 4 | #include "utf8Rus.h" | 
| 5 | 5 | 
 | 
| 6 |  | -#ifndef DSP_LCD | 
| 7 |  | -char* utf8Rus(const char* str, bool uppercase) { | 
| 8 |  | -  int index = 0; | 
| 9 |  | -  static char strn[BUFLEN]; | 
| 10 |  | -  bool E = false; | 
| 11 |  | -  strlcpy(strn, str, BUFLEN); | 
| 12 |  | -  if (uppercase) { | 
| 13 |  | -    bool next = false; | 
| 14 |  | -    for (char *iter = strn; *iter != '\0'; ++iter) | 
| 15 |  | -    { | 
| 16 |  | -      if (E) { | 
| 17 |  | -        E = false; | 
| 18 |  | -        continue; | 
| 19 |  | -      } | 
| 20 |  | -      uint8_t rus = (uint8_t) * iter; | 
| 21 |  | -      if (rus == 208 && (uint8_t) * (iter + 1) == 129) { // ёКостыли | 
| 22 |  | -        *iter = (char)209; | 
| 23 |  | -        *(iter + 1) = (char)145; | 
| 24 |  | -        E = true; | 
| 25 |  | -        continue; | 
| 26 |  | -      } | 
| 27 |  | -      if (rus == 209 && (uint8_t) * (iter + 1) == 145) { | 
| 28 |  | -        *iter = (char)209; | 
| 29 |  | -        *(iter + 1) = (char)145; | 
| 30 |  | -        E = true; | 
| 31 |  | -        continue; | 
| 32 |  | -      } | 
| 33 |  | -      if (next) { | 
| 34 |  | -        if (rus >= 128 && rus <= 143) *iter = (char)(rus + 32); | 
| 35 |  | -        if (rus >= 176 && rus <= 191) *iter = (char)(rus - 32); | 
| 36 |  | -        next = false; | 
| 37 |  | -      } | 
| 38 |  | -      if (rus == 208) next = true; | 
| 39 |  | -      if (rus == 209) { | 
| 40 |  | -        *iter = (char)208; | 
| 41 |  | -        next = true; | 
| 42 |  | -      } | 
| 43 |  | -      *iter = toupper(*iter); | 
| 44 |  | -    } | 
| 45 |  | -  } | 
| 46 |  | -  if(L10N_LANGUAGE==EN) return strn; | 
| 47 |  | -  while (strn[index]) | 
| 48 |  | -  { | 
| 49 |  | -    if (strn[index] >= 0xBF) | 
| 50 |  | -    { | 
| 51 |  | -      switch (strn[index]) { | 
| 52 |  | -        case 0xD0: { | 
| 53 |  | -            if (strn[index + 1] == 0x81) { | 
| 54 |  | -              strn[index] = 0xA8; | 
| 55 |  | -              break; | 
| 56 |  | -            } | 
| 57 |  | -            if (strn[index + 1] >= 0x90 && strn[index + 1] <= 0xBF) strn[index] = strn[index + 1] + 0x30; | 
| 58 |  | -            break; | 
| 59 |  | -          } | 
| 60 |  | -        case 0xD1: { | 
| 61 |  | -            if (strn[index + 1] == 0x91) { | 
| 62 |  | -              //strn[index] = 0xB7; | 
| 63 |  | -              strn[index] = 0xB8; | 
| 64 |  | -              break; | 
| 65 |  | -            } | 
| 66 |  | -            if (strn[index + 1] >= 0x80 && strn[index + 1] <= 0x8F) strn[index] = strn[index + 1] + 0x70; | 
| 67 |  | -            break; | 
| 68 |  | -          } | 
| 69 |  | -      } | 
| 70 |  | -      int sind = index + 2; | 
| 71 |  | -      while (strn[sind]) { | 
| 72 |  | -        strn[sind - 1] = strn[sind]; | 
| 73 |  | -        sind++; | 
| 74 |  | -      } | 
| 75 |  | -      strn[sind - 1] = 0; | 
|  | 6 | +size_t strlen_utf8(const char* s) { | 
|  | 7 | +  size_t count = 0; | 
|  | 8 | +  while (*s) { | 
|  | 9 | +    count++; | 
|  | 10 | +    if ((*s & 0xF0) == 0xF0) { // 4-byte character | 
|  | 11 | +      s += 4; | 
|  | 12 | +    } else if ((*s & 0xE0) == 0xE0) { // 3-byte character | 
|  | 13 | +      s += 3; | 
|  | 14 | +    } else if ((*s & 0xC0) == 0xC0) { // 2-byte character | 
|  | 15 | +      s += 2; | 
|  | 16 | +    } else { // 1-byte character (ASCII) | 
|  | 17 | +      s += 1; | 
| 76 | 18 |     } | 
| 77 |  | -    index++; | 
| 78 | 19 |   } | 
| 79 |  | -  return strn; | 
|  | 20 | +  return count; | 
| 80 | 21 | } | 
| 81 |  | -#else //#ifndef DSP_LCD | 
| 82 |  | -char* utf8Rus(const char* str, bool uppercase) { | 
| 83 |  | -  int index = 0; | 
| 84 |  | -  static char strn[BUFLEN]; | 
| 85 |  | -  static char newStr[BUFLEN]; | 
| 86 |  | -  bool E = false; | 
| 87 |  | -  strlcpy(strn, str, BUFLEN); | 
| 88 |  | -  newStr[0] = '\0'; | 
| 89 |  | -  bool next = false; | 
| 90 |  | -  for (char *iter = strn; *iter != '\0'; ++iter) | 
| 91 |  | -  { | 
| 92 |  | -    if (E) { | 
| 93 |  | -      E = false; | 
| 94 |  | -      continue; | 
| 95 |  | -    } | 
| 96 |  | -    uint8_t rus = (uint8_t) * iter; | 
| 97 |  | -    if (rus == 208 && (uint8_t) * (iter + 1) == 129) { // ёКостыли | 
| 98 |  | -      *iter = (char)209; | 
| 99 |  | -      *(iter + 1) = (char)145; | 
| 100 |  | -      E = true; | 
| 101 |  | -      continue; | 
| 102 |  | -    } | 
| 103 |  | -    if (rus == 209 && (uint8_t) * (iter + 1) == 145) { | 
| 104 |  | -      *iter = (char)209; | 
| 105 |  | -      *(iter + 1) = (char)145; | 
| 106 |  | -      E = true; | 
| 107 |  | -      continue; | 
| 108 |  | -    } | 
| 109 |  | -    if (next) { | 
| 110 |  | -      if (rus >= 128 && rus <= 143) *iter = (char)(rus + 32); | 
| 111 |  | -      if (rus >= 176 && rus <= 191) *iter = (char)(rus - 32); | 
| 112 |  | -      next = false; | 
| 113 |  | -    } | 
| 114 |  | -    if (rus == 208) next = true; | 
| 115 |  | -    if (rus == 209) { | 
| 116 |  | -      *iter = (char)208; | 
| 117 |  | -      next = true; | 
| 118 |  | -    } | 
| 119 |  | -    *iter = toupper(*iter); | 
| 120 |  | -  } | 
| 121 | 22 | 
 | 
| 122 |  | -  while (strn[index]) | 
| 123 |  | -  { | 
| 124 |  | -    if (strlen(newStr) > BUFLEN - 2) break; | 
| 125 |  | -    if (strn[index] >= 0xBF) | 
| 126 |  | -    { | 
| 127 |  | -      switch (strn[index]) { | 
| 128 |  | -        case 0xD0: { | 
| 129 |  | -            switch (strn[index + 1]) | 
| 130 |  | -            { | 
| 131 |  | -              case 0x90: strcat(newStr, "A"); break; | 
| 132 |  | -              case 0x91: strcat(newStr, "B"); break; | 
| 133 |  | -              case 0x92: strcat(newStr, "V"); break; | 
| 134 |  | -              case 0x93: strcat(newStr, "G"); break; | 
| 135 |  | -              case 0x94: strcat(newStr, "D"); break; | 
| 136 |  | -              case 0x95: strcat(newStr, "E"); break; | 
| 137 |  | -              case 0x96: strcat(newStr, "ZH"); break; | 
| 138 |  | -              case 0x97: strcat(newStr, "Z"); break; | 
| 139 |  | -              case 0x98: strcat(newStr, "I"); break; | 
| 140 |  | -              case 0x99: strcat(newStr, "Y"); break; | 
| 141 |  | -              case 0x9A: strcat(newStr, "K"); break; | 
| 142 |  | -              case 0x9B: strcat(newStr, "L"); break; | 
| 143 |  | -              case 0x9C: strcat(newStr, "M"); break; | 
| 144 |  | -              case 0x9D: strcat(newStr, "N"); break; | 
| 145 |  | -              case 0x9E: strcat(newStr, "O"); break; | 
| 146 |  | -              case 0x9F: strcat(newStr, "P"); break; | 
| 147 |  | -              case 0xA0: strcat(newStr, "R"); break; | 
| 148 |  | -              case 0xA1: strcat(newStr, "S"); break; | 
| 149 |  | -              case 0xA2: strcat(newStr, "T"); break; | 
| 150 |  | -              case 0xA3: strcat(newStr, "U"); break; | 
| 151 |  | -              case 0xA4: strcat(newStr, "F"); break; | 
| 152 |  | -              case 0xA5: strcat(newStr, "H"); break; | 
| 153 |  | -              case 0xA6: strcat(newStr, "TS"); break; | 
| 154 |  | -              case 0xA7: strcat(newStr, "CH"); break; | 
| 155 |  | -              case 0xA8: strcat(newStr, "SH"); break; | 
| 156 |  | -              case 0xA9: strcat(newStr, "SHCH"); break; | 
| 157 |  | -              case 0xAA: strcat(newStr, "'"); break; | 
| 158 |  | -              case 0xAB: strcat(newStr, "YU"); break; | 
| 159 |  | -              case 0xAC: strcat(newStr, "'"); break; | 
| 160 |  | -              case 0xAD: strcat(newStr, "E"); break; | 
| 161 |  | -              case 0xAE: strcat(newStr, "YU"); break; | 
| 162 |  | -              case 0xAF: strcat(newStr, "YA"); break; | 
| 163 |  | -            } | 
| 164 |  | -            break; | 
| 165 |  | -          } | 
| 166 |  | -        case 0xD1: { | 
| 167 |  | -            if (strn[index + 1] == 0x91) { | 
| 168 |  | -              strcat(newStr, "YO"); break; | 
| 169 |  | -              break; | 
| 170 |  | -            } | 
| 171 |  | -            break; | 
| 172 |  | -          } | 
|  | 23 | +char* utf8Rus(const char* str, bool uppercase) { | 
|  | 24 | +  static char out[BUFLEN]; | 
|  | 25 | +  int outPos = 0; | 
|  | 26 | +#ifdef DSP_LCD | 
|  | 27 | +  static const char* mapD0[] = { | 
|  | 28 | +    "A","B","V","G","D","E","ZH","Z","I","Y", | 
|  | 29 | +    "K","L","M","N","O","P","R","S","T","U", | 
|  | 30 | +    "F","H","TS","CH","SH","SHCH","'","YU","'","E","YU","YA" | 
|  | 31 | +  }; | 
|  | 32 | +#endif | 
|  | 33 | +  for (int i = 0; str[i] && outPos < BUFLEN - 1; i++) { | 
|  | 34 | +    uint8_t c = (uint8_t)str[i]; | 
|  | 35 | +    if (c == 0xD0 && str[i+1]) { | 
|  | 36 | +      uint8_t n = (uint8_t)str[++i]; | 
|  | 37 | +      if (n == 0x81) {                  // Ё | 
|  | 38 | +      #ifdef DSP_LCD | 
|  | 39 | +        const char* t = "YO"; | 
|  | 40 | +        for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t; | 
|  | 41 | +      #else | 
|  | 42 | +        out[outPos++] = uppercase ? 0xA8 : 0xB8; | 
|  | 43 | +      #endif | 
|  | 44 | +      } else if (n >= 144 && n <= 191) { | 
|  | 45 | +      #ifdef DSP_LCD | 
|  | 46 | +        if(n>=176) n-=32; | 
|  | 47 | +        const char* t = mapD0[n - 0x90]; | 
|  | 48 | +        for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t; | 
|  | 49 | +      #else | 
|  | 50 | +        uint8_t ch = n + 48; | 
|  | 51 | +        if(n>=176 && uppercase) ch-=32; | 
|  | 52 | +        out[outPos++] = ch; | 
|  | 53 | +      #endif | 
| 173 | 54 |       } | 
| 174 |  | -      int sind = index + 2; | 
| 175 |  | -      while (strn[sind]) { | 
| 176 |  | -        strn[sind - 1] = strn[sind]; | 
| 177 |  | -        sind++; | 
|  | 55 | +    } else if (c == 0xD1 && str[i+1]) { | 
|  | 56 | +      uint8_t n = (uint8_t)str[++i]; | 
|  | 57 | +      if (n == 0x91) {                  // ё | 
|  | 58 | +      #ifdef DSP_LCD | 
|  | 59 | +        const char* t = "YO"; | 
|  | 60 | +        for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t; | 
|  | 61 | +      #else | 
|  | 62 | +        out[outPos++] = uppercase ? 0xA8 : 0xB8; | 
|  | 63 | +      #endif | 
|  | 64 | +      } else if (n >= 128 && n <= 143) { | 
|  | 65 | +      #ifdef DSP_LCD | 
|  | 66 | +        n+=16; | 
|  | 67 | +        const char* t = mapD0[n - 128]; | 
|  | 68 | +        for (; *t && outPos < BUFLEN-1; t++) out[outPos++] = *t; | 
|  | 69 | +      #else | 
|  | 70 | +        uint8_t ch = n + 112; | 
|  | 71 | +        if(uppercase) ch-=32; | 
|  | 72 | +        out[outPos++] = ch; | 
|  | 73 | +      #endif | 
| 178 | 74 |       } | 
| 179 |  | -      strn[sind - 1] = 0; | 
| 180 |  | -    } else { | 
| 181 |  | -    	if(strn[index]==7) strn[index]=165; | 
| 182 |  | -    	if(strn[index]==9) strn[index]=223; | 
| 183 |  | -      char Temp[2] = {(char) strn[index] , 0 } ; | 
| 184 |  | -      strcat(newStr, Temp); | 
|  | 75 | +    } else {                              // ASCII | 
|  | 76 | +    #ifdef DSP_LCD | 
|  | 77 | +      char ch = (char)toupper(c); | 
|  | 78 | +      if (ch == 7) ch = (char)165; | 
|  | 79 | +      if (ch == 9) ch = (char)223; | 
|  | 80 | +      out[outPos++] = ch; | 
|  | 81 | +    #else | 
|  | 82 | +      out[outPos++] = uppercase ? toupper(c) : c; | 
|  | 83 | +    #endif | 
| 185 | 84 |     } | 
| 186 |  | -    index++; | 
| 187 | 85 |   } | 
| 188 |  | -  return newStr; | 
|  | 86 | +  out[outPos] = 0; | 
|  | 87 | +  return out; | 
| 189 | 88 | } | 
| 190 |  | -#endif //#ifndef DSP_LCD | 
| 191 |  | - | 
| 192 | 89 | 
 | 
0 commit comments