Пример #1
0
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);
}
Пример #2
0
bool GDI2FT_OS2_METRICS::init( HDC hdc )
/* --------------------------------------------------------------------------------
-------------------------------------------------------------------------------- */
{
	DWORD font_data_size;

	font_data_size = GetFontData( hdc, OS2_TABLE_TAG, offsetof( TT_OS2, xAvgCharWidth ), &_xAvgCharWidth, sizeof( _xAvgCharWidth ) );
	if( font_data_size == GDI_ERROR )
		return false;

	font_data_size = GetFontData( hdc, OS2_TABLE_TAG, offsetof( TT_OS2, usWeightClass ), &_usWeightClass, sizeof( _usWeightClass ) );
	if( font_data_size == GDI_ERROR )
		return false;

	font_data_size = GetFontData( hdc, OS2_TABLE_TAG, offsetof( TT_OS2, usWidthClass ), &_usWidthClass, sizeof( _usWidthClass ) );
	if( font_data_size == GDI_ERROR )
		return false;

	font_data_size = GetFontData( hdc, OS2_TABLE_TAG, offsetof( TT_OS2, fsSelection ), &_fsSelection, sizeof( _fsSelection ) );
	if( font_data_size == GDI_ERROR )
		return false;
	
	_xAvgCharWidth = SWAPWORD( _xAvgCharWidth );
	_usWeightClass = SWAPWORD( _usWeightClass );
	_usWidthClass = SWAPWORD( _usWidthClass );
	_fsSelection = SWAPWORD( _fsSelection );

	return true;
}
Пример #3
0
static bool GetDataFromHFONT( HFONT hf, char** outFontBuffer, unsigned int& outFontBufferLen )
{
    HDC		hdc;

    if ( ( hdc = GetDC(0) ) == NULL ) {
        DeleteObject(hf);
        return false;
    }
    
    SelectObject(hdc, hf);

    outFontBufferLen = GetFontData(hdc, 0, 0, 0, 0);
    
    if (outFontBufferLen == GDI_ERROR) {
        ReleaseDC(0, hdc);
        DeleteObject(hf);
        return false;
    }
    
    *outFontBuffer = (char *) malloc( outFontBufferLen );
    
    if ( GetFontData( hdc, 0, 0, *outFontBuffer, (DWORD) outFontBufferLen ) == GDI_ERROR ) {
        free( *outFontBuffer );
        *outFontBuffer = NULL;
        outFontBufferLen = 0;
        ReleaseDC(0, hdc);
        DeleteObject(hf);
        return false;
    }
    
    ReleaseDC( 0, hdc );
    DeleteObject( hf );
    
    return true;
}
Пример #4
0
bool os2_metrics::init(HDC hdc)
{
	// retrieve needed fields from the OS/2 table

	DWORD font_data_size;

	font_data_size = GetFontData(hdc, OS2_TABLE_TAG, offsetof(TT_OS2, xAvgCharWidth), &_xAvgCharWidth, sizeof(_xAvgCharWidth));
	if (font_data_size == GDI_ERROR)
		return false;

	font_data_size = GetFontData(hdc, OS2_TABLE_TAG, offsetof(TT_OS2, usWeightClass), &_usWeightClass, sizeof(_usWeightClass));
	if (font_data_size == GDI_ERROR)
		return false;

	font_data_size = GetFontData(hdc, OS2_TABLE_TAG, offsetof(TT_OS2, usWidthClass), &_usWidthClass, sizeof(_usWidthClass));
	if (font_data_size == GDI_ERROR)
		return false;

	font_data_size = GetFontData(hdc, OS2_TABLE_TAG, offsetof(TT_OS2, fsSelection), &_fsSelection, sizeof(_fsSelection));
	if (font_data_size == GDI_ERROR)
		return false;

	_xAvgCharWidth = SWAPWORD(_xAvgCharWidth);
	_usWeightClass = SWAPWORD(_usWeightClass);
	_usWidthClass = SWAPWORD(_usWidthClass);
	_fsSelection = SWAPWORD(_fsSelection);

	return true;
}
Пример #5
0
static VOID *load_gsub_table(HDC hdc)
{
    VOID* GSUB_Table = NULL;
    int length = GetFontData(hdc, GSUB_TAG , 0, NULL, 0);
    if (length != GDI_ERROR)
    {
        GSUB_Table = HeapAlloc(GetProcessHeap(),0,length);
        GetFontData(hdc, GSUB_TAG , 0, GSUB_Table, length);
        TRACE("Loaded GSUB table of %i bytes\n",length);
    }
    return GSUB_Table;
}
Пример #6
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;
}
Пример #7
0
static BOOL get_font_metrics(HDC hdc, struct font_metrics *fm)
{
    OUTLINETEXTMETRICW otm;
    TT_OS2_V2 tt_os2;
    TT_HHEA tt_hori;
    LONG size;
    UINT16 line_gap;

    otm.otmSize = sizeof(otm);
    if (!GetOutlineTextMetricsW(hdc, otm.otmSize, &otm)) return FALSE;

    fm->em_height = otm.otmEMSquare;
    fm->dpi = GetDeviceCaps(hdc, LOGPIXELSY);

    memset(&tt_hori, 0, sizeof(tt_hori));
    if (GetFontData(hdc, MS_HHEA_TAG, 0, &tt_hori, sizeof(tt_hori)) != GDI_ERROR)
    {
        fm->ascent = GET_BE_WORD(tt_hori.Ascender);
        fm->descent = -GET_BE_WORD(tt_hori.Descender);
        TRACE("hhea: ascent %d, descent %d\n", fm->ascent, fm->descent);
        line_gap = GET_BE_WORD(tt_hori.LineGap);
        fm->line_spacing = fm->ascent + fm->descent + line_gap;
        TRACE("line_gap %u, line_spacing %u\n", line_gap, fm->line_spacing);
        if (fm->ascent + fm->descent != 0) return TRUE;
    }

    size = GetFontData(hdc, MS_OS2_TAG, 0, NULL, 0);
    if (size == GDI_ERROR) return FALSE;

    if (size > sizeof(tt_os2)) size = sizeof(tt_os2);

    memset(&tt_os2, 0, sizeof(tt_os2));
    if (GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size) != size) return FALSE;

    fm->ascent = GET_BE_WORD(tt_os2.usWinAscent);
    fm->descent = GET_BE_WORD(tt_os2.usWinDescent);
    TRACE("usWinAscent %u, usWinDescent %u\n", fm->ascent, fm->descent);
    if (fm->ascent + fm->descent == 0)
    {
        fm->ascent = GET_BE_WORD(tt_os2.sTypoAscender);
        fm->descent = GET_BE_WORD(tt_os2.sTypoDescender);
        TRACE("sTypoAscender %u, sTypoDescender %u\n", fm->ascent, fm->descent);
    }
    line_gap = GET_BE_WORD(tt_os2.sTypoLineGap);
    fm->line_spacing = fm->ascent + fm->descent + line_gap;
    TRACE("line_gap %u, line_spacing %u\n", line_gap, fm->line_spacing);
    return TRUE;
}
Пример #8
0
PassRefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
{
    HWndDC hdc(0);
    HGDIOBJ oldFont = SelectObject(hdc, hfont());

    DWORD size = GetFontData(hdc, table, 0, 0, 0);
    RefPtr<SharedBuffer> buffer;
    if (size != GDI_ERROR) {
        buffer = SharedBuffer::create(size);
        DWORD result = GetFontData(hdc, table, 0, (PVOID)buffer->data(), size);
        ASSERT(result == size);
    }

    SelectObject(hdc, oldFont);
    return buffer.release();
}
Пример #9
0
static QString getEnglishName(const QString &familyName)
{
    QString i18n_name;

    HDC hdc = GetDC( 0 );
    LOGFONT lf;
    memset(&lf, 0, sizeof(LOGFONT));
    memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t));
    lf.lfCharSet = DEFAULT_CHARSET;
    HFONT hfont = CreateFontIndirect(&lf);

    if(!hfont) {
        ReleaseDC(0, hdc);
        return QString();
    }

    HGDIOBJ oldobj = SelectObject( hdc, hfont );

    const DWORD name_tag = MAKE_TAG( 'n', 'a', 'm', 'e' );

    // get the name table
    unsigned char *table = 0;

    DWORD bytes = GetFontData( hdc, name_tag, 0, 0, 0 );
    if ( bytes == GDI_ERROR ) {
        // ### Unused variable
        /* int err = GetLastError(); */
        goto error;
    }

    table = new unsigned char[bytes];
    GetFontData(hdc, name_tag, 0, table, bytes);
    if ( bytes == GDI_ERROR )
        goto error;

    i18n_name = getEnglishName(table, bytes);
