1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Text; 6 using System.Drawing; 7 using System.Text.RegularExpressions; 8 using System.Collections; 9 10 /// <summary> 11 ///BarCode 的摘要说明 12 /// </summary> 13 14 public class BarCodeHelper 15 { 16 public static string get39(string s, int width, int height) 17 { 18 Hashtable ht = new Hashtable(); 19 20 #region 39码 12位 21 ht.Add('A', "110101001011"); 22 ht.Add('B', "101101001011"); 23 ht.Add('C', "110110100101"); 24 ht.Add('D', "101011001011"); 25 ht.Add('E', "110101100101"); 26 ht.Add('F', "101101100101"); 27 ht.Add('G', "101010011011"); 28 ht.Add('H', "110101001101"); 29 ht.Add('I', "101101001101"); 30 ht.Add('J', "101011001101"); 31 ht.Add('K', "110101010011"); 32 ht.Add('L', "101101010011"); 33 ht.Add('M', "110110101001"); 34 ht.Add('N', "101011010011"); 35 ht.Add('O', "110101101001"); 36 ht.Add('P', "101101101001"); 37 ht.Add('Q', "101010110011"); 38 ht.Add('R', "110101011001"); 39 ht.Add('S', "101101011001"); 40 ht.Add('T', "101011011001"); 41 ht.Add('U', "110010101011"); 42 ht.Add('V', "100110101011"); 43 ht.Add('W', "110011010101"); 44 ht.Add('X', "100101101011"); 45 ht.Add('Y', "110010110101"); 46 ht.Add('Z', "100110110101"); 47 ht.Add('0', "101001101101"); 48 ht.Add('1', "110100101011"); 49 ht.Add('2', "101100101011"); 50 ht.Add('3', "110110010101"); 51 ht.Add('4', "101001101011"); 52 ht.Add('5', "110100110101"); 53 ht.Add('6', "101100110101"); 54 ht.Add('7', "101001011011"); 55 ht.Add('8', "110100101101"); 56 ht.Add('9', "101100101101"); 57 ht.Add('+', "100101001001"); 58 ht.Add('-', "100101011011"); 59 ht.Add('*', "100101101101"); 60 ht.Add('/', "100100101001"); 61 ht.Add('%', "101001001001"); 62 ht.Add('$', "100100100101"); 63 ht.Add('.', "110010101101"); 64 ht.Add(' ', "100110101101"); 65 #endregion 66 #region 39码 9位 67 #endregion 68 69 s = s.ToUpper(); 70 71 string result_bin = "";//二进制串 72 73 try 74 { 75 foreach (char ch in s) 76 { 77 result_bin += ht[ch].ToString(); 78 result_bin += "0";//间隔,与一个单位的线条宽度相等 79 } 80 } 81 catch { return "存在不允许的字符!"; } 82 83 string result_html = "";//HTML代码 84 string color = "";//颜色 85 foreach (char c in result_bin) 86 { 87 color = c == '0' ? "#FFFFFF" : "#000000"; 88 result_html += "<div style=\"width:" + width + "px;height:" + height + "px;float:left;background:" + color + ";\"></div>"; 89 } 90 result_html += "<div style=\"clear:both\"></div>"; 91 92 int len = ht['*'].ToString().Length; 93 foreach (char c in s) 94 { 95 result_html += "<div style=\"width:" + (width * (len + 1)) + "px;float:left;color:#000000;text-align:center;\">" + c + "</div>"; 96 } 97 result_html += "<div style=\"clear:both\"></div>"; 98 99 return "<div style=\"background:#FFFFFF;padding:5px;font-size:" + (width * 10) + "px;font-family:'楷体';\">" + result_html + "</div>"; 100 } 101 public static string getEAN13(string s, int width, int height) 102 { 103 int checkcode_input = -1;//输入的校验码 104 if (!Regex.IsMatch(s, @"^\d{12}$")) 105 { 106 if (!Regex.IsMatch(s, @"^\d{13}$")) 107 { 108 return "存在不允许的字符!"; 109 } 110 else 111 { 112 checkcode_input = int.Parse(s[12].ToString()); 113 s = s.Substring(0, 12); 114 } 115 } 116 117 int sum_even = 0;//偶数位之和 118 int sum_odd = 0;//奇数位之和 119 120 for (int i = 0; i < 12; i++) 121 { 122 if (i % 2 == 0) 123 { 124 sum_odd += int.Parse(s[i].ToString()); 125 } 126 else 127 { 128 sum_even += int.Parse(s[i].ToString()); 129 } 130 } 131 132 int checkcode = (10 - (sum_even * 3 + sum_odd) % 10) % 10;//校验码 133 134 if (checkcode_input > 0 && checkcode_input != checkcode) 135 { 136 return "输入的校验码错误!"; 137 } 138 139 s += checkcode;//变成13位 140 141 // 000000000101左侧42个01010右侧35个校验7个101000000000 142 // 6 101左侧6位 01010右侧5位 校验1位101000000000 143 144 string result_bin = "";//二进制串 145 result_bin += "000000000101"; 146 147 string type = ean13type(s[0]); 148 for (int i = 1; i < 7; i++) 149 { 150 result_bin += ean13(s[i], type[i - 1]); 151 } 152 result_bin += "01010"; 153 for (int i = 7; i < 13; i++) 154 { 155 result_bin += ean13(s[i], 'C'); 156 } 157 result_bin += "101000000000"; 158 159 string result_html = "";//HTML代码 160 string color = "";//颜色 161 int height_bottom = width * 5; 162 foreach (char c in result_bin) 163 { 164 color = c == '0' ? "#FFFFFF" : "#000000"; 165 result_html += "<div style=\"width:" + width + "px;height:" + height + "px;float:left;background:" + color + ";\"></div>"; 166 } 167 result_html += "<div style=\"clear:both\"></div>"; 168 169 result_html += "<div style=\"float:left;color:#000000;width:" + (width * 9) + "px;text-align:center;\">" + s[0] + "</div>"; 170 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#000000;\"></div>"; 171 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#FFFFFF;\"></div>"; 172 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#000000;\"></div>"; 173 for (int i = 1; i < 7; i++) 174 { 175 result_html += "<div style=\"float:left;width:" + (width * 7) + "px;color:#000000;text-align:center;\">" + s[i] + "</div>"; 176 } 177 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#FFFFFF;\"></div>"; 178 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#000000;\"></div>"; 179 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#FFFFFF;\"></div>"; 180 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#000000;\"></div>"; 181 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#FFFFFF;\"></div>"; 182 for (int i = 7; i < 13; i++) 183 { 184 result_html += "<div style=\"float:left;width:" + (width * 7) + "px;color:#000000;text-align:center;\">" + s[i] + "</div>"; 185 } 186 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#000000;\"></div>"; 187 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#FFFFFF;\"></div>"; 188 result_html += "<div style=\"float:left;width:" + width + "px;height:" + height_bottom + "px;background:#000000;\"></div>"; 189 result_html += "<div style=\"float:left;color:#000000;width:" + (width * 9) + "px;\"></div>"; 190 result_html += "<div style=\"clear:both\"></div>"; 191 192 return "<div style=\"background:#FFFFFF;padding:0px;font-size:" + (width * 10) + "px;font-family:'楷体';\">" + result_html + "</div>"; 193 } 194 private static string ean13(char c, char type) 195 { 196 switch (type) 197 { 198 case 'A': 199 { 200 switch (c) 201 { 202 case '0': return "0001101"; 203 case '1': return "0011001"; 204 case '2': return "0010011"; 205 case '3': return "0111101";//011101 206 case '4': return "0100011"; 207 case '5': return "0110001"; 208 case '6': return "0101111"; 209 case '7': return "0111011"; 210 case '8': return "0110111"; 211 case '9': return "0001011"; 212 default: return "Error!"; 213 } 214 } 215 case 'B': 216 { 217 switch (c) 218 { 219 case '0': return "0100111"; 220 case '1': return "0110011"; 221 case '2': return "0011011"; 222 case '3': return "0100001"; 223 case '4': return "0011101"; 224 case '5': return "0111001"; 225 case '6': return "0000101";//000101 226 case '7': return "0010001"; 227 case '8': return "0001001"; 228 case '9': return "0010111"; 229 default: return "Error!"; 230 } 231 } 232 case 'C': 233 { 234 switch (c) 235 { 236 case '0': return "1110010"; 237 case '1': return "1100110"; 238 case '2': return "1101100"; 239 case '3': return "1000010"; 240 case '4': return "1011100"; 241 case '5': return "1001110"; 242 case '6': return "1010000"; 243 case '7': return "1000100"; 244 case '8': return "1001000"; 245 case '9': return "1110100"; 246 default: return "Error!"; 247 } 248 } 249 default: return "Error!"; 250 } 251 } 252 private static string ean13type(char c) 253 { 254 switch (c) 255 { 256 case '0': return "AAAAAA"; 257 case '1': return "AABABB"; 258 case '2': return "AABBAB"; 259 case '3': return "AABBBA"; 260 case '4': return "ABAABB"; 261 case '5': return "ABBAAB"; 262 case '6': return "ABBBAA";//中国 263 case '7': return "ABABAB"; 264 case '8': return "ABABBA"; 265 case '9': return "ABBABA"; 266 default: return "Error!"; 267 } 268 } 269 270 #region Code patterns 271 272 // in principle these rows should each have 6 elements 273 // however, the last one -- STOP -- has 7. The cost of the 274 // extra integers is trivial, and this lets the code flow 275 // much more elegantly 276 private static readonly int[,] cPatterns = 277 { 278 {2,1,2,2,2,2,0,0}, // 0 279 {2,2,2,1,2,2,0,0}, // 1 280 {2,2,2,2,2,1,0,0}, // 2 281 {1,2,1,2,2,3,0,0}, // 3 282 {1,2,1,3,2,2,0,0}, // 4 283 {1,3,1,2,2,2,0,0}, // 5 284 {1,2,2,2,1,3,0,0}, // 6 285 {1,2,2,3,1,2,0,0}, // 7 286 {1,3,2,2,1,2,0,0}, // 8 287 {2,2,1,2,1,3,0,0}, // 9 288 {2,2,1,3,1,2,0,0}, // 10 289 {2,3,1,2,1,2,0,0}, // 11 290 {1,1,2,2,3,2,0,0}, // 12 291 {1,2,2,1,3,2,0,0}, // 13 292 {1,2,2,2,3,1,0,0}, // 14 293 {1,1,3,2,2,2,0,0}, // 15 294 {1,2,3,1,2,2,0,0}, // 16 295 {1,2,3,2,2,1,0,0}, // 17 296 {2,2,3,2,1,1,0,0}, // 18 297 {2,2,1,1,3,2,0,0}, // 19 298 {2,2,1,2,3,1,0,0}, // 20 299 {2,1,3,2,1,2,0,0}, // 21 300 {2,2,3,1,1,2,0,0}, // 22 301 {3,1,2,1,3,1,0,0}, // 23 302 {3,1,1,2,2,2,0,0}, // 24 303 {3,2,1,1,2,2,0,0}, // 25 304 {3,2,1,2,2,1,0,0}, // 26 305 {3,1,2,2,1,2,0,0}, // 27 306 {3,2,2,1,1,2,0,0}, // 28 307 {3,2,2,2,1,1,0,0}, // 29 308 {2,1,2,1,2,3,0,0}, // 30 309 {2,1,2,3,2,1,0,0}, // 31 310 {2,3,2,1,2,1,0,0}, // 32 311 {1,1,1,3,2,3,0,0}, // 33 312 {1,3,1,1,2,3,0,0}, // 34 313 {1,3,1,3,2,1,0,0}, // 35 314 {1,1,2,3,1,3,0,0}, // 36 315 {1,3,2,1,1,3,0,0}, // 37 316 {1,3,2,3,1,1,0,0}, // 38 317 {2,1,1,3,1,3,0,0}, // 39 318 {2,3,1,1,1,3,0,0}, // 40 319 {2,3,1,3,1,1,0,0}, // 41 320 {1,1,2,1,3,3,0,0}, // 42 321 {1,1,2,3,3,1,0,0}, // 43 322 {1,3,2,1,3,1,0,0}, // 44 323 {1,1,3,1,2,3,0,0}, // 45 324 {1,1,3,3,2,1,0,0}, // 46 325 {1,3,3,1,2,1,0,0}, // 47 326 {3,1,3,1,2,1,0,0}, // 48 327 {2,1,1,3,3,1,0,0}, // 49 328 {2,3,1,1,3,1,0,0}, // 50 329 {2,1,3,1,1,3,0,0}, // 51 330 {2,1,3,3,1,1,0,0}, // 52 331 {2,1,3,1,3,1,0,0}, // 53 332 {3,1,1,1,2,3,0,0}, // 54 333 {3,1,1,3,2,1,0,0}, // 55 334 {3,3,1,1,2,1,0,0}, // 56 335 {3,1,2,1,1,3,0,0}, // 57 336 {3,1,2,3,1,1,0,0}, // 58 337 {3,3,2,1,1,1,0,0}, // 59 338 {3,1,4,1,1,1,0,0}, // 60 339 {2,2,1,4,1,1,0,0}, // 61 340 {4,3,1,1,1,1,0,0}, // 62 341 {1,1,1,2,2,4,0,0}, // 63 342 {1,1,1,4,2,2,0,0}, // 64 343 {1,2,1,1,2,4,0,0}, // 65 344 {1,2,1,4,2,1,0,0}, // 66 345 {1,4,1,1,2,2,0,0}, // 67 346 {1,4,1,2,2,1,0,0}, // 68 347 {1,1,2,2,1,4,0,0}, // 69 348 {1,1,2,4,1,2,0,0}, // 70 349 {1,2,2,1,1,4,0,0}, // 71 350 {1,2,2,4,1,1,0,0}, // 72 351 {1,4,2,1,1,2,0,0}, // 73 352 {1,4,2,2,1,1,0,0}, // 74 353 {2,4,1,2,1,1,0,0}, // 75 354 {2,2,1,1,1,4,0,0}, // 76 355 {4,1,3,1,1,1,0,0}, // 77 356 {2,4,1,1,1,2,0,0}, // 78 357 {1,3,4,1,1,1,0,0}, // 79 358 {1,1,1,2,4,2,0,0}, // 80 359 {1,2,1,1,4,2,0,0}, // 81 360 {1,2,1,2,4,1,0,0}, // 82 361 {1,1,4,2,1,2,0,0}, // 83 362 {1,2,4,1,1,2,0,0}, // 84 363 {1,2,4,2,1,1,0,0}, // 85 364 {4,1,1,2,1,2,0,0}, // 86 365 {4,2,1,1,1,2,0,0}, // 87 366 {4,2,1,2,1,1,0,0}, // 88 367 {2,1,2,1,4,1,0,0}, // 89 368 {2,1,4,1,2,1,0,0}, // 90 369 {4,1,2,1,2,1,0,0}, // 91 370 {1,1,1,1,4,3,0,0}, // 92 371 {1,1,1,3,4,1,0,0}, // 93 372 {1,3,1,1,4,1,0,0}, // 94 373 {1,1,4,1,1,3,0,0}, // 95 374 {1,1,4,3,1,1,0,0}, // 96 375 {4,1,1,1,1,3,0,0}, // 97 376 {4,1,1,3,1,1,0,0}, // 98 377 {1,1,3,1,4,1,0,0}, // 99 378 {1,1,4,1,3,1,0,0}, // 100 379 {3,1,1,1,4,1,0,0}, // 101 380 {4,1,1,1,3,1,0,0}, // 102 381 {2,1,1,4,1,2,0,0}, // 103 382 {2,1,1,2,1,4,0,0}, // 104 383 {2,1,1,2,3,2,0,0}, // 105 384 {2,3,3,1,1,1,2,0} // 106 385 }; 386 387 #endregion Code patterns 388 389 #region 128条形码 390 391 private const int cQuietWidth = 10; 392 393 /// <summary> 394 /// Make an image of a Code128 barcode for a given string 395 /// </summary> 396 /// <param name="InputData">Message to be encoded</param> 397 /// <param name="BarWeight">Base thickness for bar width (1 or 2 works well)</param> 398 /// <param name="AddQuietZone">Add required horiz margins (use if output is tight)</param> 399 /// <returns>An Image of the Code128 barcode representing the message</returns> 400 public static Image MakeBarcodeImage(string InputData, int BarWeight, bool AddQuietZone) 401 { 402 // get the Code128 codes to represent the message 403 Code128Content content = new Code128Content(InputData); 404 int[] codes = content.Codes; 405 406 int width, height; 407 width = ((codes.Length - 3) * 11 + 35) * BarWeight; 408 height = Convert.ToInt32(System.Math.Ceiling(Convert.ToSingle(width) * .15F)); 409 410 if (AddQuietZone) 411 { 412 width += 20; // on both sides 413 } 414 //draw the codetext bottom 415 height += 30; 416 // get surface to draw on 417 Image myimg = new System.Drawing.Bitmap(width, height); 418 using (Graphics gr = Graphics.FromImage(myimg)) 419 { 420 421 // set to white so we don't have to fill the spaces with white 422 gr.FillRectangle(System.Drawing.Brushes.White, 0, 0, width, height); 423 424 // skip quiet zone 425 int cursor = AddQuietZone ? 10 : 0; 426 427 for (int codeidx = 0; codeidx < codes.Length; codeidx++) 428 { 429 int code = codes[codeidx]; 430 431 // take the bars two at a time: a black and a white 432 for (int bar = 0; bar < 8; bar += 2) 433 { 434 int barwidth = cPatterns[code, bar] * BarWeight; 435 int spcwidth = cPatterns[code, bar + 1] * BarWeight; 436 437 // if width is zero, don't try to draw it 438 if (barwidth > 0) 439 { 440 gr.FillRectangle(System.Drawing.Brushes.Black, cursor, 5, barwidth, height - 20); 441 } 442 443 // note that we never need to draw the space, since we 444 // initialized the graphics to all white 445 446 // advance cursor beyond this pair 447 cursor += (barwidth + spcwidth); 448 } 449 } 450 gr.DrawString(InputData, new Font("Arial", 9), Brushes.Black, new PointF(10, height - 15)); 451 } 452 return myimg; 453 454 } 455 456 #endregion 457 } 458 459 #region Code128Content 460 461 public enum CodeSet 462 { 463 CodeA 464 , CodeB 465 // ,CodeC // not supported 466 } 467 468 /// <summary> 469 /// Represent the set of code values to be output into barcode form 470 /// </summary> 471 public class Code128Content 472 { 473 private int[] mCodeList; 474 475 /// <summary> 476 /// Create content based on a string of ASCII data 477 /// </summary> 478 /// <param name="AsciiData">the string that should be represented</param> 479 public Code128Content(string AsciiData) 480 { 481 mCodeList = StringToCode128(AsciiData); 482 } 483 484 /// <summary> 485 /// Provides the Code128 code values representing the object's string 486 /// </summary> 487 public int[] Codes 488 { 489 get 490 { 491 return mCodeList; 492 } 493 } 494 495 /// <summary> 496 /// Transform the string into integers representing the Code128 codes 497 /// necessary to represent it 498 /// </summary> 499 /// <param name="AsciiData">String to be encoded</param> 500 /// <returns>Code128 representation</returns> 501 private int[] StringToCode128(string AsciiData) 502 { 503 // turn the string into ascii byte data 504 byte[] asciiBytes = Encoding.ASCII.GetBytes(AsciiData); 505 506 // decide which codeset to start with 507 Code128Code.CodeSetAllowed csa1 = asciiBytes.Length > 0 ? Code128Code.CodesetAllowedForChar(asciiBytes[0]) : Code128Code.CodeSetAllowed.CodeAorB; 508 Code128Code.CodeSetAllowed csa2 = asciiBytes.Length > 0 ? Code128Code.CodesetAllowedForChar(asciiBytes[1]) : Code128Code.CodeSetAllowed.CodeAorB; 509 CodeSet currcs = GetBestStartSet(csa1, csa2); 510 511 // set up the beginning of the barcode 512 System.Collections.ArrayList codes = new System.Collections.ArrayList(asciiBytes.Length + 3); // assume no codeset changes, account for start, checksum, and stop 513 codes.Add(Code128Code.StartCodeForCodeSet(currcs)); 514 515 // add the codes for each character in the string 516 for (int i = 0; i < asciiBytes.Length; i++) 517 { 518 int thischar = asciiBytes[i]; 519 int nextchar = asciiBytes.Length > (i + 1) ? asciiBytes[i + 1] : -1; 520 521 codes.AddRange(Code128Code.CodesForChar(thischar, nextchar, ref currcs)); 522 } 523 524 // calculate the check digit 525 int checksum = (int)(codes[0]); 526 for (int i = 1; i < codes.Count; i++) 527 { 528 checksum += i * (int)(codes[i]); 529 } 530 codes.Add(checksum % 103); 531 532 codes.Add(Code128Code.StopCode()); 533 534 int[] result = codes.ToArray(typeof(int)) as int[]; 535 return result; 536 } 537 538 /// <summary> 539 /// Determines the best starting code set based on the the first two 540 /// characters of the string to be encoded 541 /// </summary> 542 /// <param name="csa1">First character of input string</param> 543 /// <param name="csa2">Second character of input string</param> 544 /// <returns>The codeset determined to be best to start with</returns> 545 private CodeSet GetBestStartSet(Code128Code.CodeSetAllowed csa1, Code128Code.CodeSetAllowed csa2) 546 { 547 int vote = 0; 548 549 vote += (csa1 == Code128Code.CodeSetAllowed.CodeA) ? 1 : 0; 550 vote += (csa1 == Code128Code.CodeSetAllowed.CodeB) ? -1 : 0; 551 vote += (csa2 == Code128Code.CodeSetAllowed.CodeA) ? 1 : 0; 552 vote += (csa2 == Code128Code.CodeSetAllowed.CodeB) ? -1 : 0; 553 554 return (vote > 0) ? CodeSet.CodeA : CodeSet.CodeB; // ties go to codeB due to my own prejudices 555 } 556 } 557 558 /// <summary> 559 /// Static tools for determining codes for individual characters in the content 560 /// </summary> 561 public static class Code128Code 562 { 563 #region Constants 564 565 private const int cSHIFT = 98; 566 private const int cCODEA = 101; 567 private const int cCODEB = 100; 568 569 private const int cSTARTA = 103; 570 private const int cSTARTB = 104; 571 private const int cSTOP = 106; 572 573 #endregion 574 575 /// <summary> 576 /// Get the Code128 code value(s) to represent an ASCII character, with 577 /// optional look-ahead for length optimization 578 /// </summary> 579 /// <param name="CharAscii">The ASCII value of the character to translate</param> 580 /// <param name="LookAheadAscii">The next character in sequence (or -1 if none)</param> 581 /// <param name="CurrCodeSet">The current codeset, that the returned codes need to follow; 582 /// if the returned codes change that, then this value will be changed to reflect it</param> 583 /// <returns>An array of integers representing the codes that need to be output to produce the 584 /// given character</returns> 585 public static int[] CodesForChar(int CharAscii, int LookAheadAscii, ref CodeSet CurrCodeSet) 586 { 587 int[] result; 588 int shifter = -1; 589 590 if (!CharCompatibleWithCodeset(CharAscii, CurrCodeSet)) 591 { 592 // if we have a lookahead character AND if the next character is ALSO not compatible 593 if ((LookAheadAscii != -1) && !CharCompatibleWithCodeset(LookAheadAscii, CurrCodeSet)) 594 { 595 // we need to switch code sets 596 switch (CurrCodeSet) 597 { 598 case CodeSet.CodeA: 599 shifter = cCODEB; 600 CurrCodeSet = CodeSet.CodeB; 601 break; 602 case CodeSet.CodeB: 603 shifter = cCODEA; 604 CurrCodeSet = CodeSet.CodeA; 605 break; 606 } 607 } 608 else 609 { 610 // no need to switch code sets, a temporary SHIFT will suffice 611 shifter = cSHIFT; 612 } 613 } 614 615 if (shifter != -1) 616 { 617 result = new int[2]; 618 result[0] = shifter; 619 result[1] = CodeValueForChar(CharAscii); 620 } 621 else 622 { 623 result = new int[1]; 624 result[0] = CodeValueForChar(CharAscii); 625 } 626 627 return result; 628 } 629 630 /// <summary> 631 /// Tells us which codesets a given character value is allowed in 632 /// </summary> 633 /// <param name="CharAscii">ASCII value of character to look at</param> 634 /// <returns>Which codeset(s) can be used to represent this character</returns> 635 public static CodeSetAllowed CodesetAllowedForChar(int CharAscii) 636 { 637 if (CharAscii >= 32 && CharAscii <= 95) 638 { 639 return CodeSetAllowed.CodeAorB; 640 } 641 else 642 { 643 return (CharAscii < 32) ? CodeSetAllowed.CodeA : CodeSetAllowed.CodeB; 644 } 645 } 646 647 /// <summary> 648 /// Determine if a character can be represented in a given codeset 649 /// </summary> 650 /// <param name="CharAscii">character to check for</param> 651 /// <param name="currcs">codeset context to test</param> 652 /// <returns>true if the codeset contains a representation for the ASCII character</returns> 653 public static bool CharCompatibleWithCodeset(int CharAscii, CodeSet currcs) 654 { 655 CodeSetAllowed csa = CodesetAllowedForChar(CharAscii); 656 return csa == CodeSetAllowed.CodeAorB 657 || (csa == CodeSetAllowed.CodeA && currcs == CodeSet.CodeA) 658 || (csa == CodeSetAllowed.CodeB && currcs == CodeSet.CodeB); 659 } 660 661 /// <summary> 662 /// Gets the integer code128 code value for a character (assuming the appropriate code set) 663 /// </summary> 664 /// <param name="CharAscii">character to convert</param> 665 /// <returns>code128 symbol value for the character</returns> 666 public static int CodeValueForChar(int CharAscii) 667 { 668 return (CharAscii >= 32) ? CharAscii - 32 : CharAscii + 64; 669 } 670 671 /// <summary> 672 /// Return the appropriate START code depending on the codeset we want to be in 673 /// </summary> 674 /// <param name="cs">The codeset you want to start in</param> 675 /// <returns>The code128 code to start a barcode in that codeset</returns> 676 public static int StartCodeForCodeSet(CodeSet cs) 677 { 678 return cs == CodeSet.CodeA ? cSTARTA : cSTARTB; 679 } 680 681 /// <summary> 682 /// Return the Code128 stop code 683 /// </summary> 684 /// <returns>the stop code</returns> 685 public static int StopCode() 686 { 687 return cSTOP; 688 } 689 690 /// <summary> 691 /// Indicates which code sets can represent a character -- CodeA, CodeB, or either 692 /// </summary> 693 public enum CodeSetAllowed 694 { 695 CodeA, 696 CodeB, 697 CodeAorB 698 } 699 700 } 701 #endregion