/**************************************************************************** * PSDRV_WriteDownloadGlyphShow * * Download and write out a number of glyphs * */ BOOL PSDRV_WriteDownloadGlyphShow(PHYSDEV dev, WORD *glyphs, UINT count) { PSDRV_PDEVICE *physDev = get_psdrv_dev( dev ); UINT i; char g_name[MAX_G_NAME + 1]; assert(physDev->font.fontloc == Download); switch(physDev->font.fontinfo.Download->type) { case Type42: for(i = 0; i < count; i++) { get_glyph_name(dev->hdc, glyphs[i], g_name); T42_download_glyph(dev, physDev->font.fontinfo.Download, glyphs[i], g_name); PSDRV_WriteGlyphShow(dev, g_name); } break; case Type1: for(i = 0; i < count; i++) { get_glyph_name(dev->hdc, glyphs[i], g_name); T1_download_glyph(dev, physDev->font.fontinfo.Download, glyphs[i], g_name); PSDRV_WriteGlyphShow(dev, g_name); } break; default: ERR("Type = %d\n", physDev->font.fontinfo.Download->type); assert(0); } return TRUE; }
/**************************************************************************** * PSDRV_WriteSetDownloadFont * * Write setfont for download font. * */ BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev) { char *ps_name; LPOUTLINETEXTMETRICA potm; DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL); DOWNLOAD *pdl; assert(physDev->font.fontloc == Download); potm = HeapAlloc(GetProcessHeap(), 0, len); GetOutlineTextMetricsA(physDev->hdc, len, potm); get_download_name(physDev, potm, &ps_name); if(physDev->font.fontinfo.Download == NULL) { RECT bbox; UINT emsize; if (!get_bbox(physDev, &bbox, &emsize)) { HeapFree(GetProcessHeap(), 0, potm); return FALSE; } if(!is_room_for_font(physDev)) PSDRV_EmptyDownloadList(physDev, TRUE); pdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pdl)); pdl->ps_name = HeapAlloc(GetProcessHeap(), 0, strlen(ps_name)+1); strcpy(pdl->ps_name, ps_name); pdl->next = NULL; if(physDev->pi->ppd->TTRasterizer == RO_Type42) { pdl->typeinfo.Type42 = T42_download_header(physDev, ps_name, &bbox, emsize); pdl->type = Type42; } if(pdl->typeinfo.Type42 == NULL) { pdl->typeinfo.Type1 = T1_download_header(physDev, ps_name, &bbox, emsize); pdl->type = Type1; } pdl->next = physDev->downloaded_fonts; physDev->downloaded_fonts = pdl; physDev->font.fontinfo.Download = pdl; if(pdl->type == Type42) { char g_name[MAX_G_NAME + 1]; get_glyph_name(physDev->hdc, 0, g_name); T42_download_glyph(physDev, pdl, 0, g_name); } } PSDRV_WriteSetFont(physDev, ps_name, physDev->font.size, physDev->font.escapement); HeapFree(GetProcessHeap(), 0, ps_name); HeapFree(GetProcessHeap(), 0, potm); return TRUE; }
BOOL T42_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index, char *glyph_name) { DWORD start, end, i; char *buf; TYPE42 *t42; const char glyph_def[] = "/%s findfont exch 1 index\n" "havetype42gdir\n" "{/GlyphDirectory get begin %d exch def end}\n" "{/sfnts get 4 index get 3 index 2 index putinterval pop}\n" "ifelse\n" "/CharStrings get\n" "begin\n" " /%s %d def\n" "end\n" "pop pop\n"; TRACE("%d %s\n", index, glyph_name); assert(pdl->type == Type42); t42 = pdl->typeinfo.Type42; if(index < t42->glyph_sent_size) { if(t42->glyph_sent[index]) return TRUE; } else { t42->glyph_sent_size = (index / GLYPH_SENT_INC + 1) * GLYPH_SENT_INC; t42->glyph_sent = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, t42->glyph_sent, t42->glyph_sent_size * sizeof(*(t42->glyph_sent))); } if(!get_glyf_pos(t42, index, &start, &end)) return FALSE; TRACE("start = %x end = %x\n", start, end); if(GET_BE_WORD(t42->tables[t42->glyf_tab].data + start) == 0xffff) { /* Composite glyph */ BYTE *sg_start = t42->tables[t42->glyf_tab].data + start + 10; DWORD sg_flags, sg_index; char sg_name[MAX_G_NAME + 1]; do { sg_flags = GET_BE_WORD(sg_start); sg_index = GET_BE_WORD(sg_start + 2); TRACE("Sending subglyph %04x for glyph %04x\n", sg_index, index); get_glyph_name(physDev->hdc, sg_index, sg_name); T42_download_glyph(physDev, pdl, sg_index, sg_name); sg_start += 4; if(sg_flags & ARG_1_AND_2_ARE_WORDS) sg_start += 4; else sg_start += 2; if(sg_flags & WE_HAVE_A_SCALE) sg_start += 2; else if(sg_flags & WE_HAVE_AN_X_AND_Y_SCALE) sg_start += 4; else if(sg_flags & WE_HAVE_A_TWO_BY_TWO) sg_start += 8; } while(sg_flags & MORE_COMPONENTS); } for(i = 1; t42->glyf_blocks[i]; i++) if(start < t42->glyf_blocks[i]) break; buf = HeapAlloc(GetProcessHeap(), 0, sizeof(glyph_def) + strlen(pdl->ps_name) + 100); /* we don't have a string for the gdir and glyf tables, but we do have a string for the TT header. So the offset we need is tables - 2 */ sprintf(buf, "%d %d\n", t42->num_of_written_tables - 2 + i, start - t42->glyf_blocks[i-1]); PSDRV_WriteSpool(physDev, buf, strlen(buf)); PSDRV_WriteSpool(physDev, "<", 1); for(i = start; i < end; i++) { sprintf(buf, "%02x", *(t42->tables[t42->glyf_tab].data + i)); PSDRV_WriteSpool(physDev, buf, strlen(buf)); if((i - start) % 16 == 15) PSDRV_WriteSpool(physDev, "\n", 1); } PSDRV_WriteSpool(physDev, ">\n", 2); sprintf(buf, glyph_def, pdl->ps_name, index, glyph_name, index); PSDRV_WriteSpool(physDev, buf, strlen(buf)); t42->glyph_sent[index] = TRUE; HeapFree(GetProcessHeap(), 0, buf); return TRUE; }
/**************************************************************************** * PSDRV_WriteSetDownloadFont * * Write setfont for download font. * */ BOOL PSDRV_WriteSetDownloadFont(PHYSDEV dev) { PSDRV_PDEVICE *physDev = get_psdrv_dev( dev ); char *ps_name; LPOUTLINETEXTMETRICA potm; DWORD len = GetOutlineTextMetricsA(dev->hdc, 0, NULL); DOWNLOAD *pdl; LOGFONTW lf; UINT ppem; XFORM xform; assert(physDev->font.fontloc == Download); if (!GetObjectW( GetCurrentObject(dev->hdc, OBJ_FONT), sizeof(lf), &lf )) return FALSE; potm = HeapAlloc(GetProcessHeap(), 0, len); if (!potm) return FALSE; GetOutlineTextMetricsA(dev->hdc, len, potm); get_download_name(dev, potm, &ps_name); physDev->font.fontinfo.Download = is_font_downloaded(physDev, ps_name); ppem = calc_ppem_for_height(dev->hdc, lf.lfHeight); /* Retrieve the world -> device transform */ GetTransform(dev->hdc, 0x204, &xform); if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) { if (xform.eM22 < 0) physDev->font.escapement = -physDev->font.escapement; xform.eM11 = xform.eM22 = fabs(xform.eM22); xform.eM21 = xform.eM12 = 0; } physDev->font.size.xx = ps_round(ppem * xform.eM11); physDev->font.size.xy = ps_round(ppem * xform.eM12); physDev->font.size.yx = -ps_round(ppem * xform.eM21); physDev->font.size.yy = -ps_round(ppem * xform.eM22); physDev->font.underlineThickness = potm->otmsUnderscoreSize; physDev->font.underlinePosition = potm->otmsUnderscorePosition; physDev->font.strikeoutThickness = potm->otmsStrikeoutSize; physDev->font.strikeoutPosition = potm->otmsStrikeoutPosition; if(physDev->font.fontinfo.Download == NULL) { RECT bbox; UINT emsize; if (!get_bbox(dev->hdc, &bbox, &emsize)) { HeapFree(GetProcessHeap(), 0, potm); return FALSE; } if(!is_room_for_font(physDev)) PSDRV_EmptyDownloadList(dev, TRUE); pdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pdl)); pdl->ps_name = HeapAlloc(GetProcessHeap(), 0, strlen(ps_name)+1); strcpy(pdl->ps_name, ps_name); pdl->next = NULL; if(physDev->pi->ppd->TTRasterizer == RO_Type42) { pdl->typeinfo.Type42 = T42_download_header(dev, ps_name, &bbox, emsize); pdl->type = Type42; } if(pdl->typeinfo.Type42 == NULL) { pdl->typeinfo.Type1 = T1_download_header(dev, ps_name, &bbox, emsize); pdl->type = Type1; } pdl->next = physDev->downloaded_fonts; physDev->downloaded_fonts = pdl; physDev->font.fontinfo.Download = pdl; if(pdl->type == Type42) { char g_name[MAX_G_NAME + 1]; get_glyph_name(dev->hdc, 0, g_name); T42_download_glyph(dev, pdl, 0, g_name); } } PSDRV_WriteSetFont(dev, ps_name, physDev->font.size, physDev->font.escapement); HeapFree(GetProcessHeap(), 0, ps_name); HeapFree(GetProcessHeap(), 0, potm); return TRUE; }