error:
    delete [] table;
    SelectObject( hdc, oldobj );
    DeleteObject( hfont );
    ReleaseDC( 0, hdc );

    //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data());
    return i18n_name;
}
Пример #10
0
String GetFontDataSys(Font font)
{
	String r;
	HFONT hfont = GetWin32Font(font, 0);
	if(hfont) {
		HDC hdc = Win32_IC();
		HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
		DWORD size = GetFontData(hdc, 0, 0, NULL, 0);
		if(size == GDI_ERROR) {
			LLOG("PdfDraw::Finish: GDI_ERROR on font " << pdffont.GetKey(i));
			return Null;
		}
		StringBuffer b(size);
		GetFontData(hdc, 0, 0, b, size);
		::SelectObject(hdc, ohfont);
		r = b;
	}
	return r;
}
Пример #11
0
/* [fault_status][comm_status] */ error_status_t gdipp_rpc_get_font_size( 
	/* [in] */ handle_t h_gdipp_rpc,
	/* [context_handle_noserialize][in] */ GDIPP_RPC_SESSION_HANDLE h_session,
	/* [in] */ unsigned long table,
	/* [in] */ unsigned long offset,
	/* [out] */ unsigned long *font_size)
{
	const gdipp::rpc_session *curr_session = reinterpret_cast<const gdipp::rpc_session *>(h_session);
	*font_size = GetFontData(curr_session->font_holder, table, offset, NULL, 0);

	return RPC_S_OK;
}
Пример #12
0
	//------------------------------------------------------------------------------
	void IGUIFont_ft2::DrawString(IGUIInterfaceRender* pRender, 
		const CGUIStringRender& rString, 
		const CGUIVector2& rPos,
		real fAlpha,
		int32 nStartPos,
		int32 nEndPos)
	{
		if( rString.m_strContent.empty())
		{
			//empty string
			return;
		}

		CGUIVector2 aPos = rPos;

		if( nEndPos<0 || nEndPos>int32(rString.m_strContent.size()))
		{
			nEndPos = rString.m_strContent.size();
		}

		const CGUIStringRenderInfo& rInfo = rString.m_aStringInfo;
		CGUIFontData_ft2* pFontData = GetFontData( rInfo.m_uFontID );

		for( int32 i=nStartPos; i<nEndPos; ++i)
		{
			SCharData_ft2 * pCharData = pFontData->GetCharData( rString.m_strContent[i] );

			if( pCharData->m_pTexture)
			{
				CGUIRect aCharRect(
					CGUIVector2(aPos.x+pCharData->m_fBearingX*rInfo.m_fFontScale, aPos.y-pCharData->m_fBearingY*rInfo.m_fFontScale),
					CGUISize(pCharData->m_fBitmapWidth*rInfo.m_fFontScale,pCharData->m_fBitmapHeight*rInfo.m_fFontScale));

				//dest area size
				CGUIColor aColor(rInfo.m_aColor);
				aColor.SetAlpha(aColor.GetAlpha()*fAlpha);
				pRender->DrawTile( 
					aCharRect,
					0, 
					pCharData->m_pTexture,
					pCharData->m_aUV, 
					eImageOrientation_Normal,
					aColor,
					aColor,
					aColor,
					aColor);
			}

			aPos.x+=pCharData->m_aSize.m_fWidth*rInfo.m_fFontScale;
		}
	}
