Example #1
0
File: download.c Project: bpon/wine
static UINT calc_ppem_for_height(HDC hdc, LONG height)
{
    BYTE os2[78]; /* size of version 0 table */
    BYTE hhea[8]; /* just enough to get the ascender and descender */
    LONG ascent = 0, descent = 0;
    UINT emsize;

    if(height < 0) return -height;

    if(GetFontData(hdc, MS_MAKE_TAG('O','S','/','2'), 0, os2, sizeof(os2)) == sizeof(os2))
    {
        ascent  = GET_BE_WORD(os2 + 74); /* usWinAscent */
        descent = GET_BE_WORD(os2 + 76); /* usWinDescent */
    }

    if(ascent + descent == 0)
    {
        if(GetFontData(hdc, MS_MAKE_TAG('h','h','e','a'), 0, hhea, sizeof(hhea)) == sizeof(hhea))
        {
            ascent  =  (signed short)GET_BE_WORD(hhea + 4); /* Ascender */
            descent = -(signed short)GET_BE_WORD(hhea + 6); /* Descender */
        }
    }

    if(ascent + descent == 0) return height;

    get_bbox(hdc, NULL, &emsize);

    return MulDiv(emsize, height, ascent + descent);
}
Example #2
0
static BOOL LoadTable(HDC hdc, OTTable *table)
{
    unsigned int i;

    if(table->MS_tag == MS_MAKE_TAG('g','d','i','r')) return TRUE;
    table->len = GetFontData(hdc, table->MS_tag, 0, NULL, 0);
    table->data = HeapAlloc(GetProcessHeap(), 0, (table->len + 3) & ~3 );
    memset(table->data + ((table->len - 1) & ~3), 0, sizeof(DWORD));
    GetFontData(hdc, table->MS_tag, 0, table->data, table->len);
    table->check = 0;
    for(i = 0; i < (table->len + 3) / 4; i++)
        table->check += FLIP_ORDER(*((DWORD*)(table->data) + i));
    return TRUE;
}
Example #3
0
static BOOL is_fake_italic( HDC hdc )
{
    TEXTMETRICW tm;
    BYTE head[54]; /* the head table is 54 bytes long */
    WORD mac_style;

    GetTextMetricsW( hdc, &tm );
    if (!tm.tmItalic) return FALSE;

    if (GetFontData( hdc, MS_MAKE_TAG('h','e','a','d'), 0, head, sizeof(head) ) == GDI_ERROR)
        return FALSE;

    mac_style = GET_BE_WORD( head + 44 );
    TRACE( "mac style %04x\n", mac_style );
    return !(mac_style & 2);
}
Example #4
0
/****************************************************************************
 *  get_bbox
 *
 * This retrieves the bounding box of the font in font units as well as
 * the size of the emsquare.  To avoid having to worry about mapping mode and
 * the font size we'll get the data directly from the TrueType HEAD table rather
 * than using GetOutlineTextMetrics.
 */
static BOOL get_bbox(PSDRV_PDEVICE *physDev, RECT *rc, UINT *emsize)
{
    BYTE head[54]; /* the head table is 54 bytes long */

    if(GetFontData(physDev->hdc, MS_MAKE_TAG('h','e','a','d'), 0, head,
                   sizeof(head)) == GDI_ERROR) {
        ERR("Can't retrieve head table\n");
        return FALSE;
    }
    *emsize = GET_BE_WORD(head + 18); /* unitsPerEm */
    rc->left = (signed short)GET_BE_WORD(head + 36); /* xMin */
    rc->bottom = (signed short)GET_BE_WORD(head + 38); /* yMin */
    rc->right = (signed short)GET_BE_WORD(head + 40); /* xMax */
    rc->top = (signed short)GET_BE_WORD(head + 42); /* yMax */
    return TRUE;
}
Example #5
0
/****************************************************************************
 *  get_bbox
 *
 * This retrieves the bounding box of the font in font units as well as
 * the size of the emsquare.  To avoid having to worry about mapping mode and
 * the font size we'll get the data directly from the TrueType HEAD table rather
 * than using GetOutlineTextMetrics.
 */
