123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /*
- * PostScript driver Type1 font functions
- *
- * Copyright 2002 Huw D M Davies for CodeWeavers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include "config.h"
- #include "wine/port.h"
- #include <string.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <assert.h>
- #include "windef.h"
- #include "winbase.h"
- #include "winerror.h"
- #include "wingdi.h"
- #include "winspool.h"
- #include "psdrv.h"
- #include "wine/debug.h"
- WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
- struct tagTYPE1 {
- DWORD glyph_sent_size;
- BOOL *glyph_sent;
- DWORD emsize;
- };
- #define GLYPH_SENT_INC 128
- /* Type 1 font commands */
- enum t1_cmds {
- rlineto = 5,
- rrcurveto = 8,
- closepath = 9,
- hsbw = 13,
- endchar = 14,
- rmoveto = 21
- };
- TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, char *ps_name, RECT *bbox, UINT emsize)
- {
- char *buf;
- TYPE1 *t1;
- char dict[] = /* name, emsquare, fontbbox */
- "25 dict begin\n"
- " /FontName /%s def\n"
- " /Encoding 256 array 0 1 255{1 index exch /.notdef put} for def\n"
- " /PaintType 0 def\n"
- " /FontMatrix [1 %d div 0 0 1 %d div 0 0] def\n"
- " /FontBBox [%d %d %d %d] def\n"
- " /FontType 1 def\n"
- " /Private 7 dict begin\n"
- " /RD {string currentfile exch readhexstring pop} def\n"
- " /ND {def} def\n"
- " /NP {put} def\n"
- " /MinFeature {16 16} def\n"
- " /BlueValues [] def\n"
- " /password 5839 def\n"
- " /lenIV -1 def\n"
- " currentdict end def\n"
- " currentdict dup /Private get begin\n"
- " /CharStrings 256 dict begin\n"
- " /.notdef 4 RD 8b8b0d0e ND\n"
- " currentdict end put\n"
- " end\n"
- "currentdict end dup /FontName get exch definefont pop\n";
- t1 = HeapAlloc(GetProcessHeap(), 0, sizeof(*t1));
- t1->emsize = emsize;
- t1->glyph_sent_size = GLYPH_SENT_INC;
- t1->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- t1->glyph_sent_size *
- sizeof(*(t1->glyph_sent)));
- buf = HeapAlloc(GetProcessHeap(), 0, sizeof(dict) + strlen(ps_name) +
- 100);
- sprintf(buf, dict, ps_name, t1->emsize, t1->emsize,
- bbox->left, bbox->bottom, bbox->right, bbox->top);
- PSDRV_WriteSpool(physDev, buf, strlen(buf));
- HeapFree(GetProcessHeap(), 0, buf);
- return t1;
- }
- typedef struct {
- BYTE *str;
- int len, max_len;
- } STR;
- static STR *str_init(int sz)
- {
- STR *str = HeapAlloc(GetProcessHeap(), 0, sizeof(*str));
- str->max_len = sz;
- str->str = HeapAlloc(GetProcessHeap(), 0, str->max_len);
- str->len = 0;
- return str;
- }
- static void str_free(STR *str)
- {
- HeapFree(GetProcessHeap(), 0, str->str);
- HeapFree(GetProcessHeap(), 0, str);
- }
- static void str_add_byte(STR *str, BYTE b)
- {
- if(str->len == str->max_len) {
- str->max_len *= 2;
- str->str = HeapReAlloc(GetProcessHeap(), 0, str->str, str->max_len);
- }
- str->str[str->len++] = b;
- }
- static void str_add_num(STR *str, int num)
- {
- if(num <= 107 && num >= -107)
- str_add_byte(str, num + 139);
- else if(num >= 108 && num <= 1131) {
- str_add_byte(str, ((num - 108) >> 8) + 247);
- str_add_byte(str, (num - 108) & 0xff);
- } else if(num <= -108 && num >= -1131) {
- num = -num;
- str_add_byte(str, ((num - 108) >> 8) + 251);
- str_add_byte(str, (num - 108) & 0xff);
- } else {
- str_add_byte(str, 0xff);
- str_add_byte(str, (num >> 24) & 0xff);
- str_add_byte(str, (num >> 16) & 0xff);
- str_add_byte(str, (num >> 8) & 0xff);
- str_add_byte(str, (num & 0xff));
- }
- }
- static void str_add_point(STR *str, POINTFX *pt, POINT *curpos)
- {
- POINT newpos;
- newpos.x = pt->x.value + ((pt->x.fract >> 15) & 0x1);
- newpos.y = pt->y.value + ((pt->y.fract >> 15) & 0x1);
- str_add_num(str, newpos.x - curpos->x);
- str_add_num(str, newpos.y - curpos->y);
- *curpos = newpos;
- }
- static void str_add_cmd(STR *str, enum t1_cmds cmd)
- {
- str_add_byte(str, (BYTE)cmd);
- }
- static int str_get_bytes(STR *str, BYTE **b)
- {
- *b = str->str;
- return str->len;
- }
- BOOL T1_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
- char *glyph_name)
- {
- DWORD len, i;
- char *buf;
- TYPE1 *t1;
- STR *charstring;
- BYTE *bytes;
- HFONT old_font, unscaled_font;
- GLYPHMETRICS gm;
- char *glyph_buf;
- POINT curpos;
- TTPOLYGONHEADER *pph;
- TTPOLYCURVE *ppc;
- LOGFONTW lf;
- RECT rc;
- char glyph_def_begin[] =
- "/%s findfont dup\n"
- "/Private get begin\n"
- "/CharStrings get begin\n"
- "/%s %d RD\n";
- char glyph_def_end[] =
- "ND\n"
- "end end\n";
- TRACE("%ld %s\n", index, glyph_name);
- assert(pdl->type == Type1);
- t1 = pdl->typeinfo.Type1;
- if(index < t1->glyph_sent_size) {
- if(t1->glyph_sent[index])
- return TRUE;
- } else {
- t1->glyph_sent_size = (index / GLYPH_SENT_INC + 1) * GLYPH_SENT_INC;
- t1->glyph_sent = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- t1->glyph_sent,
- t1->glyph_sent_size * sizeof(*(t1->glyph_sent)));
- }
- GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
- rc.left = rc.right = rc.bottom = 0;
- rc.top = t1->emsize;
- DPtoLP(physDev->hdc, (POINT*)&rc, 2);
- lf.lfHeight = -abs(rc.top - rc.bottom);
- lf.lfOrientation = lf.lfEscapement = 0;
- unscaled_font = CreateFontIndirectW(&lf);
- old_font = SelectObject(physDev->hdc, unscaled_font);
- len = GetGlyphOutlineW(physDev->hdc, index, GGO_GLYPH_INDEX | GGO_BEZIER,
- &gm, 0, NULL, NULL);
- if(len == GDI_ERROR) return FALSE;
- glyph_buf = HeapAlloc(GetProcessHeap(), 0, len);
- GetGlyphOutlineW(physDev->hdc, index, GGO_GLYPH_INDEX | GGO_BEZIER,
- &gm, len, glyph_buf, NULL);
- SelectObject(physDev->hdc, old_font);
- DeleteObject(unscaled_font);
- charstring = str_init(100);
- curpos.x = gm.gmptGlyphOrigin.x;
- curpos.y = 0;
- str_add_num(charstring, curpos.x);
- str_add_num(charstring, gm.gmCellIncX);
- str_add_cmd(charstring, hsbw);
- pph = (TTPOLYGONHEADER*)glyph_buf;
- while((char*)pph < glyph_buf + len) {
- TRACE("contour len %ld\n", pph->cb);
- ppc = (TTPOLYCURVE*)((char*)pph + sizeof(*pph));
- str_add_point(charstring, &pph->pfxStart, &curpos);
- str_add_cmd(charstring, rmoveto);
- while((char*)ppc < (char*)pph + pph->cb) {
- TRACE("line type %d cpfx = %d\n", ppc->wType, ppc->cpfx);
- switch(ppc->wType) {
- case TT_PRIM_LINE:
- for(i = 0; i < ppc->cpfx; i++) {
- str_add_point(charstring, ppc->apfx + i, &curpos);
- str_add_cmd(charstring, rlineto);
- }
- break;
- case TT_PRIM_CSPLINE:
- for(i = 0; i < ppc->cpfx/3; i++) {
- str_add_point(charstring, ppc->apfx + 3 * i, &curpos);
- str_add_point(charstring, ppc->apfx + 3 * i + 1, &curpos);
- str_add_point(charstring, ppc->apfx + 3 * i + 2, &curpos);
- str_add_cmd(charstring, rrcurveto);
- }
- break;
- default:
- ERR("curve type = %d\n", ppc->wType);
- return FALSE;
- }
- ppc = (TTPOLYCURVE*)((char*)ppc + sizeof(*ppc) +
- (ppc->cpfx - 1) * sizeof(POINTFX));
- }
- str_add_cmd(charstring, closepath);
- pph = (TTPOLYGONHEADER*)((char*)pph + pph->cb);
- }
- str_add_cmd(charstring, endchar);
- buf = HeapAlloc(GetProcessHeap(), 0, sizeof(glyph_def_begin) +
- strlen(pdl->ps_name) + strlen(glyph_name) + 100);
- sprintf(buf, "%%%%glyph %04lx\n", index);
- PSDRV_WriteSpool(physDev, buf, strlen(buf));
- len = str_get_bytes(charstring, &bytes);
- sprintf(buf, glyph_def_begin, pdl->ps_name, glyph_name, len);
- PSDRV_WriteSpool(physDev, buf, strlen(buf));
- PSDRV_WriteBytes(physDev, bytes, len);
- sprintf(buf, glyph_def_end);
- PSDRV_WriteSpool(physDev, buf, strlen(buf));
- str_free(charstring);
- t1->glyph_sent[index] = TRUE;
- HeapFree(GetProcessHeap(), 0, glyph_buf);
- HeapFree(GetProcessHeap(), 0, buf);
- return TRUE;
- }
- void T1_free(TYPE1 *t1)
- {
- HeapFree(GetProcessHeap(), 0, t1->glyph_sent);
- HeapFree(GetProcessHeap(), 0, t1);
- return;
- }
|