Пример #13
0
bool os2_metrics::init(void *font_id)
{
	// retrieve needed fields from the OS/2 table

	DWORD font_data_size;

	const HDC font_holder = dc_pool_instance.claim();
	assert(font_holder != NULL);
	font_mgr_instance.select_font(font_id, font_holder);

	font_data_size = GetFontData(font_holder, OS2_TABLE_TAG, offsetof(TT_OS2, xAvgCharWidth), reinterpret_cast<byte *>(&_xAvgCharWidth), sizeof(_xAvgCharWidth));
	if (font_data_size == GDI_ERROR)
		goto failed_init_os2_metrics;

	font_data_size = GetFontData(font_holder, OS2_TABLE_TAG, offsetof(TT_OS2, usWeightClass), reinterpret_cast<byte *>(&_usWeightClass), sizeof(_usWeightClass));
	if (font_data_size == GDI_ERROR)
		goto failed_init_os2_metrics;

	font_data_size = GetFontData(font_holder, OS2_TABLE_TAG, offsetof(TT_OS2, usWidthClass), reinterpret_cast<byte *>(&_usWidthClass), sizeof(_usWidthClass));
	if (font_data_size == GDI_ERROR)
		goto failed_init_os2_metrics;

	font_data_size = GetFontData(font_holder, OS2_TABLE_TAG, offsetof(TT_OS2, fsSelection), reinterpret_cast<byte *>(&_fsSelection), sizeof(_fsSelection));
	if (font_data_size == GDI_ERROR)
		goto failed_init_os2_metrics;

	_xAvgCharWidth = SWAPWORD(_xAvgCharWidth);
	_usWeightClass = SWAPWORD(_usWeightClass);
	_usWidthClass = SWAPWORD(_usWidthClass);
	_fsSelection = SWAPWORD(_fsSelection);

	return true;

failed_init_os2_metrics:
	dc_pool_instance.free(font_holder);
	return false;
}
Пример #14
0
/* [fault_status][comm_status] */ error_status_t gdipp_rpc_get_font_data( 
	/* [in] */ handle_t h_gdipp_rpc,
	/* [context_handle_noserialize][in] */ GDIPP_RPC_SESSION_HANDLE h_session,
	/* [in] */ unsigned long table,
	/* [in] */ unsigned long offset,
	/* [size_is][out] */ byte *data_buf,
	/* [in] */ unsigned long buf_size)
{
	const gdipp::rpc_session *curr_session = reinterpret_cast<const gdipp::rpc_session *>(h_session);

	// TODO: output pointer is not allocated with MIDL_user_allocate
	// TODO: return value not returned
	GetFontData(curr_session->font_holder, table, offset, data_buf, buf_size);

	return RPC_S_OK;
}
Пример #15
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);
}
Пример #16
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;
}
Пример #17
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 */
}
Пример #18
0
/**
 * FreeType 用 ストリーム読み込み関数
 * @param stream	FT_Streamへのポインタ
 * @param offset	ストリーム先頭からのオフセット
 * @param buffer	格納先バッファ
 * @param count		読み出すバイト数
 * @return	何バイト読み込まれたか
 */
unsigned long tNativeFreeTypeFace::IoFunc(
    FT_Stream stream,
    unsigned long   offset,
    unsigned char*  buffer,
    unsigned long   count )
{
    if(count != 0)
    {
        tNativeFreeTypeFace * _this =
            static_cast<tNativeFreeTypeFace*>(stream->descriptor.pointer);
        DWORD result = GetFontData(_this->DC,
                                   _this->IsTTC ? TVP_TT_TABLE_ttcf : 0,
                                   offset, buffer, count);
        if(result == GDI_ERROR)
        {
            // エラー
            return 0;
        }
        return result;
    }
    return 0;
}
Пример #19
0
	//------------------------------------------------------------------------------
	CGUISize IGUIFont_ft2::GetCharacterSize( wchar charCode, const CGUIStringRenderInfo& rInfo )
	{
		CGUIFontData_ft2* pFontData = GetFontData( rInfo.m_uFontID );
		SCharData_ft2 * pCharData = pFontData->GetCharData( charCode );
		return pCharData->m_aSize * rInfo.m_fFontScale;
	}