static UINT get_bbox(HDC hdc, RECT *rc)
{
    BYTE head[54]; /* the head table is 54 bytes long */

    if(GetFontData(hdc, MS_MAKE_TAG('h','e','a','d'), 0, head, sizeof(head)) == GDI_ERROR)
    {
        ERR("Can't retrieve head table\n");
        return 0;
    }
    if(rc)
    {
        rc->left   = (signed short)GET_BE_WORD(head + 36); /* xMin */
        rc->bottom = (signed short)GET_BE_WORD(head + 38); /* yMin */
        rc->right  = (signed short)GET_BE_WORD(head + 40); /* xMax */
        rc->top    = (signed short)GET_BE_WORD(head + 42); /* yMax */
    }
    return GET_BE_WORD(head + 18); /* unitsPerEm */
}
Example #6
0
TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, char *ps_name,
                            RECT *bbox, UINT emsize)
{
    DWORD i, j, tablepos, nb_blocks, glyf_off = 0, loca_off = 0, cur_off;
    WORD num_of_tables = sizeof(tables_templ) / sizeof(tables_templ[0]) - 1;
    char *buf;
    TYPE42 *t42;
    static const char start[] = /* name, fontbbox */
            "25 dict begin\n"
	    " /FontName /%s def\n"
	    " /Encoding 256 array 0 1 255{1 index exch /.notdef put} for\n"
	    " def\n"
	    " /PaintType 0 def\n"
	    " /FontMatrix [1 0 0 1 0 0] def\n"
	    " /FontBBox [%f %f %f %f] def\n"
	    " /FontType 42 def\n"
	    " /CharStrings 256 dict begin\n"
	    "  /.notdef 0 def\n"
            " currentdict end def\n"
	    " /sfnts [\n";
    static const char TT_offset_table[] = "<00010000%04x%04x%04x%04x\n";
    static const char TT_table_dir_entry[] = "%08x%08x%08x%08x\n";
    static const char storage[] ="]\nhavetype42gdir{pop}{{string} forall}ifelse\n";
    static const char end[] = "] def\n"
      "havetype42gdir{/GlyphDirectory 256 dict def\n"
      " sfnts 0 get dup\n"
      "  %d <6c6f6378000000000000000000000000> putinterval\n" /* replace loca entry with dummy locx */
      "  %d <676c6678000000000000000000000000> putinterval\n" /* replace glyf entry with dummy glfx */
      " }if\n"
      "currentdict end dup /FontName get exch definefont pop\n";


    t42 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*t42));
    memcpy(t42->tables, tables_templ, sizeof(tables_templ));
    t42->loca_tab = t42->glyf_tab = t42->head_tab = t42->hmtx_tab = -1;
    t42->emsize = emsize;
    t42->num_of_written_tables = 0;

    for(i = 0; i < num_of_tables; i++) {
        LoadTable(physDev->hdc, t42->tables + i);
	if(t42->tables[i].len > 0xffff && t42->tables[i].write) break;
	if(t42->tables[i].write) t42->num_of_written_tables++;
	if(t42->tables[i].MS_tag == MS_MAKE_TAG('l','o','c','a'))
	    t42->loca_tab = i;
	else if(t42->tables[i].MS_tag == MS_MAKE_TAG('g','l','y','f'))
	    t42->glyf_tab = i;
	else if(t42->tables[i].MS_tag == MS_MAKE_TAG('h','e','a','d'))
	    t42->head_tab = i;
	else if(t42->tables[i].MS_tag == MS_MAKE_TAG('h','m','t','x'))
	    t42->hmtx_tab = i;
	else if(t42->tables[i].MS_tag == MS_MAKE_TAG('m','a','x','p'))
	    t42->maxp_tab = i;
    }
    if(i < num_of_tables) {
        TRACE("Table %d has length %d.  Will use Type 1 font instead.\n", i, t42->tables[i].len);
        T42_free(t42);
	return NULL;
    }

    t42->glyph_sent_size = GLYPH_SENT_INC;
    t42->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
				t42->glyph_sent_size *
				sizeof(*(t42->glyph_sent)));

    buf = HeapAlloc(GetProcessHeap(), 0, sizeof(start) + strlen(ps_name) +
		    100);

    push_lc_numeric("C");
    sprintf(buf, start, ps_name,
	    (float)bbox->left / emsize, (float)bbox->bottom / emsize,
	    (float)bbox->right / emsize, (float)bbox->top / emsize);
    pop_lc_numeric();

    PSDRV_WriteSpool(physDev, buf, strlen(buf));

    t42->num_of_written_tables++; /* explicitly add glyf */
    sprintf(buf, TT_offset_table, t42->num_of_written_tables,
	    t42->num_of_written_tables, t42->num_of_written_tables, t42->num_of_written_tables);

    PSDRV_WriteSpool(physDev, buf, strlen(buf));

    tablepos = 12 + t42->num_of_written_tables * 16;
    cur_off = 12;
    for(i = 0; i < num_of_tables; i++) {
        if(!t42->tables[i].write) continue;
        sprintf(buf, TT_table_dir_entry, FLIP_ORDER(t42->tables[i].MS_tag),
		t42->tables[i].check, t42->tables[i].len ? tablepos : 0,
		t42->tables[i].len);
	PSDRV_WriteSpool(physDev, buf, strlen(buf));
	tablepos += ((t42->tables[i].len + 3) & ~3);
        if(t42->tables[i].MS_tag == MS_MAKE_TAG('l','o','c','a'))
            loca_off = cur_off;
        cur_off += 16;
    }
    sprintf(buf, TT_table_dir_entry, FLIP_ORDER(t42->tables[t42->glyf_tab].MS_tag),
            t42->tables[t42->glyf_tab].check, tablepos, t42->tables[t42->glyf_tab].len);
    PSDRV_WriteSpool(physDev, buf, strlen(buf));
    PSDRV_WriteSpool(physDev, "00>\n", 4); /* add an extra byte for old PostScript rips */
    glyf_off = cur_off;

    for(i = 0; i < num_of_tables; i++) {
        if(t42->tables[i].len == 0 || !t42->tables[i].write) continue;
	PSDRV_WriteSpool(physDev, "<", 1);
	for(j = 0; j < ((t42->tables[i].len + 3) & ~3); j++) {
	    sprintf(buf, "%02x", t42->tables[i].data[j]);
	    PSDRV_WriteSpool(physDev, buf, strlen(buf));
	    if(j % 16 == 15) PSDRV_WriteSpool(physDev, "\n", 1);
	}
	PSDRV_WriteSpool(physDev, "00>\n", 4); /* add an extra byte for old PostScript rips */
    }
    
    /* glyf_blocks is a 0 terminated list, holding the start offset of each block.  For simplicity
       glyf_blocks[0] is 0 */
    nb_blocks = 2;
    t42->glyf_blocks = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nb_blocks + 1) * sizeof(DWORD));
    for(i = 0; i < GET_BE_WORD(t42->tables[t42->maxp_tab].data + 4); i++) {
        DWORD start, end, size;
        get_glyf_pos(t42, i, &start, &end);
        size = end - t42->glyf_blocks[nb_blocks-2];
        if(size > 0x2000 && t42->glyf_blocks[nb_blocks-1] % 4 == 0) {
            nb_blocks++;
            t42->glyf_blocks = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                           t42->glyf_blocks, (nb_blocks + 1) * sizeof(DWORD));
        }
        t42->glyf_blocks[nb_blocks-1] = end;
    }

    PSDRV_WriteSpool(physDev, "[ ", 2);
    for(i = 1; t42->glyf_blocks[i]; i++) {
        sprintf(buf,"%d ", t42->glyf_blocks[i] - t42->glyf_blocks[i-1] + 1);
        /* again add one byte for old PostScript rips */
        PSDRV_WriteSpool(physDev, buf, strlen(buf));
        if(i % 8 == 0)
            PSDRV_WriteSpool(physDev, "\n", 1);
    }
    PSDRV_WriteSpool(physDev, storage, sizeof(storage) - 1);
    sprintf(buf, end, loca_off, glyf_off);
    PSDRV_WriteSpool(physDev, buf, strlen(buf));
    HeapFree(GetProcessHeap(), 0, buf);
    return t42;
}
Example #7
0
#define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
          ( ( (DWORD)_x4 << 24 ) |     \
            ( (DWORD)_x3 << 16 ) |     \
            ( (DWORD)_x2 <<  8 ) |     \
              (DWORD)_x1         )

