void EscInterpreter::printGR24(int dx) { int width = GetNextByte(); // Количество "кусочков" данных о изображении width += 256 * (int)GetNextByte(); // Читать и выводить данные for (; width > 0; width--) { for (unsigned char n = 0; n < 3; n++) { unsigned char fbyte = GetNextByte(); unsigned char mask = 0x80; for (int i = 0; i < 8; i++) { if (fbyte & mask) { DrawStrike(float(m_x), float((m_y + (n * 4 * 8/*игл*/) + i * 4))); /* 4 соответствует 1/180 inch - расстояние мажду иглами у 24-pin dot matrix printers */ } mask >>= 1; } } m_x += dx; } }
void Stream::StreamInUtf32() const { static int indexes[2][4] = { {3, 2, 1, 0}, {0, 1, 2, 3} }; unsigned long ch = 0; unsigned char bytes[4]; int* pIndexes = (m_charSet == utf32be) ? indexes[1] : indexes[0]; bytes[0] = GetNextByte(); bytes[1] = GetNextByte(); bytes[2] = GetNextByte(); bytes[3] = GetNextByte(); if (!m_input.good()) { return; } for (int i = 0; i < 4; ++i) { ch <<= 8; ch |= bytes[pIndexes[i]]; } QueueUnicodeCodepoint(m_readahead, ch); }
void Stream::StreamInUtf8() const { unsigned char b = GetNextByte(); if (m_input.good()) { m_readahead.push_back(b); } }
int EpsilonDataset::GetNextBlockData() { int nStartBlockBufOffset = 0; pabyBlockData = NULL; nBlockDataSize = 0; while (nFileBufOffset < MAX_SIZE_BEFORE_BLOCK_MARKER) { int chNextByte = GetNextByte(); if (chNextByte < 0) return FALSE; if (chNextByte != EPS_MARKER) { nStartBlockFileOff = nFileOff - 1; nStartBlockBufOffset = nFileBufOffset - 1; nBlockDataSize = 1; break; } } if (nFileBufOffset == MAX_SIZE_BEFORE_BLOCK_MARKER) return FALSE; while (nFileBufOffset < BLOCK_DATA_MAX_SIZE) { int chNextByte = GetNextByte(); if (chNextByte < 0) break; if (chNextByte == EPS_MARKER) { pabyBlockData = pabyFileBuf + nStartBlockBufOffset; return TRUE; } nBlockDataSize ++; } pabyBlockData = pabyFileBuf + nStartBlockBufOffset; return TRUE; }
void EscInterpreter::printGR9(int dx) { int width = GetNextByte(); // Количество "кусочков" данных о изображении width += 256 * (int)GetNextByte(); // Читать и выводить данные for (; width > 0; width--) { unsigned char fbyte = GetNextByte(); unsigned char mask = 0x80; for (int i = 0; i < 8; i++) { if (fbyte & mask) { DrawStrike(float(m_x), float(m_y + i * 12)); /* 12 соответствует 1/60 inch... На самом деле расстояние мажду иглами у 9-pin dot matrix printers = 1/72 inch, но при эмуляции на 24-pin принимается 1/60 */ } mask >>= 1; } m_x += dx; } }
static void GetDeviceName(const ASCII ** strpointer, struct connection_in * in) { BYTE sn[SERIAL_NUMBER_SIZE] ; BYTE dn[SERIAL_NUMBER_SIZE] ; if ( isxdigit((*strpointer)[0]) && isxdigit((*strpointer)[1]) ) { // family code specified sn[0] = string2num(*strpointer); *strpointer += 2; GetDefaultDeviceName( dn, sn, in ) ; // Choice of default or specified ID GetNextByte(strpointer,dn[1],&sn[1]); GetNextByte(strpointer,dn[2],&sn[2]); GetNextByte(strpointer,dn[3],&sn[3]); GetNextByte(strpointer,dn[4],&sn[4]); GetNextByte(strpointer,dn[5],&sn[5]); GetNextByte(strpointer,dn[6],&sn[6]); } else { const ASCII * name_to_familycode = namefind((*strpointer)) ; if ( name_to_familycode != NULL) { // device name specified (e.g. DS2401) sn[0] = string2num(name_to_familycode); GetDefaultDeviceName( dn, sn, in ) ; sn[1] = dn[1] ; sn[2] = dn[2] ; sn[3] = dn[3] ; sn[4] = dn[4] ; sn[5] = dn[5] ; sn[6] = dn[6] ; } else { // Bad device name LEVEL_DEFAULT("Device %d <%s> not recognized for %s %d -- ignored",DirblobElements(&(in->master.fake.main))+1,*strpointer,in->adapter_name,in->master.fake.index); return ; } } sn[SERIAL_NUMBER_SIZE-1] = CRC8compute(sn, SERIAL_NUMBER_SIZE-1, 0); DirblobAdd(sn, &(in->master.fake.main)); // Ignore bad return }
// Интерпретировать следующий токен bool EscInterpreter::InterpretNext() { if (IsEndOfFile()) return false; unsigned char ch = GetNextByte(); switch (ch) { case 0/*NUL*/: case 7/*BEL*/: case 17/*DC1*/: case 19/*DC3*/: case 127/*DEL*/: break; // Игнорируемые коды case 24/*CAN*/: m_endofpage = true; m_x = m_y = 0; return false; //Конец страницы case 8/*BS*/: // Backspace - сдвиг на 1 символ назад m_x -= m_shiftx; if (m_x < 0) m_x = 0; break; case 9/*HT*/: // Горизонтальная табуляция - реализован частный случай //NOTE: переустановка позиций табуляции игнорируется m_x += m_shiftx * 8; m_x = (m_x / (m_shiftx * 8)) * (m_shiftx * 8); break; case 10/*LF*/: // Line Feed - сдвиг к следующей строке m_y += m_shifty; return true; case 11/*VT*/: //Вертикальная табуляция - в частном случае удовлетворяет описанию. //NOTE: Переустановка позиций табуляции игнорируется m_x = 0; m_y += m_shifty; return true; case 12/*FF*/: // Form Feed - !!! доделать m_endofpage = true; m_x = m_y = 0; return false; case 13/*CR*/: // Carriage Return - возврат каретки m_x = 0; break; case 14/*SO*/: // Включение шрифта вразрядку m_fontsp = true; UpdateShiftX(); break; case 15/*SI*/: // Включение сжатого шрифта (17.1 символов на дюйм) m_fontks = true; UpdateShiftX(); break; case 18/*DC2*/: // Выключение сжатого шрифта m_fontks = false; UpdateShiftX(); break; case 20/*DC4*/: // Выключение шрифта вразрядку m_fontsp = false; UpdateShiftX(); break; case 27/*ESC*/: //Expanded Function Codes return InterpretEscape(); /* иначе "напечатать" символ */ default: PrintCharacter(ch); m_x += m_shiftx; break; } return true; }
// Интерпретировать Escape-последовательность bool EscInterpreter::InterpretEscape() { unsigned char ch = GetNextByte(); switch (ch) { case 'U': // Печать в одном или двух направлениях GetNextByte(); // Игнорируем break; case 'x': // Выбор качества m_printmode = (GetNextByte() != 0); break; // Группа функций character pitch case 'P': // Включение шрифта "пика" m_fontel = false; UpdateShiftX(); break; case 'M': // Включение шрифта "элита" (12 символов на дюйм) m_fontel = true; UpdateShiftX(); break; case 15/*SI*/: // Включение сжатого шрифта m_fontks = true; UpdateShiftX(); break; case '0': // Установка интервала 1/8" m_shifty = 720 / 8; break; case '1': // Установка интервала 7/72" m_shifty = 720 * 7 / 72; break; case '2': m_shifty = 720 / 6; /* set line spacing to 1/6 inch */ break; case 'A': /* text line spacing */ m_shifty = (720 * (int)GetNextByte() / 60); break; case '3': /* graphics line spacing */ m_shifty = (720 * (int)GetNextByte() / 180); break; case 'J': /* variable line spacing */ m_y += (int)GetNextByte() * 720 / 180; return true; case 'C': //PageLength - игнорировать if (GetNextByte() == 0) GetNextByte(); break; case 'N': //Skip perforation - игнорировать GetNextByte(); break; case 'O': break; case 'B': //Set vertical tabs - игнорировать ??? while (GetNextByte() != 0); break; case '/': GetNextByte(); break; case 'D': //Set horizontal tabs - игнорировать ??? while (GetNextByte() != 0); break; case 'Q': //Set right margin - игнорировать ??? GetNextByte(); break; //Bit image graphics mode !!! - недоделано case 'K': /* 8-bit single density graphics */ case 'L': /* the same */ printGR9(2 * 6); break; case 'Y': /* 8-bit double-speed double-density graphics */ printGR9(2 * 3); break; case 'Z': /* 8-bit quadple-density graphics */ printGR9(3 /* = 2*1.5 */); break; case '*': /* Bit Image Graphics Mode */ switch (GetNextByte()) { case 0: /* same as ESC K graphic command */ case 1: /* same as ESC L graphic command */ printGR9(2 * 6); break; case 2: /* same as ESC Y graphic command */ printGR9(2 * 3); break; case 3: /* same as ESC Z graphic command */ printGR9(3); break; case 4: /* CRT 1 */ printGR9(9); break; case 5: //TODO break; case 6: /* CRT 2 */ printGR9(8); break; case 32: /* High-resolution for ESC K */ printGR24(2 * 6); break; case 33: /* High-resolution for ESC L */ printGR24(2 * 3); break; case 38: /* CRT 3 */ printGR24(2 * 4); break; case 39: /* High-resolution triple-density */ printGR24(2 * 2); break; case 40: /* high-resolution hex-density */ printGR24(2); break; } break; /* reassign bit image command ??? */ case '?': break; /* download - игнорировать (???) */ case '&': break; /* this command downloads character sets to the printer */ case '%': break; /* select/deselect download character code */ case ':': /* this command copies the internal character set into the download area */ GetNextByte(); GetNextByte(); GetNextByte(); break; case 'R': /* international character set - игнорировать (???) */ m_charset = GetNextByte(); break; /* MSB control - игнорорировать (???) */ case '#': break; /* clear most significant bit */ case '=': break; /* clear most significant bit */ case '>': break; /* set most significant bit */ /* print table control */ case '6': break; /* select upper character set */ case '7': break; /* select lower character set */ /* home head */ case '<': m_x = 0; /* repositions the print head to the left most column */ break; case 14/*SO*/: // Включение шрифта вразрядку m_fontsp = true; UpdateShiftX(); break; /* inter character space */ case 32/*SP*/: GetNextByte(); break; /* absolute dot position */ case '$': m_x = GetNextByte(); m_x += 256 * (int)GetNextByte(); m_x = (int)((int)m_x * 720 / 60); break; /* relative dot position */ case '\\': { int shift = GetNextByte(); shift += 256 * (int)GetNextByte(); m_x += (int)((int)shift * 720 / (m_printmode ? 180 : 120)); /* !!! учесть моду LQ или DRAFT */ } break; /* CHARACTER CONTROL CODES */ case 'E': // Включение жирного шрифта m_fontfe = true; UpdateShiftX(); break; case 'F': // Выключение жирного шрифта m_fontfe = false; UpdateShiftX(); break; case 'G': // Включение двойной печати m_fontdo = true; break; case 'H': // Выключение двойной печати m_fontdo = false; m_superscript = m_subscript = false; break; case '-': // Подчеркивание m_fontun = (GetNextByte() != 0); break; case 'S': // Включение печати в верхней или нижней части строки { unsigned char ss = GetNextByte(); m_superscript = (ss == 0); m_subscript = (ss == 1); } break; case 'T': // Выключение печати в верхней или нижней части строки m_superscript = m_subscript = false; break; case 'W': // Включение или выключение шрифта вразрядку m_fontsp = (GetNextByte() != 0); UpdateShiftX(); break; case '!': // Выбор вида шрифта { unsigned char fontbits = GetNextByte(); m_fontel = (fontbits & 1) != 0; m_fontks = ((fontbits & 4) != 0) && !m_fontel; m_fontfe = ((fontbits & 8) != 0) && !m_fontel; m_fontdo = (fontbits & 16) != 0; m_fontsp = (fontbits & 32) != 0; UpdateShiftX(); } break; /* italic print */ case '4': /* set italics */ break; case '5': /* clear itelics */ break; /* character table */ case 't': /* select character table ??? */ GetNextByte(); /* игнорировать */ break; /* double height */ case 'w': /* select double height !!! */ GetNextByte(); break; /* SYSTEM CONTROL CODES */ /* reset */ case '@': PrinterReset(); break; /* cut sheet feeder control */ case 25/*EM*/: GetNextByte(); /* ??? - игнорировать */ break; } return true; }
LongBufferSizeType PreTokenizerDecoder::Read(Byte* inBuffer,LongBufferSizeType inBufferSize) { LongBufferSizeType readCount = 0; Byte buffer; while(NotEnded() && readCount < inBufferSize) { if(GetNextByte(buffer) != eSuccess) break; // skip slashes with endliners after them if('\\' == buffer && NotEnded()) { mCarriegeReturnEncountered = false; if(GetNextByte(buffer) != eSuccess) break; if(buffer != 0xA && buffer != 0xD) { // place both chars... *inBuffer = '\\'; ++inBuffer; ++readCount; if(readCount < inBufferSize) { *inBuffer = buffer; ++inBuffer; ++readCount; } else mReadCharsBuffer.push_back(buffer); } else { ++mCurrentLineIndex; // advance line index, also in lines that are continued // note that when skipping, i will possibly still place one character in the output buffer, in case of \0D and something which is not 0A. this // is fine becuase the buffer requires at least one more. // check out if this is 0D0A sequance, which in case the 0A should be skipped as well if(0xD == buffer && NotEnded()) { if(GetNextByte(buffer) != eSuccess) break; if(buffer != 0xA) { *inBuffer = buffer; ++inBuffer; ++readCount; } } } } else { if(0xA == buffer && !mCarriegeReturnEncountered) { ++mCurrentLineIndex; mCarriegeReturnEncountered = false; } else if(0xD == buffer) { ++mCurrentLineIndex; mCarriegeReturnEncountered = true; // this indication is now up, so that if next read is 0xA it will counted as an 0D0A pair, which counts as one line } else mCarriegeReturnEncountered = false; *inBuffer = buffer; ++inBuffer; ++readCount; } } return readCount; }
void Stream::StreamInUtf16() const { unsigned long ch = 0; unsigned char bytes[2]; int nBigEnd = (m_charSet == utf16be) ? 0 : 1; bytes[0] = GetNextByte(); bytes[1] = GetNextByte(); if (!m_input.good()) { return; } ch = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) | static_cast<unsigned long>(bytes[1 ^ nBigEnd]); if (ch >= 0xDC00 && ch < 0xE000) { // Trailing (low) surrogate...ugh, wrong order QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); return; } else if (ch >= 0xD800 && ch < 0xDC00) { // ch is a leading (high) surrogate // Four byte UTF-8 code point // Read the trailing (low) surrogate for (;;) { bytes[0] = GetNextByte(); bytes[1] = GetNextByte(); if (!m_input.good()) { QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); return; } unsigned long chLow = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) | static_cast<unsigned long>(bytes[1 ^ nBigEnd]); if (chLow < 0xDC00 || chLow >= 0xE000) { // Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the // stream. QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); // Deal with the next UTF-16 unit if (chLow < 0xD800 || chLow >= 0xE000) { // Easiest case: queue the codepoint and return QueueUnicodeCodepoint(m_readahead, ch); return; } else { // Start the loop over with the new high surrogate ch = chLow; continue; } } // Select the payload bits from the high surrogate ch &= 0x3FF; ch <<= 10; // Include bits from low surrogate ch |= (chLow & 0x3FF); // Add the surrogacy offset ch += 0x10000; break; } } QueueUnicodeCodepoint(m_readahead, ch); }