Пример #20
0
bool FreeTypeSysFontData::Init(LPCTSTR name, int weight, bool italic)
{
	const CGdippSettings* pSettings = CGdippSettings::GetInstance();
	void* pNameFromGDI		= NULL; // Windows 偐傜庢摼偟偨 name 僞僌偺撪梕
	void* pNameFromFreeType	= NULL; // FreeType 偐傜庢摼偟偨 name 僞僌偺撪梕
	HFONT hf = NULL;
	DWORD cbNameTable;
	DWORD cbFontData;
	int index;
	DWORD buf;
	FT_StreamRec& fsr = m_ftStream;
	m_name.assign(name);
	m_hdc = CreateCompatibleDC(NULL);
	if(m_hdc == NULL) {
		return false;
	}
	// 柤慜埲奜揔摉
	if (pSettings->FontSubstitutes() < SETTING_FONTSUBSTITUTE_ALL)
	{
		hf = CreateFont(
					12, 0, 0, 0, weight,
					italic, FALSE, FALSE,
					DEFAULT_CHARSET,
					OUT_DEFAULT_PRECIS,
					FONT_MAGIC_NUMBER,
					DEFAULT_QUALITY,
					DEFAULT_PITCH | FF_DONTCARE,
					name);
	}
	else
		hf = CreateFont(
					12, 0, 0, 0, weight,
					italic, FALSE, FALSE,
					DEFAULT_CHARSET,
					OUT_DEFAULT_PRECIS,
					CLIP_DEFAULT_PRECIS,
					DEFAULT_QUALITY,
					DEFAULT_PITCH | FF_DONTCARE,
					name);

	if(hf == NULL){
		return false;
	}

	m_hOldFont = SelectFont(m_hdc, hf);
	// 僼僅儞僩僨乕僞偑摼傜傟偦偆偐僠僃僢僋
	cbNameTable = ::GetFontData(m_hdc, TVP_TT_TABLE_name, 0, NULL, 0);
	if(cbNameTable == GDI_ERROR){
		goto ERROR_Init;
	}

	pNameFromGDI		= malloc(cbNameTable);
	if (!pNameFromGDI) {
		goto ERROR_Init;
	}
	pNameFromFreeType	= malloc(cbNameTable);
	if (!pNameFromFreeType) {
		goto ERROR_Init;
	}

	//- name 僞僌偺撪梕傪儊儌儕偵撉傒崬傓
	if(GetFontData(m_hdc, TVP_TT_TABLE_name, 0, pNameFromGDI, cbNameTable) == GDI_ERROR){
		goto ERROR_Init;
	}

	// 僼僅儞僩僒僀僘庢摼張棟
	cbFontData = ::GetFontData(m_hdc, TVP_TT_TABLE_ttcf, 0, &buf, 1);
	if(cbFontData == 1){
		// TTC 僼傽僀儖偩偲巚傢傟傞
		cbFontData = ::GetFontData(m_hdc, TVP_TT_TABLE_ttcf, 0, NULL, 0);
		m_isTTC = true;
	}
	else{
		cbFontData = ::GetFontData(m_hdc, 0, 0, NULL, 0);
	}
	if(cbFontData == GDI_ERROR){
		// 僄儔乕; GetFontData 偱偼埖偊側偐偭偨
		goto ERROR_Init;
	}

	if (pSettings->UseMapping()) {
		HANDLE hmap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT | SEC_NOCACHE, 0, cbFontData, NULL);
		if (!hmap) {
			goto ERROR_Init;
		}
		m_pMapping = MapViewOfFile(hmap, FILE_MAP_ALL_ACCESS, 0, 0, cbFontData);
		m_dwSize = cbFontData;
		CloseHandle(hmap);

		if (m_pMapping) {
			::GetFontData(m_hdc, m_isTTC ? TVP_TT_TABLE_ttcf : 0, 0, m_pMapping, cbFontData);
		}
	}

	// FT_StreamRec 偺奺僼傿乕儖僪傪杽傔傞
	fsr.base				= 0;
	fsr.size				= cbFontData;
	fsr.pos					= 0;
	fsr.descriptor.pointer	= this;
	fsr.pathname.pointer	= NULL;
	fsr.read				= IoFunc;
	fsr.close				= CloseFunc;

	index = 0;
	m_locked = true;
	if(!OpenFaceByIndex(index)){
		goto ERROR_Init;
	}

	for(;;) {
		// FreeType 偐傜丄name 僞僌偺僒僀僘傪庢摼偡傞
		FT_ULong length = 0;
		FT_Error err = FT_Load_Sfnt_Table(m_ftFace, TTAG_name, 0, NULL, &length);
		if(err){
			goto ERROR_Init;
		}

		// FreeType 偐傜摼偨 name 僞僌偺挿偝傪 Windows 偐傜摼偨挿偝偲斾妑
		if(length == cbNameTable){
			// FreeType 偐傜 name 僞僌傪庢摼
			err = FT_Load_Sfnt_Table(m_ftFace, TTAG_name, 0, (unsigned char*)pNameFromFreeType, &length);
			if(err){
				goto ERROR_Init;
			}
			// FreeType 偐傜撉傒崬傫偩 name 僞僌偺撪梕偲丄Windows 偐傜撉傒崬傫偩
			// name 僞僌偺撪梕傪斾妑偡傞丅
			// 堦抳偟偰偄傟偽偦偺 index 偺僼僅儞僩傪巊偆丅
			if(!memcmp(pNameFromGDI, pNameFromFreeType, cbNameTable)){
				// 堦抳偟偨
				// face 偼奐偄偨傑傑
				break; // 儖乕僾傪敳偗傞
			}
		}

		// 堦抳偟側偐偭偨
		// 僀儞僨僢僋僗傪堦偮憹傗偟丄偦偺 face 傪奐偔
		index ++;

		if(!OpenFaceByIndex(index)){
			// 堦抳偡傞 face 偑側偄傑傑 僀儞僨僢僋僗偑斖埻傪挻偊偨偲尒傜傟傞
			// index 傪 0 偵愝掕偟偰偦偺 index 傪奐偒丄儖乕僾傪敳偗傞
			index = 0;
			if(!OpenFaceByIndex(index)){
				goto ERROR_Init;
			}
			break;
		}
	}

	free(pNameFromGDI);
	free(pNameFromFreeType);
	m_locked = false;
	return true;

ERROR_Init:
	m_locked = false;
	if (hf) {
		SelectFont(m_hdc, m_hOldFont);
		DeleteFont(hf);
		m_hOldFont = NULL;
	}
	free(pNameFromGDI);
	free(pNameFromFreeType);
	return false;
}
Пример #21
0
	//------------------------------------------------------------------------------
	real IGUIFont_ft2::GetFontHeight( const CGUIStringRenderInfo& rInfo )
	{
		CGUIFontData_ft2* pFontData = GetFontData( rInfo.m_uFontID );
		return pFontData->GetFontSize() * rInfo.m_fFontScale;
	}
