/* * Copyright (C) 2002-2004 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * Converted to WinUAE by Toni Wilen 2009 * * Freetype to Win32 CreateFont() conversion by TW in 2010 */ #include "sysconfig.h" #include "sysdeps.h" #include "uae.h" #define WINFONT #define C_LIBPNG #include "epsonprinter.h" #include "win32.h" #include "parser.h" #include "threaddep/thread.h" #include "uae/io.h" #include //#define DEBUGPRINT _T("C:\\Users\\twilen\\Desktop\\CMD_file.1") int pngprint = 0; #ifdef C_LIBPNG #include #include #endif #define PARAM16(I) (params[I+1]*256+params[I]) #define PIXX ((Bitu)floor(curX*dpiX+0.5)) #define PIXY ((Bitu)floor(curY*dpiY+0.5)) #define true 1 #define false 0 #ifdef WINFONT static const TCHAR *epsonprintername; static HFONT curFont; static float curFontHorizPoints, curFontVertPoints; static const TCHAR *curFontName; static HDC memHDC; static LPOUTLINETEXTMETRIC otm; #else static FT_Library FTlib; static FT_Face curFont; #endif static Real64 curX, curY; static Bit16u dpiX, dpiY, ESCCmd; static int ESCSeen; static Bit8u numParam, neededParam; static Bit8u params[20]; static Bit16u style; static Real64 cpi, actcpi; static Bit8u score; static Real64 topMargin, bottomMargin, rightMargin, leftMargin; static Real64 pageWidth, pageHeight, defaultPageWidth, defaultPageHeight; static Real64 lineSpacing, horiztabs[32]; static Bit8u numHorizTabs; static Real64 verttabs[16]; static Bit8u numVertTabs, curCharTable, printQuality; static enum Typeface LQtypeFace; static Real64 extraIntraSpace; static int charRead, autoFeed, printUpperContr; static int printColor, colorPrinted; static struct bitGraphicParams { Bit16u horizDens, vertDens; int adjacent; Bit8u bytesColumn; Bit16u remBytes; Bit8u column[6]; Bit8u readBytesColumn; int pin9; } bitGraph; static Bit8u densk, densl, densy, densz; static Bit16u curMap[256], charTables[4]; static Real64 definedUnit; static int multipoint; static Real64 multiPointSize, multicpi, hmi; static Bit8u msb; static Bit16u numPrintAsChar; static void *outputHandle; static Bit16u multipageOutput, multiPageCounter; static HDC printerDC; static int justification; #define CHARBUFFERSIZE 1000 static int charcnt; static Bit8u charbuffer[CHARBUFFERSIZE]; static uae_u8 *page, *cpage; static int page_w, page_h, page_pitch; static int pagesize; static HMODULE ft; static int pins = 24; static void printCharBuffer(void); static const Bit8u colors[] = { 0x00, 0x00, 0x00, // 0 black 0xff, 0x00, 0xff, // 1 magenta (/green) 0x00, 0xff, 0xff, // 2 cyan (/red) 0xff, 0x00, 0xff, // 3 violet 0xff, 0xff, 0x00, // 4 yellow (/blue) 0xff, 0x00, 0x00, // 5 red 0x00, 0xff, 0x00 // 6 green }; // Various ASCII codepage to unicode maps static const Bit16u cp437Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp737Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0, 0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8, 0x03b9,0x03ba,0x03bb,0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c3,0x03c2,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03c9,0x03ac,0x03ad,0x03ae,0x03ca,0x03af,0x03cc,0x03cd,0x03cb,0x03ce,0x0386,0x0388,0x0389,0x038a,0x038c,0x038e, 0x038f,0x00b1,0x2265,0x2264,0x03aa,0x03ab,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp775Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x0106,0x00fc,0x00e9,0x0101,0x00e4,0x0123,0x00e5,0x0107,0x0142,0x0113,0x0156,0x0157,0x012b,0x0179,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x014d,0x00f6,0x0122,0x00a2,0x015a,0x015b,0x00d6,0x00dc,0x00f8,0x00a3,0x00d8,0x00d7,0x00a4, 0x0100,0x012a,0x00f3,0x017b,0x017c,0x017a,0x201d,0x00a6,0x00a9,0x00ae,0x00ac,0x00bd,0x00bc,0x0141,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x0104,0x010c,0x0118,0x0116,0x2563,0x2551,0x2557,0x255d,0x012e,0x0160,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x0172,0x016a,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x017d, 0x0105,0x010d,0x0119,0x0117,0x012f,0x0161,0x0173,0x016b,0x017e,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x00d3,0x00df,0x014c,0x0143,0x00f5,0x00d5,0x00b5,0x0144,0x0136,0x0137,0x013b,0x013c,0x0146,0x0112,0x0145,0x2019, 0x00ad,0x00b1,0x201c,0x00be,0x00b6,0x00a7,0x00f7,0x201e,0x00b0,0x2219,0x00b7,0x00b9,0x00b3,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp850Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00f8,0x00a3,0x00d8,0x00d7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x00ae,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x00c1,0x00c2,0x00c0,0x00a9,0x2563,0x2551,0x2557,0x255d,0x00a2,0x00a5,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x00e3,0x00c3,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x00a4, 0x00f0,0x00d0,0x00ca,0x00cb,0x00c8,0x0131,0x00cd,0x00ce,0x00cf,0x2518,0x250c,0x2588,0x2584,0x00a6,0x00cc,0x2580, 0x00d3,0x00df,0x00d4,0x00d2,0x00f5,0x00d5,0x00b5,0x00fe,0x00de,0x00da,0x00db,0x00d9,0x00fd,0x00dd,0x00af,0x00b4, 0x00ad,0x00b1,0x2017,0x00be,0x00b6,0x00a7,0x00f7,0x00b8,0x00b0,0x00a8,0x00b7,0x00b9,0x00b3,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp852Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x016f,0x0107,0x00e7,0x0142,0x00eb,0x0150,0x0151,0x00ee,0x0179,0x00c4,0x0106, 0x00c9,0x0139,0x013a,0x00f4,0x00f6,0x013d,0x013e,0x015a,0x015b,0x00d6,0x00dc,0x0164,0x0165,0x0141,0x00d7,0x010d, 0x00e1,0x00ed,0x00f3,0x00fa,0x0104,0x0105,0x017d,0x017e,0x0118,0x0119,0x00ac,0x017a,0x010c,0x015f,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x00c1,0x00c2,0x011a,0x015e,0x2563,0x2551,0x2557,0x255d,0x017b,0x017c,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x0102,0x0103,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x00a4, 0x0111,0x0110,0x010e,0x00cb,0x010f,0x0147,0x00cd,0x00ce,0x011b,0x2518,0x250c,0x2588,0x2584,0x0162,0x016e,0x2580, 0x00d3,0x00df,0x00d4,0x0143,0x0144,0x0148,0x0160,0x0161,0x0154,0x00da,0x0155,0x0170,0x00fd,0x00dd,0x0163,0x00b4, 0x00ad,0x02dd,0x02db,0x02c7,0x02d8,0x00a7,0x00f7,0x00b8,0x00b0,0x00a8,0x02d9,0x0171,0x0158,0x0159,0x25a0,0x00a0 }; static const Bit16u cp855Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x0452,0x0402,0x0453,0x0403,0x0451,0x0401,0x0454,0x0404,0x0455,0x0405,0x0456,0x0406,0x0457,0x0407,0x0458,0x0408, 0x0459,0x0409,0x045a,0x040a,0x045b,0x040b,0x045c,0x040c,0x045e,0x040e,0x045f,0x040f,0x044e,0x042e,0x044a,0x042a, 0x0430,0x0410,0x0431,0x0411,0x0446,0x0426,0x0434,0x0414,0x0435,0x0415,0x0444,0x0424,0x0433,0x0413,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x0445,0x0425,0x0438,0x0418,0x2563,0x2551,0x2557,0x255d,0x0439,0x0419,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x043a,0x041a,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x00a4, 0x043b,0x041b,0x043c,0x041c,0x043d,0x041d,0x043e,0x041e,0x043f,0x2518,0x250c,0x2588,0x2584,0x041f,0x044f,0x2580, 0x042f,0x0440,0x0420,0x0441,0x0421,0x0442,0x0422,0x0443,0x0423,0x0436,0x0416,0x0432,0x0412,0x044c,0x042c,0x2116, 0x00ad,0x044b,0x042b,0x0437,0x0417,0x0448,0x0428,0x044d,0x042d,0x0449,0x0429,0x0447,0x0427,0x00a7,0x25a0,0x00a0 }; static const Bit16u cp857Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x0131,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x0130,0x00d6,0x00dc,0x00f8,0x00a3,0x00d8,0x015e,0x015f, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x011e,0x011f,0x00bf,0x00ae,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x00c1,0x00c2,0x00c0,0x00a9,0x2563,0x2551,0x2557,0x255d,0x00a2,0x00a5,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x00e3,0x00c3,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x00a4, 0x00ba,0x00aa,0x00ca,0x00cb,0x00c8,0x0000,0x00cd,0x00ce,0x00cf,0x2518,0x250c,0x2588,0x2584,0x00a6,0x00cc,0x2580, 0x00d3,0x00df,0x00d4,0x00d2,0x00f5,0x00d5,0x00b5,0x0000,0x00d7,0x00da,0x00db,0x00d9,0x00ec,0x00ff,0x00af,0x00b4, 0x00ad,0x00b1,0x0000,0x00be,0x00b6,0x00a7,0x00f7,0x00b8,0x00b0,0x00a8,0x00b7,0x00b9,0x00b3,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp860Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e3,0x00e0,0x00c1,0x00e7,0x00ea,0x00ca,0x00e8,0x00cd,0x00d4,0x00ec,0x00c3,0x00c2, 0x00c9,0x00c0,0x00c8,0x00f4,0x00f5,0x00f2,0x00da,0x00f9,0x00cc,0x00d5,0x00dc,0x00a2,0x00a3,0x00d9,0x20a7,0x00d3, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x00d2,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp861Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00d0,0x00f0,0x00de,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00fe,0x00fb,0x00dd,0x00fd,0x00d6,0x00dc,0x00f8,0x00a3,0x00d8,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00c1,0x00cd,0x00d3,0x00da,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp862Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x05d0,0x05d1,0x05d2,0x05d3,0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df, 0x05e0,0x05e1,0x05e2,0x05e3,0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp863Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00c2,0x00e0,0x00b6,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x2017,0x00c0,0x00a7, 0x00c9,0x00c8,0x00ca,0x00f4,0x00cb,0x00cf,0x00fb,0x00f9,0x00a4,0x00d4,0x00dc,0x00a2,0x00a3,0x00d9,0x00db,0x0192, 0x00a6,0x00b4,0x00f3,0x00fa,0x00a8,0x00b8,0x00b3,0x00af,0x00ce,0x2310,0x00ac,0x00bd,0x00bc,0x00be,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp864Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x066a,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00b0,0x00b7,0x2219,0x221a,0x2592,0x2500,0x2502,0x253c,0x2524,0x252c,0x251c,0x2534,0x2510,0x250c,0x2514,0x2518, 0x03b2,0x221e,0x03c6,0x00b1,0x00bd,0x00bc,0x2248,0x00ab,0x00bb,0xfef7,0xfef8,0x0000,0x0000,0xfefb,0xfefc,0x0000, 0x00a0,0x00ad,0xfe82,0x00a3,0x00a4,0xfe84,0x0000,0x0000,0xfe8e,0xfe8f,0xfe95,0xfe99,0x060c,0xfe9d,0xfea1,0xfea5, 0x0660,0x0661,0x0662,0x0663,0x0664,0x0665,0x0666,0x0667,0x0668,0x0669,0xfed1,0x061b,0xfeb1,0xfeb5,0xfeb9,0x061f, 0x00a2,0xfe80,0xfe81,0xfe83,0xfe85,0xfeca,0xfe8b,0xfe8d,0xfe91,0xfe93,0xfe97,0xfe9b,0xfe9f,0xfea3,0xfea7,0xfea9, 0xfeab,0xfead,0xfeaf,0xfeb3,0xfeb7,0xfebb,0xfebf,0xfec1,0xfec5,0xfecb,0xfecf,0x00a6,0x00ac,0x00f7,0x00d7,0xfec9, 0x0640,0xfed3,0xfed7,0xfedb,0xfedf,0xfee3,0xfee7,0xfeeb,0xfeed,0xfeef,0xfef3,0xfebd,0xfecc,0xfece,0xfecd,0xfee1, 0xfe7d,0x0651,0xfee5,0xfee9,0xfeec,0xfef0,0xfef2,0xfed0,0xfed5,0xfef5,0xfef6,0xfedd,0xfed9,0xfef1,0x25a0, }; static const Bit16u cp865Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00f8,0x00a3,0x00d8,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00a4, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; static const Bit16u cp866Map[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f, 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f, 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f, 0x0401,0x0451,0x0404,0x0454,0x0407,0x0457,0x040e,0x045e,0x00b0,0x2219,0x00b7,0x221a,0x2116,0x00a4,0x25a0,0x00a0 }; static const Bit16u codepages[15] = {0, 437, 932, 850, 851, 853, 855, 860, 863, 865, 852, 857, 862, 864, 866}; // TODO: Implement all international charsets static const Bit16u intCharSets[15][12] = { {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // USA {0x0023, 0x0024, 0x00e0, 0x00ba, 0x00e7, 0x00a7, 0x005e, 0x0060, 0x00e9, 0x00f9, 0x00e8, 0x00a8}, // France {0x0023, 0x0024, 0x00a7, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x0060, 0x00e4, 0x00f6, 0x00fc, 0x00df}, // Germany {0x00a3, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // UK {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Denmark I {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Sweden {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Italy {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Spain {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Japan {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Norway {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Denmark II {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Spain II {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Latin America {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, {0x0023, 0x0024, 0x00a7, 0x00c4, 0x0027, 0x0022, 0x00b6, 0x0060, 0x00a9, 0x00ae, 0x2020, 0x2122} // Legal }; static void selectCodepage(Bit16u cp) { int i; const Bit16u *mapToUse = NULL; switch(cp) { case 0: // Italics, use cp437 case 437: mapToUse = cp437Map; break; case 737: mapToUse = cp737Map; break; case 775: mapToUse = cp775Map; break; case 850: mapToUse = cp850Map; break; case 852: mapToUse = cp852Map; break; case 855: mapToUse = cp855Map; break; case 857: mapToUse = cp857Map; break; case 860: mapToUse = cp860Map; break; case 861: mapToUse = cp861Map; break; case 863: mapToUse = cp863Map; break; case 864: mapToUse = cp864Map; break; case 865: mapToUse = cp865Map; break; case 866: mapToUse = cp866Map; break; default: write_log(_T("Unsupported codepage %i. Using CP437 instead.\n"), cp); mapToUse = cp437Map; } for (i=0; i<256; i++) curMap[i] = mapToUse[i]; } static int selectfont(Bit16u style) { static const TCHAR *thisFontName; static float thisFontHorizPoints; static float thisFontVertPoints; static Bit16u thisStyle; if (curFont) { for (;;) { if (thisFontName != curFontName) break; if (thisFontHorizPoints != curFontHorizPoints) break; if (thisFontVertPoints != curFontVertPoints) break; if ((thisStyle & (STYLE_ITALICS | STYLE_PROP)) != (style & (STYLE_ITALICS | STYLE_PROP))) break; // still using same font return 1; } DeleteObject (curFont); curFont = NULL; thisFontName = NULL; xfree (otm); otm = NULL; } thisFontHorizPoints = curFontHorizPoints; thisFontVertPoints = curFontVertPoints; thisStyle = style; thisFontName = curFontName; int ly = GetDeviceCaps (memHDC, LOGPIXELSY); int lx = GetDeviceCaps (memHDC, LOGPIXELSX); int rounds = 0; while (rounds < 2) { curFont = CreateFont ((int)(thisFontVertPoints * dpiY / ly + 0.5), (int)(thisFontHorizPoints * dpiX / lx + 0.5), 0, 0, FW_NORMAL, (style & STYLE_ITALICS) ? TRUE : FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, ((style & STYLE_PROP) ? VARIABLE_PITCH : FIXED_PITCH) | FF_DONTCARE, thisFontName); if (curFont) break; rounds++; if (style & STYLE_PROP) thisFontName = curFontName = _T("Times New Roman"); else thisFontName = curFontName = _T("Courier New"); } if (curFont) { SelectObject (memHDC, curFont); int size = GetOutlineTextMetrics (memHDC, 0, NULL); if (size == 0) { DeleteObject(curFont); curFont = NULL; } else { otm = (LPOUTLINETEXTMETRIC)xmalloc (uae_u8, size); GetOutlineTextMetrics (memHDC, size, otm); } } return curFont ? 1 : 0; } static void updateFont(void) { Real64 horizPoints = 10.5; Real64 vertPoints = 10.5; const TCHAR *fontName; if (curFont != NULL) #ifdef WINFONT DeleteObject (curFont); #else FT_Done_Face(curFont); #endif curFont = NULL; int prop = style & STYLE_PROP; switch (LQtypeFace) { case roman: default: if (prop) fontName = _T("Times New Roman"); else fontName = _T("Courier New"); break; case sansserif: if (prop) fontName = _T("Arial"); else fontName = _T("Lucida Console"); break; } #ifdef WINFONT curFontName = fontName; #else if (!ft) { write_log(_T("EPSONPRINTER: No freetype6.dll, unable to load font %s\n"), fontName); curFont = NULL; } else if (FT_New_Face(FTlib, fontName, 0, &curFont)) { char windowsdir[MAX_DPATH]; GetWindowsDirectoryA (windowsdir, sizeof windowsdir); strcat (windowsdir, "\\Fonts\\"); strcat (windowsdir, fontName); if (FT_New_Face(FTlib, windowsdir, 0, &curFont)) { GetWindowsDirectoryA (windowsdir, sizeof windowsdir); strcat (windowsdir, "\\Fonts\\"); strcat (windowsdir, "times.ttf"); if (FT_New_Face(FTlib, windowsdir, 0, &curFont)) { write_log(_T("Unable to load font %s\n"), fontName); curFont = NULL; } } } #endif if (!multipoint) { actcpi = cpi; if (cpi != 10 && !(style & STYLE_CONDENSED)) { horizPoints *= (Real64)10/(Real64)cpi; vertPoints *= (Real64)10/(Real64)cpi; } if (!(style & STYLE_PROP)) { if (cpi == 10 && (style & STYLE_CONDENSED)) { actcpi = 17.14; horizPoints *= (Real64)10/(Real64)17.14; vertPoints *= (Real64)10/(Real64)17.14; } if (cpi == 12 && (style & STYLE_CONDENSED)) { actcpi = 20.0; horizPoints *= (Real64)10/(Real64)20.0; vertPoints *= (Real64)10/(Real64)20.0; } } if (style & (STYLE_PROP | STYLE_CONDENSED)) { horizPoints /= (Real64)2.0; vertPoints /= (Real64)2.0; } if ((style & STYLE_DOUBLEWIDTH) || (style & STYLE_DOUBLEWIDTHONELINE)) { actcpi /= 2; horizPoints *= (Real64)2.0; } if (style & STYLE_DOUBLEHEIGHT) vertPoints *= (Real64)2.0; } else { actcpi = multicpi; horizPoints = vertPoints = multiPointSize; } if ((style & STYLE_SUPERSCRIPT) || (style & STYLE_SUBSCRIPT)) { horizPoints *= (Real64)2/(Real64)3; vertPoints *= (Real64)2/(Real64)3; actcpi /= (Real64)2/(Real64)3; } #ifdef WINFONT curFontHorizPoints = horizPoints; curFontVertPoints = vertPoints; #else if (curFont) FT_Set_Char_Size(curFont, (Bit16u)horizPoints*64, (Bit16u)vertPoints*64, dpiX, dpiY); #endif if (style & STYLE_ITALICS || charTables[curCharTable] == 0) { #ifndef WINFONT FT_Matrix matrix; matrix.xx = 0x10000L; matrix.xy = (FT_Fixed)(0.20 * 0x10000L); matrix.yx = 0; matrix.yy = 0x10000L; if (curFont) FT_Set_Transform(curFont, &matrix, 0); #endif } } static void getfname (TCHAR *fname) { TCHAR tmp[MAX_DPATH]; int number = 0; fetch_screenshotpath (tmp, sizeof tmp / sizeof (TCHAR)); for (;;) { FILE *fp; _stprintf (fname, _T("%sPRINT_%03d.png"), tmp, number); if ((fp = uae_tfopen(fname, _T("rb"))) == NULL) return; number++; fclose (fp); } } static int volatile prt_thread_mode; STATIC_INLINE void getcolor (uae_u8 *Tpage, uae_u8 *Tcpage, int x, int y, int Tpage_pitch, Bit8u *r, Bit8u *g, Bit8u *b) { Bit8u pixel = *((Bit8u*)Tpage + x + (y*Tpage_pitch)); Bit8u c = *((Bit8u*)Tcpage + x + (y*Tpage_pitch)); Bit8u color_r = 0, color_g = 0, color_b = 0; if (c) { Bit32u color = 0; int cindex = 0; while (c) { if (c & 1) { color_r |= (255 - colors[cindex * 3 + 0]) * pixel / 255; color_g |= (255 - colors[cindex * 3 + 1]) * pixel / 255; color_b |= (255 - colors[cindex * 3 + 2]) * pixel / 255; } cindex++; c >>= 1; } } *r = 255 - color_r; *g = 255 - color_g; *b = 255 - color_b; } struct printdata { volatile struct printdata *next; volatile int page_w; volatile int page_h; volatile int page_pitch; volatile uae_u8 *page; volatile uae_u8 *cpage; volatile int colorprinted; }; static volatile struct printdata *queue; static uae_sem_t queue_sem, queue_sem2; static DOCINFO docinfo; static void prt_thread(void *p) { prt_thread_mode = 1; write_log(_T("EPSONPRINTER: background print thread started\n")); while (prt_thread_mode) { uae_sem_wait(&queue_sem); volatile struct printdata *pd = queue; if (pd) { queue = pd->next; } uae_sem_post(&queue_sem); if (!pd) { if (prt_thread_mode < 0 && !queue) { write_log(_T("EPSONPRINTER: background thread end request %p %d\n"), printerDC, multiPageCounter); if (printerDC) { if (multiPageCounter > 0) { write_log(_T("EPSONPRINTER end document\n")); EndDoc(printerDC); } DeleteDC(printerDC); } printerDC = NULL; if (memHDC) DeleteDC(memHDC); memHDC = NULL; multiPageCounter = 0; break; } Sleep(10); } else if (pd) { Bit16u x, y; HDC TmemHDC = memHDC; int Tpage_w = pd->page_w; int Tpage_h = pd->page_h; int Tpage_pitch = pd->page_pitch; uae_u8 *Tpage = (uae_u8*)pd->page; uae_u8 *Tcpage = (uae_u8*)pd->cpage; int TcolorPrinter = pd->colorprinted; if (!multiPageCounter) { docinfo.cbSize = sizeof(docinfo); docinfo.lpszDocName = _T("WinUAE Epson Printer"); docinfo.lpszOutput = NULL; docinfo.lpszDatatype = NULL; docinfo.fwType = 0; StartDoc(printerDC, &docinfo); multiPageCounter = 1; write_log(_T("EPSONPRINTER new document\n")); } else { multiPageCounter++; } HDC TprinterDC = printerDC; if (TprinterDC) { int hz = GetDeviceCaps (TprinterDC, PHYSICALWIDTH); int vz = GetDeviceCaps (TprinterDC, PHYSICALHEIGHT); int topmargin = GetDeviceCaps (TprinterDC, PHYSICALOFFSETX); int leftmargin = GetDeviceCaps (TprinterDC, PHYSICALOFFSETY); HDC dc = NULL; write_log (_T("EPSONPRINTER: page=%d, HP=%d WP=%d TM=%d LM=%d W=%d H=%d\n"), multiPageCounter, hz, vz, topmargin, leftmargin, Tpage_w, Tpage_h); if (TcolorPrinter) dc = GetDC (NULL); HBITMAP bitmap = CreateCompatibleBitmap (dc ? dc : TmemHDC, Tpage_w, Tpage_h); HGDIOBJ hobj = SelectObject (TmemHDC, bitmap); BitBlt (TmemHDC, 0, 0, Tpage_w, Tpage_h, NULL, 0, 0, WHITENESS); StartPage (TprinterDC); // this really needs to use something else than SetPixel().. for (y=0; ypage_w = page_w; pd->page_h = page_h; pd->page_pitch = page_pitch; pd->page = page; pd->cpage = cpage; pd->colorprinted = colorPrinted; if (queue == NULL) { queue = pd; } else { volatile struct printdata *pdx = queue; while (pdx->next) { pdx = pdx->next; } pdx->next = pd; } page = NULL; cpage = NULL; } uae_sem_post(&queue_sem); xfree(page); page = NULL; xfree(cpage); cpage = NULL; if (curFont) DeleteObject (curFont); curFont = NULL; } static void newPage(int save) { printCharBuffer (); if (save) outputPage (); if (page == NULL) { page = xcalloc(uae_u8, pagesize); cpage = xcalloc(uae_u8, pagesize); } curY = topMargin; memset (page, 0, pagesize); } static void initPrinter(void) { Bitu i; curX = curY = 0.0; ESCSeen = false; ESCCmd = 0; numParam = neededParam = 0; topMargin = 0.0; leftMargin = 0.0; rightMargin = pageWidth = defaultPageWidth; bottomMargin = pageHeight = defaultPageHeight; lineSpacing = (Real64)1/6; cpi = 10.0; curCharTable = 1; style = 0; extraIntraSpace = 0.0; printUpperContr = true; bitGraph.remBytes = 0; densk = 0; densl = 1; densy = 2; densz = 3; charTables[0] = 0; // Italics charTables[1] = charTables[2] = charTables[3] = 437; definedUnit = -1; multipoint = false; multiPointSize = 0.0; multicpi = 0.0; hmi = -1.0; msb = 255; numPrintAsChar = 0; LQtypeFace = roman; justification = JUST_LEFT; charcnt = 0; printColor = 0; selectCodepage(charTables[curCharTable]); updateFont(); newPage(false); // Default tabs => Each eight characters for (i = 0; i < 32; i++) horiztabs[i] = i * 8.0f * (1.0f / (Real64)cpi); numHorizTabs = 32; numVertTabs = 255; uae_sem_init(&queue_sem, 0, 1); } static void resetPrinterHard(void) { charRead = false; initPrinter(); } static int printer_init(Bit16u dpi2, Bit16u width, Bit16u height, const TCHAR *printername, int multipageOutput2, int numpins) { pins = numpins; #ifndef WINFONT if (ft == NULL || FT_Init_FreeType(&FTlib)) { write_log(_T("EPSONPRINTER: Unable to init Freetype2. ASCII printing disabled\n")); return 0; } #endif dpiX = dpiY = dpi2; multipageOutput = multipageOutput2; defaultPageWidth = (Real64)width/(Real64)10; defaultPageHeight = (Real64)height/(Real64)10; if (printername) { #if 0 // Show Print dialog to obtain a printer device context PRINTDLG pd; pd.lStructSize = sizeof(PRINTDLG); pd.hDevMode = (HANDLE) NULL; pd.hDevNames = (HANDLE) NULL; pd.Flags = PD_RETURNDC; pd.hwndOwner = NULL; pd.hDC = (HDC) NULL; pd.nFromPage = 1; pd.nToPage = 1; pd.nMinPage = 0; pd.nMaxPage = 0; pd.nCopies = 1; pd.hInstance = NULL; pd.lCustData = 0L; pd.lpfnPrintHook = (LPPRINTHOOKPROC) NULL; pd.lpfnSetupHook = (LPSETUPHOOKPROC) NULL; pd.lpPrintTemplateName = (LPWSTR) NULL; pd.lpSetupTemplateName = (LPWSTR) NULL; pd.hPrintTemplate = (HANDLE) NULL; pd.hSetupTemplate = (HANDLE) NULL; PrintDlg(&pd); printerDC = pd.hDC; #endif epsonprintername = printername; printerDC = CreateDC (NULL, epsonprintername, NULL, NULL); if (!printerDC) return 0; dpiX = GetDeviceCaps(printerDC, LOGPIXELSX); dpiY = GetDeviceCaps(printerDC, LOGPIXELSY); defaultPageWidth = (Real64)GetDeviceCaps(printerDC, HORZRES) / dpiX; defaultPageHeight = (Real64)GetDeviceCaps(printerDC, VERTRES) / dpiY; } // Create page page_w = (Bitu)(defaultPageWidth*dpiX); page_h = (Bitu)(defaultPageHeight*dpiY); pagesize = page_w * page_h; page_pitch = page_w; page = xcalloc (uae_u8, pagesize); cpage = xcalloc (uae_u8, pagesize); curFont = NULL; charRead = false; autoFeed = false; outputHandle = NULL; write_log (_T("EPSONPRINTER: Page size: %dx%d DPI: %dx%d\n"), page_w, page_h, dpiX, dpiY); initPrinter(); memHDC = CreateCompatibleDC (NULL); return 1; }; static void printer_close(void) { if (page != NULL) { xfree (page); page = NULL; xfree (cpage); cpage = NULL; #ifndef WINFONT if (ft) FT_Done_FreeType(FTlib); #endif write_log (_T("EPSONPRINTER: end\n")); } xfree (otm); otm = NULL; if (curFont) DeleteObject (curFont); curFont = NULL; if (prt_thread_mode) { prt_thread_mode = -1; } }; static void setupBitImage(Bit8u dens, Bit16u numCols, int pin9) { switch (dens) { case 0: bitGraph.horizDens = 60; bitGraph.vertDens = 60; bitGraph.adjacent = true; bitGraph.bytesColumn = 1; break; case 1: bitGraph.horizDens = 120; bitGraph.vertDens = 60; bitGraph.adjacent = true; bitGraph.bytesColumn = 1; break; case 2: bitGraph.horizDens = 120; bitGraph.vertDens = 60; bitGraph.adjacent = false; bitGraph.bytesColumn = 1; break; case 3: bitGraph.horizDens = 60; bitGraph.vertDens = 240; bitGraph.adjacent = false; bitGraph.bytesColumn = 1; break; case 4: bitGraph.horizDens = 80; bitGraph.vertDens = 60; bitGraph.adjacent = true; bitGraph.bytesColumn = 1; break; case 5: bitGraph.horizDens = 80; bitGraph.vertDens = 72; bitGraph.adjacent = true; bitGraph.bytesColumn = 1; break; case 6: bitGraph.horizDens = 90; bitGraph.vertDens = 60; bitGraph.adjacent = true; bitGraph.bytesColumn = 1; break; case 7: bitGraph.horizDens = 144; bitGraph.vertDens = 72; bitGraph.adjacent = true; bitGraph.bytesColumn = 1; break; case 32: bitGraph.horizDens = 60; bitGraph.vertDens = 180; bitGraph.adjacent = true; bitGraph.bytesColumn = 3; break; case 33: bitGraph.horizDens = 120; bitGraph.vertDens = 180; bitGraph.adjacent = true; bitGraph.bytesColumn = 3; break; case 38: bitGraph.horizDens = 90; bitGraph.vertDens = 180; bitGraph.adjacent = true; bitGraph.bytesColumn = 3; break; case 39: bitGraph.horizDens = 180; bitGraph.vertDens = 180; bitGraph.adjacent = true; bitGraph.bytesColumn = 3; break; case 40: bitGraph.horizDens = 360; bitGraph.vertDens = 180; bitGraph.adjacent = false; bitGraph.bytesColumn = 3; break; case 64: bitGraph.horizDens = 60; bitGraph.vertDens = 360; bitGraph.adjacent = true; bitGraph.bytesColumn = 6; break; case 65: bitGraph.horizDens = 120; bitGraph.vertDens = 360; bitGraph.adjacent = true; bitGraph.bytesColumn = 6; break; case 70: bitGraph.horizDens = 90; bitGraph.vertDens = 360; bitGraph.adjacent = true; bitGraph.bytesColumn = 6; break; case 71: bitGraph.horizDens = 180; bitGraph.vertDens = 360; bitGraph.adjacent = true; bitGraph.bytesColumn = 6; break; case 72: bitGraph.horizDens = 360; bitGraph.vertDens = 360; bitGraph.adjacent = false; bitGraph.bytesColumn = 6; break; case 73: bitGraph.horizDens = 360; bitGraph.vertDens = 360; bitGraph.adjacent = true; bitGraph.bytesColumn = 6; break; default: write_log(_T("EPSONPRINTER: Unsupported bit image density %i\n"), dens); } bitGraph.pin9 = false; if (pins == 9) { if (pin9) { bitGraph.pin9 = true; bitGraph.bytesColumn = 1; } bitGraph.vertDens = 72; } bitGraph.remBytes = numCols * bitGraph.bytesColumn; bitGraph.readBytesColumn = 0; } static int processCommandChar(Bit8u ch) { if (ESCSeen) { ESCCmd = ch; ESCSeen = false; numParam = 0; if (ESCCmd != 0x78) printCharBuffer (); switch (ESCCmd) { case 0x02: // Undocumented case 0x0e: // Select double-width printing (one line) (ESC SO) case 0x0f: // Select condensed printing (ESC SI) case 0x23: // Cancel MSB control (ESC #) case 0x30: // Select 1/8-inch line spacing (ESC 0) case 0x31: // Select 7/72-inch line spacing (ESC 1) case 0x32: // Select 1/6-inch line spacing (ESC 2) case 0x34: // Select italic font (ESC 4) case 0x35: // Cancel italic font (ESC 5) case 0x36: // Enable printing of upper control codes (ESC 6) case 0x37: // Enable upper control codes (ESC 7) case 0x3c: // Unidirectional mode (one line) (ESC <) case 0x3d: // Set MSB to 0 (ESC =) case 0x3e: // Set MSB to 1 (ESC >) case 0x40: // Initialize printer (ESC @) case 0x45: // Select bold font (ESC E) case 0x46: // Cancel bold font (ESC F) case 0x47: // Select double-strike printing (ESC G) case 0x48: // Cancel double-strike printing (ESC H) case 0x4d: // Select 10.5-point, 12-cpi (ESC M) case 0x4f: // Cancel bottom margin case 0x50: // Select 10.5-point, 10-cpi (ESC P) case 0x54: // Cancel superscript/subscript printing (ESC T) case 0x67: // Select 10.5-point, 15-cpi (ESC g) case 0x73: // Select low-speed mode (ESC s) neededParam = 0; break; case 0x19: // Control paper loading/ejecting (ESC EM) case 0x20: // Set intercharacter space (ESC SP) case 0x21: // Master select (ESC !) case 0x2b: // Set n/360-inch line spacing (ESC +) case 0x2d: // Turn underline on/off (ESC -) case 0x2f: // Select vertical tab channel (ESC /) case 0x33: // Set n/180-inch line spacing (ESC 3) case 0x41: // Set n/60-inch line spacing case 0x43: // Set page length in lines (ESC C) case 0x4a: // Advance print position vertically (ESC J n) case 0x4e: // Set bottom margin (ESC N) case 0x51: // Set right margin (ESC Q) case 0x52: // Select an international character set (ESC R) case 0x53: // Select superscript/subscript printing (ESC S) case 0x55: // Turn unidirectional mode on/off (ESC U) case 0x57: // Turn double-width printing on/off (ESC W) case 0x61: // Select justification (ESC a) case 0x6b: // Select typeface (ESC k) case 0x6c: // Set left margin (ESC 1) case 0x70: // Turn proportional mode on/off (ESC p) case 0x72: // Select printing color (ESC r) case 0x74: // Select character table (ESC t) case 0x77: // Turn double-height printing on/off (ESC w) case 0x78: // Select LQ or draft (ESC x) neededParam = 1; break; case 0x24: // Set absolute horizontal print position (ESC $) case 0x3f: // Reassign bit-image mode (ESC ?) case 0x4b: // Select 60-dpi graphics (ESC K) case 0x4c: // Select 120-dpi graphics (ESC L) case 0x59: // Select 120-dpi, double-speed graphics (ESC Y) case 0x5a: // Select 240-dpi graphics (ESC Z) case 0x5e: // Select 60/120-dpi, 9-pin graphics case 0x5c: // Set relative horizontal print position (ESC \) case 0x63: // Set horizontal motion index (HMI) (ESC c) neededParam = 2; break; case 0x2a: // Select bit image (ESC *) case 0x58: // Select font by pitch and point (ESC X) neededParam = 3; break; case 0x62: // Set vertical tabs in VFU channels (ESC b) case 0x42: // Set vertical tabs (ESC B) numVertTabs = 0; return true; case 0x44: // Set horizontal tabs (ESC D) numHorizTabs = 0; return true; case 0x25: // Select user-defined set (ESC %) case 0x26: // Define user-defined characters (ESC &) case 0x3a: // Copy ROM to RAM (ESC :) write_log(_T("User-defined characters not supported!\n")); return true; case 0x28: // Two bytes sequence return true; default: write_log(_T("EPSONPRINTER: Unknown command ESC %c (%02X). Unable to skip parameters.\n"), ESCCmd, ESCCmd); neededParam = 0; ESCCmd = 0; return true; } if (neededParam > 0) return true; } // Two bytes sequence if (ESCCmd == 0x28) { ESCCmd = 0x200 + ch; switch (ESCCmd) { case 0x242: // Bar code setup and print (ESC (B) case 0x25e: // Print data as characters (ESC (^) neededParam = 2; break; case 0x255: // Set unit (ESC (U) neededParam = 3; break; case 0x243: // Set page length in defined unit (ESC (C) case 0x256: // Set absolute vertical print position (ESC (V) case 0x276: // Set relative vertical print position (ESC (v) neededParam = 4; break; case 0x228: // Assign character table (ESC (t) case 0x22d: // Select line/score (ESC (-) neededParam = 5; break; case 0x263: // Set page format (ESC (c) neededParam = 6; break; default: // ESC ( commands are always followed by a "number of parameters" word parameter write_log(_T("EPSONPRINTER: Skipping unsupported command ESC ( %c (%02X).\n"), ESCCmd, ESCCmd); neededParam = 2; ESCCmd = 0x101; return true; } if (neededParam > 0) return true; } // Ignore VFU channel setting if (ESCCmd == 0x62) { ESCCmd = 0x42; return true; } // Collect vertical tabs if (ESCCmd == 0x42) { if (ch == 0 || (numVertTabs>0 && verttabs[numVertTabs-1] > (Real64)ch*lineSpacing)) // Done ESCCmd = 0; else if (numVertTabs < 16) verttabs[numVertTabs++] = (Real64)ch*lineSpacing; } // Collect horizontal tabs if (ESCCmd == 0x44) { if (ch == 0 || (numHorizTabs>0 && horiztabs[numHorizTabs-1] > (Real64)ch*(1/(Real64)cpi))) // Done ESCCmd = 0; else if (numHorizTabs < 32) horiztabs[numHorizTabs++] = (Real64)ch*(1/(Real64)cpi); } if (numParam < neededParam) { params[numParam++] = ch; if (numParam < neededParam) return true; } if (ESCCmd != 0) { switch (ESCCmd) { case 0x02: // Undocumented // Ignore break; case 0x0e: // Select double-width printing (one line) (ESC SO) if (!multipoint) { hmi = -1; style |= STYLE_DOUBLEWIDTHONELINE; updateFont(); } break; case 0x0f: // Select condensed printing (ESC SI) if (!multipoint) { hmi = -1; style |= STYLE_CONDENSED; updateFont(); } break; case 0x19: // Control paper loading/ejecting (ESC EM) // We are not really loading paper, so most commands can be ignored if (params[0] == 'R') newPage(true); break; case 0x20: // Set intercharacter space (ESC SP) if (!multipoint) { extraIntraSpace = (Real64)params[0] / (printQuality==QUALITY_DRAFT?120:180); hmi = -1; updateFont(); } break; case 0x21: // Master select (ESC !) cpi = (params[0] & 0x01 ? 12:10) + 0.0f; // Reset first seven bits style &= 0xFF80; if (params[0] & 0x02) style |= STYLE_PROP; if (params[0] & 0x04) style |= STYLE_CONDENSED; if (params[0] & 0x08) style |= STYLE_BOLD; if (params[0] & 0x10) style |= STYLE_DOUBLESTRIKE; if (params[0] & 0x20) style |= STYLE_DOUBLEWIDTH; if (params[0] & 0x40) style |= STYLE_ITALICS; if (params[0] & 0x80) { score = SCORE_SINGLE; style |= STYLE_UNDERLINE; } hmi = -1; multipoint = false; updateFont(); break; case 0x23: // Cancel MSB control (ESC #) msb = 255; break; case 0x24: // Set absolute horizontal print position (ESC $) { Real64 newX; Real64 unitSize = definedUnit; if (unitSize < 0) unitSize = (Real64)60.0; newX = leftMargin + ((Real64)PARAM16(0)/unitSize); if (newX <= rightMargin) curX = newX; } break; case 0x2a: // Select bit image (ESC *) setupBitImage(params[0], PARAM16(1), false); break; case 0x2b: // Set n/360-inch line spacing (ESC +) lineSpacing = (Real64)params[0]/360; break; case 0x2d: // Turn underline on/off (ESC -) if (params[0] == 0 || params[0] == 48) style &= 0xFFFF - STYLE_UNDERLINE; if (params[0] == 1 || params[0] == 49) { style |= STYLE_UNDERLINE; score = SCORE_SINGLE; } updateFont(); break; case 0x2f: // Select vertical tab channel (ESC /) // Ignore break; case 0x30: // Select 1/8-inch line spacing (ESC 0) lineSpacing = (Real64)1/8; break; case 0x31: // Select 7/72-inch line spacing (ESC 1) 9-pin ONLY lineSpacing = (Real64)7/72; break; case 0x32: // Select 1/6-inch line spacing (ESC 2) lineSpacing = (Real64)1/6; break; case 0x33: // Set n/180-inch line spacing (ESC 3) lineSpacing = (Real64)params[0]/180; break; case 0x34: // Select italic font (ESC 4) style |= STYLE_ITALICS; updateFont(); break; case 0x35: // Cancel italic font (ESC 5) style &= 0xFFFF - STYLE_ITALICS; updateFont(); break; case 0x36: // Enable printing of upper control codes (ESC 6) printUpperContr = true; break; case 0x37: // Enable upper control codes (ESC 7) printUpperContr = false; break; case 0x3c: // Unidirectional mode (one line) (ESC <) // We don't have a print head, so just ignore this break; case 0x3d: // Set MSB to 0 (ESC =) msb = 0; break; case 0x3e: // Set MSB to 1 (ESC >) msb = 1; break; case 0x3f: // Reassign bit-image mode (ESC ?) if (params[0] == 75) densk = params[1]; if (params[0] == 76) densl = params[1]; if (params[0] == 89) densy = params[1]; if (params[0] == 90) densz = params[1]; break; case 0x40: // Initialize printer (ESC @) initPrinter(); break; case 0x41: // Set n/60-inch line spacing lineSpacing = (Real64)params[0]/60; break; case 0x43: // Set page length in lines (ESC C) if (params[0] != 0) pageHeight = bottomMargin = (Real64)params[0] * lineSpacing; else // == 0 => Set page length in inches { neededParam = 1; numParam = 0; ESCCmd = 0x100; return true; } break; case 0x45: // Select bold font (ESC E) style |= STYLE_BOLD; updateFont(); break; case 0x46: // Cancel bold font (ESC F) style &= 0xFFFF - STYLE_BOLD; updateFont(); break; case 0x47: // Select dobule-strike printing (ESC G) style |= STYLE_DOUBLESTRIKE; break; case 0x48: // Cancel double-strike printing (ESC H) style &= 0xFFFF - STYLE_DOUBLESTRIKE; break; case 0x4a: // Advance print position vertically (ESC J n) curY += (Real64)((Real64)params[0] / (pins == 9 ? 216 : 180)); if (curY > bottomMargin) newPage(true); break; case 0x4b: // Select 60-dpi graphics (ESC K) setupBitImage(densk, PARAM16(0), false); break; case 0x4c: // Select 120-dpi graphics (ESC L) setupBitImage(densl, PARAM16(0), false); break; case 0x4d: // Select 10.5-point, 12-cpi (ESC M) cpi = 12; hmi = -1; multipoint = false; updateFont(); break; case 0x4e: // Set bottom margin (ESC N) topMargin = 0.0; bottomMargin = (Real64)params[0] * lineSpacing; break; case 0x4f: // Cancel bottom (and top) margin topMargin = 0.0; bottomMargin = pageHeight; break; case 0x50: // Select 10.5-point, 10-cpi (ESC P) cpi = 10; hmi = -1; multipoint = false; updateFont(); break; case 0x51: // Set right margin rightMargin = (Real64)(params[0]-1.0) / (Real64)cpi; if (rightMargin < 0) rightMargin = 0; if (rightMargin < leftMargin) rightMargin = leftMargin; break; case 0x52: // Select an international character set (ESC R) if (params[0] <= 13 || params[0] == 64) { if (params[0] == 64) params[0] = 14; curMap[0x23] = intCharSets[params[0]][0]; curMap[0x24] = intCharSets[params[0]][1]; curMap[0x40] = intCharSets[params[0]][2]; curMap[0x5b] = intCharSets[params[0]][3]; curMap[0x5c] = intCharSets[params[0]][4]; curMap[0x5d] = intCharSets[params[0]][5]; curMap[0x5e] = intCharSets[params[0]][6]; curMap[0x60] = intCharSets[params[0]][7]; curMap[0x7b] = intCharSets[params[0]][8]; curMap[0x7c] = intCharSets[params[0]][9]; curMap[0x7d] = intCharSets[params[0]][10]; curMap[0x7e] = intCharSets[params[0]][11]; } break; case 0x53: // Select superscript/subscript printing (ESC S) if (params[0] == 0 || params[0] == 48) style |= STYLE_SUBSCRIPT; if (params[0] == 1 || params[1] == 49) style |= STYLE_SUPERSCRIPT; updateFont(); break; case 0x54: // Cancel superscript/subscript printing (ESC T) style &= 0xFFFF - STYLE_SUPERSCRIPT - STYLE_SUBSCRIPT; updateFont(); break; case 0x55: // Turn unidirectional mode on/off (ESC U) // We don't have a print head, so just ignore this break; case 0x57: // Turn double-width printing on/off (ESC W) if (!multipoint) { hmi = -1; if (params[0] == 0 || params[0] == 48) style &= 0xFFFF - STYLE_DOUBLEWIDTH; if (params[0] == 1 || params[0] == 49) style |= STYLE_DOUBLEWIDTH; updateFont(); } break; case 0x58: // Select font by pitch and point (ESC X) multipoint = true; // Copy currently non-multipoint CPI if no value was set so far if (multicpi == 0) multicpi = cpi; if (params[0] > 0) // Set CPI { if (params[0] == 1) // Proportional spacing style |= STYLE_PROP; else if (params[0] >= 5) multicpi = (Real64)360 / (Real64)params[0]; } if (multiPointSize == 0) multiPointSize = (Real64)10.5; if (PARAM16(1) > 0) // Set points multiPointSize = ((Real64)PARAM16(1)) / 2; updateFont(); break; case 0x59: // Select 120-dpi, double-speed graphics (ESC Y) setupBitImage(densy, PARAM16(0), false); break; case 0x5a: // Select 240-dpi graphics (ESC Z) setupBitImage(densz, PARAM16(0), false); break; case 0x5e: // Select 60/120-dpi, 9-pin graphics setupBitImage(densy, PARAM16(0), true); break; case 0x5c: // Set relative horizontal print position (ESC \) { Bit16s toMove = PARAM16(0); Real64 unitSize = definedUnit; if (unitSize < 0) unitSize = (Real64)(printQuality==QUALITY_DRAFT?120.0:180.0); curX += (Real64)((Real64)toMove / unitSize); } break; case 0x61: // Select justification (ESC a) printCharBuffer (); justification = JUST_LEFT; if (params[0] == 1 || params[0] == 31) justification = JUST_CENTER; if (params[0] == 2 || params[0] == 32) justification = JUST_RIGHT; if (params[0] == 3 || params[0] == 33) justification = JUST_FULL; break; case 0x63: // Set horizontal motion index (HMI) (ESC c) hmi = (Real64)PARAM16(0) / (Real64)360.0; extraIntraSpace = 0.0; break; case 0x67: // Select 10.5-point, 15-cpi (ESC g) cpi = 15; hmi = -1; multipoint = false; updateFont(); break; case 0x6b: // Select typeface (ESC k) if (params[0] <= 11 || params[0] == 30 || params[0] == 31) LQtypeFace = (Typeface)params[0]; updateFont(); break; case 0x6c: // Set left margin (ESC 1) leftMargin = (Real64)(params[0]-1.0) / (Real64)cpi; if (leftMargin < 0) leftMargin = 0; if (curX < leftMargin) curX = leftMargin; break; case 0x70: // Turn proportional mode on/off (ESC p) if (params[0] == 0 || params[0] == 48) style &= (0xffff - STYLE_PROP); if (params[0] == 1 || params[0] == 49) { style |= STYLE_PROP; printQuality = QUALITY_LQ; } multipoint = false; hmi = -1; updateFont(); break; case 0x72: // Select printing color (ESC r) printColor = params[0]; if (printColor > 6) printColor = 0; break; case 0x73: // Select low-speed mode (ESC s) // Ignore break; case 0x74: // Select character table (ESC t) if (params[0] < 4) curCharTable = params[0]; if (params[0] >= 48 && params[0] <= 51) curCharTable = params[0] - 48; selectCodepage(charTables[curCharTable]); updateFont(); break; case 0x77: // Turn double-height printing on/off (ESC w) if (!multipoint) { if (params[0] == 0 || params[0] == 48) style &= 0xFFFF - STYLE_DOUBLEHEIGHT; if (params[0] == 1 || params[0] == 49) style |= STYLE_DOUBLEHEIGHT; updateFont(); } break; case 0x78: // Select LQ or draft (ESC x) if (params[0] == 0 || params[0] == 48) printQuality = QUALITY_DRAFT; if (params[0] == 1 || params[0] == 49) printQuality = QUALITY_LQ; break; case 0x100: // Set page length in inches (ESC C NUL) pageHeight = (Real64)params[0]; bottomMargin = pageHeight; topMargin = 0.0; break; case 0x101: // Skip unsupported ESC ( command neededParam = PARAM16(0); numParam = 0; break; case 0x228: // Assign character table (ESC (t) if (params[2] < 4 && params[3] < 16) { charTables[params[2]] = codepages[params[3]]; if (params[2] == curCharTable) selectCodepage(charTables[curCharTable]); } break; case 0x22d: // Select line/score (ESC (-) style &= 0xFFFF - STYLE_UNDERLINE - STYLE_STRIKETHROUGH - STYLE_OVERSCORE; score = params[4]; if (score) { if (params[3] == 1) style |= STYLE_UNDERLINE; if (params[3] == 2) style |= STYLE_STRIKETHROUGH; if (params[3] == 3) style |= STYLE_OVERSCORE; } updateFont(); break; case 0x242: // Bar code setup and print (ESC (B) write_log(_T("EPSONPRINTER: Barcode printing not supported\n")); // Find out how many bytes to skip neededParam = PARAM16(0); numParam = 0; break; case 0x243: // Set page length in defined unit (ESC (C) if (params[0] != 0 && definedUnit > 0) { pageHeight = bottomMargin = ((Real64)PARAM16(2)) * definedUnit; topMargin = 0.0; } break; case 0x255: // Set unit (ESC (U) definedUnit = (Real64)3600 / (Real64)params[2]; break; case 0x256: // Set absolute vertical print position (ESC (V) { Real64 unitSize = definedUnit; Real64 newPos; if (unitSize < 0) unitSize = (Real64)360.0; newPos = topMargin + (((Real64)PARAM16(2)) * unitSize); if (newPos > bottomMargin) newPage(true); else curY = newPos; } break; case 0x25e: // Print data as characters (ESC (^) numPrintAsChar = PARAM16(0); break; case 0x263: // Set page format (ESC (c) if (definedUnit > 0) { topMargin = ((Real64)PARAM16(2)) * definedUnit; bottomMargin = ((Real64)PARAM16(4)) * definedUnit; } break; case 0x276: // Set relative vertical print position (ESC (v) { Real64 unitSize = definedUnit; Real64 newPos; if (unitSize < 0) unitSize = (Real64)360.0; newPos = curY + ((Real64)((Bit16s)PARAM16(2)) * unitSize); if (newPos > topMargin) { if (newPos > bottomMargin) newPage(true); else curY = newPos; } } break; default: if (ESCCmd < 0x100) write_log(_T("EPSONPRINTER: Skipped unsupported command ESC %c (%02X)\n"), ESCCmd, ESCCmd); else write_log(_T("EPSONPRINTER: Skipped unsupported command ESC ( %c (%02X)\n"), ESCCmd-0x200, ESCCmd-0x200); } ESCCmd = 0; return true; } switch (ch) { case 0x07: // Beeper (BEL) // BEEEP! return true; case 0x08: // Backspace (BS) { Real64 newX = curX - (1/(Real64)actcpi); if (hmi > 0) newX = curX - hmi; if (newX >= leftMargin) curX = newX; } return true; case 0x09: // Tab horizontally (HT) { // Find tab right to current pos Real64 moveTo = -1; Bit8u i; for (i=0; i curX) moveTo = horiztabs[i]; // Nothing found => Ignore if (moveTo > 0 && moveTo < rightMargin) curX = moveTo; } return true; case 0x0b: // Tab vertically (VT) if (numVertTabs == 0) // All tabs cancelled => Act like CR curX = leftMargin; else if (numVertTabs == 255) // No tabs set since reset => Act like LF { curX = leftMargin; curY += lineSpacing; if (curY > bottomMargin) newPage(true); } else { // Find tab below current pos Real64 moveTo = -1; Bit8u i; for (i=0; i curY) moveTo = verttabs[i]; // Nothing found => Act like FF if (moveTo > bottomMargin || moveTo < 0) newPage(true); else curY = moveTo; } if (style & STYLE_DOUBLEWIDTHONELINE) { style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; updateFont(); } return true; case 0x0c: // Form feed (FF) printCharBuffer (); if (style & STYLE_DOUBLEWIDTHONELINE) { style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; updateFont(); } newPage(true); return true; case 0x0d: // Carriage Return (CR) printCharBuffer (); curX = leftMargin; if (!autoFeed) return true; case 0x0a: // Line feed printCharBuffer (); if (style & STYLE_DOUBLEWIDTHONELINE) { style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; updateFont(); } curX = leftMargin; curY += lineSpacing; if (curY > bottomMargin) newPage(true); return true; case 0x0e: //Select Real64-width printing (one line) (SO) if (!multipoint) { hmi = -1; style |= STYLE_DOUBLEWIDTHONELINE; updateFont(); } return true; case 0x0f: // Select condensed printing (SI) if (!multipoint) { hmi = -1; style |= STYLE_CONDENSED; updateFont(); } return true; case 0x11: // Select printer (DC1) // Ignore return true; case 0x12: // Cancel condensed printing (DC2) hmi = -1; style &= 0xFFFF - STYLE_CONDENSED; updateFont(); return true; case 0x13: // Deselect printer (DC3) // Ignore return true; case 0x14: // Cancel double-width printing (one line) (DC4) hmi = -1; style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; updateFont(); return true; case 0x18: // Cancel line (CAN) return true; case 0x1b: // ESC ESCSeen = true; return true; default: return false; } return false; } static void printBitGraph(Bit8u ch) { Bitu i; Bitu pixsizeX, pixsizeY; Real64 oldY = curY; bitGraph.column[bitGraph.readBytesColumn++] = ch; bitGraph.remBytes--; // Only print after reading a full column if (bitGraph.readBytesColumn < bitGraph.bytesColumn) return; // When page dpi is greater than graphics dpi, the drawn pixels get "bigger" pixsizeX = dpiX/bitGraph.horizDens > 0?dpiX/bitGraph.horizDens:1; pixsizeY = dpiY/bitGraph.vertDens > 0?dpiY/bitGraph.vertDens:1; for (i=0; i=0; j--) { Bit8u pixel = (bitGraph.column[i] >> j) & 0x01; if (bitGraph.pin9 && i == 1 && j == 7) pixel = bitGraph.column[i] & 0x01; if (pixel != 0) { Bitu xx; for (xx=0; xx= 0) && (desty+y >= 0)) { Bit8u* target = (Bit8u*)page + (x+destx) + (y+desty)*page_pitch; Bit8u* ctarget = (Bit8u*)cpage + (x+destx) + (y+desty)*page_pitch; Bit8u b = *source; if (b >= 64) { b = 255; } else if (b == 0) { b = 0; } else { b = (b << 2) | (b >> 4); } if (add) { if (*target + (unsigned int)b > 255) *target = 255; else *target += b; } else *target = b; *ctarget |= 1 << printColor; } } } if (printColor) colorPrinted = true; } static void drawLine(int fromx, int tox, int y, int broken) { int x; int breakmod = dpiX / 15; int gapstart = (breakmod * 4) / 5; // Draw anti-aliased line for (x=fromx; x<=tox; x++) { // Skip parts if broken line or going over the border if ((!broken || (x%breakmod <= gapstart)) && (x < page_w) && (x >= 0)) { if (y < 0) continue; if (y > 0 && (y-1) < page_h) { *((Bit8u*)page + x + (y-1)*page_pitch) = 120; *((Bit8u*)cpage + x + (y-1)*page_pitch) |= 1 << printColor; } if (y < page_h) { *((Bit8u*)page + x + y*page_pitch) = !broken?255:120; *((Bit8u*)cpage + x + y*page_pitch) |= 1 << printColor; } if (y+1 < page_h) { *((Bit8u*)page + x + (y+1)*page_pitch) = 120; *((Bit8u*)cpage + x + (y+1)*page_pitch) |= 1 << printColor; } } } if (printColor) colorPrinted = true; } static void printSingleChar(Bit8u ch, int doprint) { int penX = PIXX; int penY = PIXY; Bit16u lineStart; int bitmap_left = 0; int bitmap_top = 0; int ascender = 0; int width = 0; int rows = 0; int height = 0; int pitch = 0; int advancex = 0; uae_u8 *gbitmap = NULL; #ifndef WINFONT // Do not print if no font is available if (!curFont) return; bitmap_left = curFont->glyph->bitmap_left; bitmap_top = curFont->glyph->bitmap_top; ascender = curFont->size->metrics.ascender / 64; rows = curFont->glyph->bitmap.rows; advancex = curFont->glyph->advance.x / 64; // Find the glyph for the char to render index = FT_Get_Char_Index(curFont, curMap[ch]); // Load the glyph FT_Load_Glyph(curFont, index, FT_LOAD_DEFAULT); // Render a high-quality bitmap FT_Render_Glyph(curFont->glyph, FT_RENDER_MODE_NORMAL); gbitmap = curFont->glyph->bitmap; #else if (!selectfont (style)) return; MAT2 m2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; GLYPHMETRICS metrics; int bufsize = GetGlyphOutline (memHDC, curMap[ch], GGO_GRAY8_BITMAP, &metrics, 0, NULL, &m2); if (bufsize >= 0) { if (bufsize == 0) bufsize = 4; gbitmap = xcalloc (uae_u8, bufsize); GetGlyphOutline (memHDC, curMap[ch], GGO_GRAY8_BITMAP, &metrics, bufsize, gbitmap, &m2); bitmap_left = metrics.gmptGlyphOrigin.x; bitmap_top = metrics.gmptGlyphOrigin.y; width = metrics.gmBlackBoxX; rows = metrics.gmBlackBoxY; advancex = metrics.gmCellIncX; height = otm->otmTextMetrics.tmHeight; ascender = otm->otmAscent; pitch = (width + 3) & ~3; } #endif int deltaY = 0; if (style & STYLE_SUBSCRIPT) deltaY = rows / 2; else if (style & STYLE_SUPERSCRIPT) deltaY = rows / 2; if (gbitmap) { penX = PIXX + bitmap_left; penY = PIXY - bitmap_top + ascender + deltaY; if (doprint) { // Copy bitmap into page blitGlyph(gbitmap, width, rows, pitch, penX, penY, false); // Doublestrike => Print the glyph a second time one pixel below if (style & STYLE_DOUBLESTRIKE) blitGlyph(gbitmap, width, rows, pitch, penX, penY+1, true); // Bold => Print the glyph a second time one pixel to the right if (style & STYLE_BOLD) { printColor = 0; blitGlyph(gbitmap, width, rows, pitch, penX+1, penY, true); } } } // For line printing lineStart = PIXX; if (style & STYLE_PROP) curX += (Real64)((Real64)(advancex)/(Real64)(dpiX)); else { if (hmi < 0) curX += 1.0f / (Real64)actcpi; else curX += hmi; } curX += extraIntraSpace; // Draw lines if desired if (doprint && score != SCORE_NONE && (style & (STYLE_UNDERLINE|STYLE_STRIKETHROUGH|STYLE_OVERSCORE))) { // Find out where to put the line Bit16u lineY = PIXY + deltaY; Bit16u xEnd = lineStart + advancex; if (style & STYLE_UNDERLINE) lineY = PIXY + deltaY + ascender * 100 / 70; if (style & STYLE_STRIKETHROUGH) lineY = PIXY + deltaY + ascender / 2; if (style & STYLE_OVERSCORE) lineY = (uae_u16)(PIXY + deltaY - otm->otmTextMetrics.tmDescent - ((score == SCORE_DOUBLE || score == SCORE_DOUBLEBROKEN) ? 5 : 0)); drawLine(lineStart, xEnd, lineY, score == SCORE_SINGLEBROKEN || score == SCORE_DOUBLEBROKEN); if (score == SCORE_DOUBLE || score == SCORE_DOUBLEBROKEN) drawLine(lineStart, xEnd, lineY + 5, score == SCORE_SINGLEBROKEN || score == SCORE_DOUBLEBROKEN); } #ifdef WINFONT xfree (gbitmap); #endif } static void printCharBuffer(void) { if (justification != JUST_LEFT) { curX = 0; for (int i = 0; i < charcnt; i++) { printSingleChar (charbuffer[i], false); } switch (justification) { case JUST_RIGHT: curX = rightMargin - curX; break; case JUST_CENTER: curX = leftMargin + (rightMargin - leftMargin) / 2 - curX / 2; break; case JUST_FULL: { float width = rightMargin - leftMargin; if (curX > width * 50 / 100) { float extraw = (width - curX) / charcnt; curX = leftMargin; for (int i = 0; i < charcnt; i++) { printSingleChar (charbuffer[i], true); curX += extraw; } charcnt = 0; return; } else { curX = leftMargin; } } break; default: curX = leftMargin; break; } } for (int i = 0; i < charcnt; i++) { printSingleChar(charbuffer[i], true); } charcnt = 0; } static void printChar(Bit8u ch) { #ifndef WINFONT FT_UInt index; #endif charRead = true; if (page == NULL) return; // Don't think that DOS programs uses this but well: Apply MSB if desired if (msb != 255) { if (msb == 0) ch &= 0x7F; if (msb == 1) ch |= 0x80; } // Are we currently printing a bit graphic? if (bitGraph.remBytes > 0) { printBitGraph(ch); return; } // Print everything? if (numPrintAsChar > 0) { numPrintAsChar--; } else if (processCommandChar(ch)) { printCharBuffer (); return; } charbuffer[charcnt++] = ch; if (charcnt >= CHARBUFFERSIZE) { printCharBuffer (); } } static int isBlank(void) { Bit16u x, y; int blank = true; for (y=0; y