typedef struct {
  DWORD MS_tag;
  DWORD len, check;
  BYTE *data;
  BOOL write;
} OTTable;

static const OTTable tables_templ[] = {
      { MS_MAKE_TAG('c','v','t',' '), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('f','p','g','m'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('g','d','i','r'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('g','l','y','f'), 0, 0, NULL, FALSE },
      { MS_MAKE_TAG('h','e','a','d'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('h','h','e','a'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('h','m','t','x'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('l','o','c','a'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('m','a','x','p'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('p','r','e','p'), 0, 0, NULL, TRUE },
      { 0, 0, 0, NULL, 0 }
};

struct tagTYPE42 {
    OTTable tables[sizeof(tables_templ)/sizeof(tables_templ[0])];
    int glyf_tab, loca_tab, head_tab; /* indices of glyf, loca and head tables */
Example #8
0
File: download.c Project: bpon/wine
/****************************************************************************
 *  get_download_name
 */
static void get_download_name(PHYSDEV dev, LPOUTLINETEXTMETRICA potm, char **str)
{
    int len;
    char *p;
    DWORD size;

    size = GetFontData(dev->hdc, MS_MAKE_TAG('n','a','m','e'), 0, NULL, 0);
    if(size != 0 && size != GDI_ERROR)
    {
        BYTE *name = HeapAlloc(GetProcessHeap(), 0, size);
        if(name)
        {
            USHORT count, i;
            BYTE *strings;
            struct
            {
                USHORT platform_id;
                USHORT encoding_id;
                USHORT language_id;
                USHORT name_id;
                USHORT length;
                USHORT offset;
            } *name_record;

            GetFontData(dev->hdc, MS_MAKE_TAG('n','a','m','e'), 0, name, size);
            count = GET_BE_WORD(name + 2);
            strings = name + GET_BE_WORD(name + 4);
            name_record = (typeof(name_record))(name + 6);
            for(i = 0; i < count; i++, name_record++)
            {
                name_record->platform_id = GET_BE_WORD(&name_record->platform_id);
                name_record->encoding_id = GET_BE_WORD(&name_record->encoding_id);
                name_record->language_id = GET_BE_WORD(&name_record->language_id);
                name_record->name_id     = GET_BE_WORD(&name_record->name_id);
                name_record->length      = GET_BE_WORD(&name_record->length);
                name_record->offset      = GET_BE_WORD(&name_record->offset);

                if(name_record->platform_id == 1 && name_record->encoding_id == 0 &&
                   name_record->language_id == 0 && name_record->name_id == 6)
                {
                    TRACE("Got Mac PS name %s\n", debugstr_an((char*)strings + name_record->offset, name_record->length));
                    *str = HeapAlloc(GetProcessHeap(), 0, name_record->length + 1);
                    memcpy(*str, strings + name_record->offset, name_record->length);
                    *(*str + name_record->length) = '\0';
                    HeapFree(GetProcessHeap(), 0, name);
                    return;
                }
                if(name_record->platform_id == 3 && name_record->encoding_id == 1 &&
                   name_record->language_id == 0x409 && name_record->name_id == 6)
                {
                    WCHAR *unicode = HeapAlloc(GetProcessHeap(), 0, name_record->length + 2);
                    DWORD len;
                    int c;

                    for(c = 0; c < name_record->length / 2; c++)
                        unicode[c] = GET_BE_WORD(strings + name_record->offset + c * 2);
                    unicode[c] = 0;
                    TRACE("Got Windows PS name %s\n", debugstr_w(unicode));
                    len = WideCharToMultiByte(1252, 0, unicode, -1, NULL, 0, NULL, NULL);
                    *str = HeapAlloc(GetProcessHeap(), 0, len);
                    WideCharToMultiByte(1252, 0, unicode, -1, *str, len, NULL, NULL);
                    HeapFree(GetProcessHeap(), 0, unicode);
                    HeapFree(GetProcessHeap(), 0, name);
                    return;
                }
            }
            TRACE("Unable to find PostScript name\n");
            HeapFree(GetProcessHeap(), 0, name);
        }
    }

    len = strlen((char*)potm + (ptrdiff_t)potm->otmpFullName) + 1;
    *str = HeapAlloc(GetProcessHeap(),0,len);
    strcpy(*str, (char*)potm + (ptrdiff_t)potm->otmpFullName);

    p = *str;
    while((p = strchr(p, ' ')))
        *p = '_';

    return;
}