// Fills |length| glyphs starting at |offset| in a |page| in the Basic 
// Multilingual Plane (<= U+FFFF). The input buffer size should be the
// same as |length|. We can use the standard Windows GDI functions here. 
// Returns true if any glyphs were found.
static bool fillBMPGlyphs(unsigned offset,
                          unsigned length,
                          UChar* buffer,
                          GlyphPage* page,
                          const SimpleFontData* fontData,
                          bool recurse)
{
    HDC dc = GetDC((HWND)0);
    HGDIOBJ oldFont = SelectObject(dc, fontData->platformData().hfont());

    TEXTMETRIC tm = {0};
    if (!GetTextMetrics(dc, &tm)) {
        SelectObject(dc, oldFont);
        ReleaseDC(0, dc);

        if (recurse) {
            if (PlatformBridge::ensureFontLoaded(fontData->platformData().hfont()))
                return fillBMPGlyphs(offset, length, buffer, page, fontData, false);

            fillEmptyGlyphs(page);
            return false;
        } else {
            // FIXME: Handle gracefully the error if this call also fails.
            // See http://crbug.com/6401
            LOG_ERROR("Unable to get the text metrics after second attempt");
            fillEmptyGlyphs(page);
            return false;
        }
    }

    // FIXME: GetGlyphIndices() sets each item of localGlyphBuffer[]
    // with the one of the values listed below.
    //  * With the GGI_MARK_NONEXISTING_GLYPHS flag
    //    + If the font has a glyph available for the character,
    //      localGlyphBuffer[i] > 0x0.
    //    + If the font does not have glyphs available for the character,
    //      localGlyphBuffer[i] = 0x1F (TrueType Collection?) or
    //                            0xFFFF (OpenType?).
    //  * Without the GGI_MARK_NONEXISTING_GLYPHS flag
    //    + If the font has a glyph available for the character,
    //      localGlyphBuffer[i] > 0x0.
    //    + If the font does not have glyphs available for the character,
    //      localGlyphBuffer[i] = 0x80.
    //      (Windows automatically assigns the glyph for a box character to
    //      prevent ExtTextOut() from returning errors.)
    // To avoid from hurting the rendering performance, this code just
    // tells WebKit whether or not the all glyph indices for the given
    // characters are 0x80 (i.e. a possibly-invalid glyph) and let it
    // use alternative fonts for the characters.
    // Although this may cause a problem, it seems to work fine as far as I
    // have tested. (Obviously, I need more tests.)
    WORD localGlyphBuffer[GlyphPage::size];

    // FIXME: I find some Chinese characters can not be correctly displayed
    // when call GetGlyphIndices without flag GGI_MARK_NONEXISTING_GLYPHS,
    // because the corresponding glyph index is set as 0x20 when current font
    // does not have glyphs available for the character. According a blog post
    // http://blogs.msdn.com/michkap/archive/2006/06/28/649791.aspx
    // I think we should switch to the way about calling GetGlyphIndices with
    // flag GGI_MARK_NONEXISTING_GLYPHS, it should be OK according the
    // description of MSDN.
    // Also according to Jungshik and Hironori's suggestion and modification
    // we treat turetype and raster Font as different way when windows version
    // is less than Vista.
    GetGlyphIndices(dc, buffer, length, localGlyphBuffer, GGI_MARK_NONEXISTING_GLYPHS);

    // Copy the output to the GlyphPage
    bool haveGlyphs = false;
    int invalidGlyph = 0xFFFF;
    const DWORD cffTableTag = 0x20464643; // 4-byte identifier for OpenType CFF table ('CFF ').
    if (!isVistaOrNewer() && !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR))
        invalidGlyph = 0x1F;

    Glyph spaceGlyph = 0;  // Glyph for a space. Lazily filled.

    for (unsigned i = 0; i < length; i++) {
        UChar c = buffer[i];
        Glyph glyph = localGlyphBuffer[i];
        const SimpleFontData* glyphFontData = fontData;
        // When this character should be a space, we ignore whatever the font
        // says and use a space. Otherwise, if fonts don't map one of these
        // space or zero width glyphs, we will get a box.
        if (Font::treatAsSpace(c)) {
            // Hard code the glyph indices for characters that should be
            // treated like spaces.
            glyph = initSpaceGlyph(dc, &spaceGlyph);
        } else if (glyph == invalidGlyph) {
            // WebKit expects both the glyph index and FontData
            // pointer to be 0 if the glyph is not present
            glyph = 0;
            glyphFontData = 0;
        } else
            haveGlyphs = true;
        page->setGlyphDataForCharacter(offset + i, glyph, glyphFontData);
    }

    SelectObject(dc, oldFont);
    ReleaseDC(0, dc);
    return haveGlyphs;
}
Пример #23
0
	//------------------------------------------------------------------------------
	void IGUIFont_ft2::DrawString(IGUIInterfaceRender* pRender, 
		const CGUIStringRender& rString, 
		const CGUIRect&	rStringRect,
		ETextAlignmentHorz uTextAlignmentHorz,
		ETextAlignmentVert uTextAlignmentVert,
		real fAlpha,
		int32 nStartPos,
		int32 nEndPos)
	{
		if( rString.m_strContent.empty())
		{
			//empty string
			return;
		}

		const CGUIStringRenderInfo& rInfo = rString.m_aStringInfo;
		CGUIFontData_ft2* pFontData = GetFontData( rInfo.m_uFontID );
		real fScaledStringWidth = GetStringWidth(rString);
		real fScaledStringHeight = pFontData->GetFontSize() * rInfo.m_fFontScale;

		CGUIVector2 aPos;
		switch( uTextAlignmentHorz )
		{
		case eTextAlignment_Horz_Left:
			aPos.x = rStringRect.m_fLeft;
			break;
		case eTextAlignment_Horz_Right:
			aPos.x = rStringRect.m_fRight-fScaledStringWidth;
			break;
		case eTextAlignment_Horz_Center:
		default:
			aPos.x = floor(rStringRect.m_fLeft+(rStringRect.GetWidth()-fScaledStringWidth)/2);
			break;
		}

		switch( uTextAlignmentVert )
		{
		case eTextAlignment_Vert_Up:
			aPos.y = rStringRect.m_fTop;
			break;
		case eTextAlignment_Vert_Down:
			aPos.y = rStringRect.m_fBottom - fScaledStringHeight;
			break;
		case eTextAlignment_Vert_Center:
		default:
			aPos.y = ceil(rStringRect.m_fTop + (rStringRect.GetHeight() - fScaledStringHeight) / 2);
			break;
		}
		aPos.y += fScaledStringHeight;

		if( nEndPos < 0 || nEndPos >int32( rString.m_strContent.size()))
		{
			nEndPos = rString.m_strContent.size();
		}

		for( int32 i= nStartPos; i<nEndPos; ++i)
		{
			SCharData_ft2 * pCharData = pFontData->GetCharData( rString.m_strContent[i] );

			if( pCharData->m_pTexture)
			{
				CGUIRect aCharRect(
					CGUIVector2(aPos.x+pCharData->m_fBearingX*rInfo.m_fFontScale, aPos.y-pCharData->m_fBearingY*rInfo.m_fFontScale),
					CGUISize(pCharData->m_fBitmapWidth*rInfo.m_fFontScale,pCharData->m_fBitmapHeight*rInfo.m_fFontScale));

				//dest area size
				CGUIColor aColor(rInfo.m_aColor);
				aColor.SetAlpha(aColor.GetAlpha()*fAlpha);
				pRender->DrawTile( 
					aCharRect,
					0, 
					pCharData->m_pTexture,
					pCharData->m_aUV, 
					eImageOrientation_Normal,
					aColor,
					aColor,
					aColor,
					aColor);
			}

			aPos.x+=pCharData->m_aSize.m_fWidth*rInfo.m_fFontScale;
		}
	}
Пример #24
0
bool QWindowsFontEngine::hasCMapTable() const
{
    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);
    return GetFontData(hdc, MAKE_LITTLE_ENDIAN_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR;
}
Пример #25
0
BOOL bTestGFD (
    HDC     hdc
    )
{
    ULONG   row = 0;                    // screen row coordinate to print at
    HFONT   hfont;
    HFONT   hfontOriginal;
    LOGFONT lfnt;

    ULONG   cjBuffer;
    PBYTE   pjBuffer;

// Clear the screen to black.

    BitBlt(hdc, 0, 0, CX, CY, (HDC) 0, 0, 0, 0);

// Get a font.

    memset(&lfnt, 0, sizeof(lfnt));
    lstrcpy(lfnt.lfFaceName, "Lucida Blackletter");
    lfnt.lfHeight = 40;
    lfnt.lfWeight = 400;

    if ((hfont = CreateFontIndirect(&lfnt)) == NULL)
    {
        DbgPrint("ft!bTestGFD(): Logical font creation failed.\n");
        return FALSE;
    }

    hfontOriginal = SelectObject(hdc, hfont);

// Determine buffer size needed by GetFontData.

                                               // 'OS/2'
    if ( (cjBuffer = (ULONG) GetFontData(hdc, 0x4f532f32, 0, (PVOID) NULL, 0)) == (ULONG) -1 )
    {
        DbgPrint("ft!bTestGFD(): could not get buffer size from API\n");
        return FALSE;
    }

// Allocate memory.

    if ( (pjBuffer = (PBYTE) LocalAlloc(LPTR, cjBuffer)) == (PBYTE) NULL )
    {
        DbgPrint("ft!bTestGFD(): LocalAlloc(LPTR, 0x%lx) failed\n", cjBuffer);
        return FALSE;
    }

// Get the OS/2 table from TrueType.

    if ( GetFontData(hdc, 0x4f532f32, 0, (PVOID) pjBuffer, cjBuffer) == (DWORD) -1 )
    {
        LocalFree(pjBuffer);

        DbgPrint("ft!bTestGFD(): call to GetFontData failed\n");
        return FALSE;
    }

// Flush out batched calls.

    GdiFlush();

// Allow an opportunity to examine the contents.

    DbgPrint("ft!bTestGFD(): call to GetFontData succeeded\n");
    DbgPrint("\tOS/2 TrueType table is at 0x%lx, size is 0x%lx (%ld)\n", pjBuffer, cjBuffer, cjBuffer);
    DbgBreakPoint();

// Restore the font.

    SelectObject(hdc, hfontOriginal);
    DeleteObject(hfont);

// Free allocated memory.

    LocalFree(pjBuffer);

    return TRUE;
}
Пример #26
0
/**
 * Fonts can have localised names and when the system locale is the same as
 * one of those localised names Windows will always return that localised name
 * instead of allowing to get the non-localised (English US) name of the font.
 * This will later on give problems as freetype uses the non-localised name of
 * the font and we need to compare based on that name.
 * Windows furthermore DOES NOT have an API to get the non-localised name nor
 * can we override the system locale. This means that we have to actually read
 * the font itself to gather the font name we want.
 * Based on: http://blogs.msdn.com/michkap/archive/2006/02/13/530814.aspx
 * @param logfont the font information to get the english name of.
 * @return the English name (if it could be found).
 */
static const char *GetEnglishFontName(const ENUMLOGFONTEX *logfont)
{
	static char font_name[MAX_PATH];
	const char *ret_font_name = NULL;
	uint pos = 0;
	HDC dc;
	HGDIOBJ oldfont;
	byte *buf;
	DWORD dw;
	uint16 format, count, stringOffset, platformId, encodingId, languageId, nameId, length, offset;

	HFONT font = CreateFontIndirect(&logfont->elfLogFont);
	if (font == NULL) goto err1;

	dc = GetDC(NULL);
	oldfont = SelectObject(dc, font);
	dw = GetFontData(dc, 'eman', 0, NULL, 0);
	if (dw == GDI_ERROR) goto err2;

	buf = MallocT<byte>(dw);
	dw = GetFontData(dc, 'eman', 0, buf, dw);
	if (dw == GDI_ERROR) goto err3;

	format = buf[pos++] << 8;
	format += buf[pos++];
	assert(format == 0);
	count = buf[pos++] << 8;
	count += buf[pos++];
	stringOffset = buf[pos++] << 8;
	stringOffset += buf[pos++];
	for (uint i = 0; i < count; i++) {
		platformId = buf[pos++] << 8;
		platformId += buf[pos++];
		encodingId = buf[pos++] << 8;
		encodingId += buf[pos++];
		languageId = buf[pos++] << 8;
		languageId += buf[pos++];
		nameId = buf[pos++] << 8;
		nameId += buf[pos++];
		if (nameId != 1) {
			pos += 4; // skip length and offset
			continue;
		}
		length = buf[pos++] << 8;
		length += buf[pos++];
		offset = buf[pos++] << 8;
		offset += buf[pos++];

		/* Don't buffer overflow */
		length = min(length, MAX_PATH - 1);
		for (uint j = 0; j < length; j++) font_name[j] = buf[stringOffset + offset + j];
		font_name[length] = '\0';

		if ((platformId == 1 && languageId == 0) ||      // Macintosh English
				(platformId == 3 && languageId == 0x0409)) { // Microsoft English (US)
			ret_font_name = font_name;
			break;
		}
	}

err3:
	free(buf);
err2:
	SelectObject(dc, oldfont);
	ReleaseDC(NULL, dc);
	DeleteObject(font);
err1:
	return ret_font_name == NULL ? WIDE_TO_MB((const TCHAR*)logfont->elfFullName) : ret_font_name;
}
Пример #27
0
void GR_Win32CharWidths::_retrieveFontInfo(HDC hdc)
{
	// retrieve CMAP table for this font
	DWORD iTableSize = GetFontData(hdc, CMAP, 0, NULL, 0);
	char * buff = NULL, * p;
	UT_uint16 i, j, k;
	UT_uint16 iTCount;
	
	if(!iTableSize || iTableSize==GDI_ERROR)
		goto end_processing;
	
	buff = new char[iTableSize];
	if(!buff)
		goto end_processing;
	
	if(GDI_ERROR == GetFontData(hdc, CMAP, 0, (LPVOID)buff, iTableSize))
		goto end_processing;

	
	// now process the data in the table ...
	p = buff;
	UT_uint32 iOffset;
	UT_uint16 iFormat;
	
	iTCount = *((UT_uint16*)&buff[2]);
	DO_BE2LE(iTCount);
	
	p += 4;
	
	
	for(i = 0; i < iTCount; i++)
	{
		UT_uint16 iPlatform = *((UT_uint16*)p);
		DO_BE2LE(iPlatform);
		p += 2;

		UT_uint16 iId = *((UT_uint16*)p);
		DO_BE2LE(iId);
		p += 2;

		if(iPlatform == 3 && iId == 1)
		{
			iOffset = *((UT_uint32*)p);
			DO_BE2LE32(iOffset);

			p += 4;
			
			iFormat = *((UT_uint16*)(&buff[0]+iOffset));
			DO_BE2LE(iFormat);


			if(iFormat != 4)
			{
				continue;
			}

			p = &buff[0] + iOffset + 2;

			UT_uint16 iLength = *((UT_uint16*)p);
			DO_BE2LE(iLength);
			
			p += 4;

			UT_uint16 iSegCount = *((UT_uint16*)p);
			DO_BE2LE(iSegCount);
			iSegCount /= 2;

			p += 8;

			UT_uint16 * pEnd = (UT_uint16*)p;
			p += 2*iSegCount + 2;

			UT_uint16 * pStart = (UT_uint16*)p;
			p += 2*iSegCount;
			
			//UT_uint16 * pDelta = (UT_uint16*)p;
			p += 2*iSegCount;
			
			UT_uint16 * pRangeOffset = (UT_uint16*)p;
			p += 2*iSegCount;

			for(j = 0; j < iSegCount; j++)
			{
				DO_BE2LE(pRangeOffset[j]);
				DO_BE2LE(pStart[j]);
				DO_BE2LE(pEnd[j]);

				if(pRangeOffset[j] == 0)
				{
					m_vRanges.addItem(pStart[j]);
					m_vRanges.addItem(pEnd[j]);
				}
				else
				{
					UT_uint16 iStartChar = pStart[j];
					for(k = pStart[j]; k <= pEnd[j]; k++)
					{
						if(pStart[j] == 0xffff && pEnd[j] == 0xffff)
						{
							// pEnd[j] == 0xffff indicates the last
							// segment; according to the docs this
							// segment need not, but can, contain any
							// valid mappings, and the docs do
							// not. Presumably if the segement
							// contains more than on character there
							// are some valid mapings, if not, i.e.,
							// If pStart[j] == 0xffff, we will
							// assume that the mapping is not valid
							// Tomas, Oct 25, 2003
							break;
						}
						
						if(0 == *(pRangeOffset[j]/2 + (k - pStart[j]) + &pRangeOffset[j]))
						{
							// this character is not present, dump
							// everyting up to here
							if(k > iStartChar)
							{
								m_vRanges.addItem(iStartChar);
								m_vRanges.addItem(k-1);
							}
							iStartChar = k + 1;
						}
					}

					if(iStartChar <= k - 1)
					{
						// dump what is left over
						m_vRanges.addItem(iStartChar);
						m_vRanges.addItem(k-1);
					}
				}
			}
			// not interested in any further tables
		}
		else if(iPlatform == 3 && iId == 0)
		{
			// symbol font
			m_vRanges.addItem(0x20);
			m_vRanges.addItem(0x255);
		}
		else
		{
			// move past the offset long
			p += 4;
		}

	}

	// g_free the table data
	delete [] buff;

 end_processing:	
	// sanity check
	if(m_vRanges.getItemCount() == 0)
	{
		UT_DEBUGMSG(("GR_Win32CharWidths::_retrieveFontInfo: no ranges in font!!!\n"));
		// just assume everything is present
		m_vRanges.addItem(0);
		m_vRanges.addItem(0xffffffff);
	}
#ifdef DEBUG
	for(UT_sint32 n = 0; n < m_vRanges.getItemCount() - 1; n += 2)
	{
		xxx_UT_DEBUGMSG(("GR_Win32CharWidths::_retrieveFontInfo: range 0x%04x - 0x%04x\n",
					 m_vRanges.getNthItem(n), m_vRanges.getNthItem(n+1)));
	}
	
#endif
}
Пример #28
0
// This function creates a font resource for the given font name with the 
// embedding type set appropriately for the licensing intent of the font.
HRESULT
CreateFontResourceForFont(
    IXpsOMObjectFactory* xpsFactory,
    LPCWSTR fontName,
    IXpsOMFontResource **fontResource
    )
{
    HRESULT hr = S_OK;
    HDC hDC = NULL;
    LOGFONT logFont = {};
    HGDIOBJ hFont = NULL;
    ULONG privStatus = 0;
    LONG ttStatus;
    XPS_FONT_EMBEDDING embedding = XPS_FONT_EMBEDDING_NORMAL;
    DWORD fontDataLen = GDI_ERROR;
    HGLOBAL hGlobal = NULL;
    LPVOID ptr = NULL;
    IStream *fontStream = NULL;
    GUID fontObfuscationGuid = {};
    IOpcPartUri* partUri = NULL;
    wchar_t fontPartName[60];

    hDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
    if (!hDC)
    {
        fwprintf(stderr, L"ERROR: Could not create device context\n");
        hr = E_UNEXPECTED;
    }

    if (SUCCEEDED(hr))
    {
        if (wcscpy_s(logFont.lfFaceName, fontName) != 0)
        {
            fwprintf(stderr, L"ERROR: Could not copy font name into LOGFONT structure\n");
            hr = E_UNEXPECTED;
        }
    }

    if (SUCCEEDED(hr))
    {
        hFont = CreateFontIndirect(&logFont);
        if (!hFont)
        {
            fwprintf(stderr, L"ERROR: Could not create font\n");
            hr = E_UNEXPECTED;
        }
    }

    if (SUCCEEDED(hr))
    {
        if (!SelectObject(hDC, hFont))
        {
            fwprintf(stderr, L"ERROR: Could not select object\n");
            hr = E_UNEXPECTED;
        }
    }

    if (SUCCEEDED(hr))
    {
        if ((ttStatus = TTGetEmbeddingType(hDC, &privStatus)) != E_NONE)
        {
            if (ttStatus == E_NOTATRUETYPEFONT)
            {
                fwprintf(stderr, L"ERROR: %s is not a TrueType font\n", fontName);
            }
            else
            {
                fwprintf(stderr, L"ERROR: Could not get embedding type: %08X\n", ttStatus);
            }
            hr = E_UNEXPECTED;
        }
    }

    if (SUCCEEDED(hr))
    {
        switch (privStatus)
        {
            case EMBED_PREVIEWPRINT:
                // Restricted font
                embedding = XPS_FONT_EMBEDDING_RESTRICTED;
                break;
            case EMBED_EDITABLE:
                // Editable font - MUST obfuscate
                embedding = XPS_FONT_EMBEDDING_OBFUSCATED;
                break;
            case EMBED_INSTALLABLE:
                // Installable font - SHOULD obfuscate
                embedding = XPS_FONT_EMBEDDING_OBFUSCATED;
                break;
            case EMBED_NOEMBEDDING:
                fwprintf(stderr, L"ERROR: %s may not be embedded\n", fontName);
                hr = E_UNEXPECTED;
                break;
            default:
                fwprintf(stderr, L"ERROR: Unrecognized embedding privileges: %08X\n", privStatus);
                hr =  E_UNEXPECTED;
                break;
        }
    }

    if (SUCCEEDED(hr))
    {
        fontDataLen = GetFontData(hDC, 0, 0, NULL, 0);
        if (fontDataLen == GDI_ERROR)
        {
            fwprintf(stderr, L"ERROR: Could not get length of font data\n");
            hr = E_UNEXPECTED;
        }
    }

    if (SUCCEEDED(hr))
    {
        hGlobal = GlobalAlloc(GMEM_MOVEABLE, fontDataLen);
        if (!hGlobal)
        {
            fwprintf(stderr, L"ERROR: Could not allocate memory with GlobalAlloc\n");
            hr = E_OUTOFMEMORY;
        }
    }

    if (SUCCEEDED(hr))
    {
        ptr = GlobalLock(hGlobal);
        if (!ptr)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            fwprintf(stderr, L"ERROR: Could not lock global memory object: %08X\n", hr);
        }
        else
        {
            if (GetFontData(hDC, 0, 0, ptr, fontDataLen) == GDI_ERROR)
            {
                fwprintf(stderr, L"ERROR: Could not get font data\n");
                hr = E_UNEXPECTED;
            }

            GlobalUnlock(hGlobal);
        }
    }

    // Could perform font subsetting with CreateFontPackage here.

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = CreateStreamOnHGlobal(hGlobal, TRUE, &fontStream)))
        {
            fwprintf(stderr, L"ERROR: Could not create font stream: %08X\n", hr);
        }
        else
        {
            // If CreateStreamOnHGlobal succeeded, the stream now controls the lifetime of the
            // HGLOBAL.
            hGlobal = NULL;
        }
    }

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = CoCreateGuid(&fontObfuscationGuid)))
        {
            fwprintf(stderr, L"ERROR: Could not create GUID for obfuscation: %08X\n", hr);
        }
    }

    if (SUCCEEDED(hr))
    {
        if (swprintf_s(
                fontPartName,
                sizeof(fontPartName)/sizeof(wchar_t),
                L"/Resources/Fonts/%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X.odttf",
                fontObfuscationGuid.Data1,
                fontObfuscationGuid.Data2,
                fontObfuscationGuid.Data3,
                fontObfuscationGuid.Data4[0],
                fontObfuscationGuid.Data4[1],
                fontObfuscationGuid.Data4[2],
                fontObfuscationGuid.Data4[3],
                fontObfuscationGuid.Data4[4],
                fontObfuscationGuid.Data4[5],
                fontObfuscationGuid.Data4[6],
                fontObfuscationGuid.Data4[7]
                ) == -1)
        {
            fwprintf(stderr, L"ERROR: Could not format GUID into part name\n");
            hr = E_UNEXPECTED;
        }
    }

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = xpsFactory->CreatePartUri(
                    fontPartName,
                    &partUri)))
        {
            fwprintf(stderr, L"ERROR: Could not create part URI: %08X\n", hr);
        }
    }

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = xpsFactory->CreateFontResource(
                    fontStream,
                    embedding,
                    partUri,
                    FALSE,
                    fontResource
                    )))
        {
            fwprintf(stderr, L"ERROR: Could not create font resource: %08X\n", hr);
        }
    }

    if (fontStream)
    {
        fontStream->Release();
        fontStream = NULL;
    }

    if (partUri)
    {
        partUri->Release();
        partUri = NULL;
    }

    if (hGlobal)
    {
        GlobalFree(hGlobal);
    }

    if (hFont)
    {
        DeleteObject(hFont);
    }

    if (hDC)
    {
        DeleteDC(hDC);
    }

    return hr;
}
Пример #29
0
static CFStringRef getPostScriptName(CFStringRef faceName, HDC dc)
{
    const DWORD cMaxNameTableSize = 1024 * 1024;

    static HashMap<String, RetainPtr<CFStringRef> > nameMap;

    // Check our hash first.
    String faceString(faceName);
    RetainPtr<CFStringRef> result = nameMap.get(faceString);
    if (result)
        return result.get();

    // We need to obtain the PostScript name from the name table and use it instead,.
    DWORD bufferSize = GetFontData(dc, 'eman', 0, NULL, 0); // "name" backwards
    if (bufferSize == 0 || bufferSize == GDI_ERROR || bufferSize > cMaxNameTableSize)
        return NULL;

    Vector<BYTE> bufferVector(bufferSize);
    BYTE* buffer = bufferVector.data();
    if (GetFontData(dc, 'eman', 0, buffer, bufferSize) == GDI_ERROR)
        return NULL;

    if (bufferSize < 6)
        return NULL;

    USHORT numberOfRecords = readBigEndianWord(buffer + 2);
    UINT stringsOffset = readBigEndianWord(buffer + 4);
    if (bufferSize < stringsOffset)
        return NULL;

    BYTE* strings = buffer + stringsOffset;

    // Now walk each name record looking for a Mac or Windows PostScript name.
    UINT offset = 6;
    for (int i = 0; i < numberOfRecords; i++) {
        if (bufferSize < offset + 12)
            return NULL;

        USHORT platformID = readBigEndianWord(buffer + offset);
        USHORT encodingID = readBigEndianWord(buffer + offset + 2);
        USHORT languageID = readBigEndianWord(buffer + offset + 4);
        USHORT nameID = readBigEndianWord(buffer + offset + 6);
        USHORT length = readBigEndianWord(buffer + offset + 8);
        USHORT nameOffset = readBigEndianWord(buffer + offset + 10);

        if (platformID == 3 && encodingID == 1 && languageID == 0x409 && nameID == 6) {
            // This is a Windows PostScript name and is therefore UTF-16.
            // Pass Big Endian as the encoding.
            if (bufferSize < stringsOffset + nameOffset + length)
                return NULL;
            result = adoptCF(CFStringCreateWithBytes(NULL, strings + nameOffset, length, kCFStringEncodingUTF16BE, false));
            break;
        } else if (platformID == 1 && encodingID == 0 && languageID == 0 && nameID == 6) {
            // This is a Mac PostScript name and is therefore ASCII.
            // See http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
            if (bufferSize < stringsOffset + nameOffset + length)
                return NULL;
            result = adoptCF(CFStringCreateWithBytes(NULL, strings + nameOffset, length, kCFStringEncodingASCII, false));
            break;
        }

        offset += 12;
    }

    if (result)
        nameMap.set(faceString, result);
    return result.get();
}
Пример #30
0
/****************************************************************************
 *  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;
}