#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include "os.h"
#define USE_PSOUT_PRIVATE 1
#include "psout.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TYPE1_TABLES_H
#include <X11/Xproto.h>
#include <X11/fonts/font.h>
#include <X11/fonts/fontstruct.h>
#include <X11/fonts/fntfilst.h>
#include <X11/fonts/fontutil.h>
#include <X11/fonts/fontenc.h>
#include <X11/fonts/ft.h>
#define NOT_IN_FTFUNCS
#include <X11/fonts/ftfuncs.h>
#include "servermd.h"
#define USE_FT_PS_NAMES 1
#ifdef USE_FT_PS_NAMES
void PsOut_Get_FreeType_Glyph_Name( char *destbuf, FontPtr pFont, unsigned long x11fontindex)
{
FTFontPtr tf = (FTFontPtr)pFont->fontPrivate;
FT_Face ttface = tf->instance->face->face;
FT_Error error;
char buf[256];
unsigned long ftindex;
ftindex = FTRemap(ttface, &tf->mapping, x11fontindex);
if( FT_Has_PS_Glyph_Names(ttface) )
{
error = FT_Get_Glyph_Name(ttface, ftindex, buf, 64);
}
else
{
error = 1;
}
if( error )
{
if( (tf->mapping.mapping->type == FONT_ENCODING_UNICODE) &&
(ftindex < 0xFFFE) )
{
sprintf(buf, "uni%04lx", ftindex);
}
else
{
sprintf(buf, "ch%02lx", ftindex);
}
}
strcpy(destbuf, buf);
}
#endif
int PsOut_DownloadFreeType(PsOutPtr self, PsFTDownloadFontType downloadfonttype, const char *psfontname, FontPtr pFont, long block_offset)
{
switch(downloadfonttype)
{
case PsFontType3:
return PsOut_DownloadFreeType3(self, psfontname, pFont, block_offset);
case PsFontType1:
return PsOut_DownloadFreeType1(self, psfontname, pFont, block_offset);
default:
FatalError("PS DDX: PsOut_DownloadFreeType(downloadfonttype='%d' not implemented\n",
(int)downloadfonttype);
return 0;
}
}
void
PsOut_FreeType_TextAttrs16(PsOutPtr self, char *fnam, int siz, int iso)
{
int i;
if( self->FontName && strcmp(fnam, self->FontName)==0 &&
siz==self->FontSize ) return;
if( self->FontName ) xfree(self->FontName);
self->FontName = (char *)xalloc(strlen(fnam)+1);
strcpy(self->FontName, fnam);
self->FontSize = siz;
for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.;
}
void
PsOut_FreeType_TextAttrsMtx16(PsOutPtr self, char *fnam, float *mtx, int iso)
{
int i;
if( self->FontName && strcmp(fnam, self->FontName)==0 &&
mtx[0]==self->FontMtx[0] && mtx[1]==self->FontMtx[1] &&
mtx[2]==self->FontMtx[2] && mtx[3]==self->FontMtx[3] ) return;
if( self->FontName ) xfree(self->FontName);
self->FontName = (char *)xalloc(strlen(fnam)+1);
strcpy(self->FontName, fnam);
for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = mtx[i];
self->FontSize = -1;
}
static
int FT_Get_CharcellMetricsCharacterHeight(FontPtr pFont)
{
FTFontPtr ftfont = (FTFontPtr)pFont->fontPrivate;
return ftfont->instance->charcellMetrics->ascent +
ftfont->instance->charcellMetrics->descent;
}
static
int FT_Get_CharcellMetricsCharacterWidth(FontPtr pFont)
{
FTFontPtr ftfont = (FTFontPtr)pFont->fontPrivate;
if( ftfont->instance->spacing != FT_PROPORTIONAL )
{
int width = ftfont->instance->charcellMetrics->characterWidth;
if( ftfont->instance->transformation.nonIdentity )
{
FT_Vector v;
FT_Matrix m = ftfont->instance->transformation.matrix;
(void)FT_Matrix_Invert(&m);
v.x = width;
v.y = FT_Get_CharcellMetricsCharacterHeight(pFont);
FT_Vector_Transform(&v, &m);
width = v.x;
}
return width;
}
return 0;
}
void
PsOut_FreeType_Text(FontPtr pFont, PsOutPtr self, int x, int y, char *text, int textl)
{
int i;
int xo = self->XOff,
yo = self->YOff;
char buf[256];
int cwidth = FT_Get_CharcellMetricsCharacterWidth(pFont);
if( self->InFrame || self->InTile ) xo = yo = 0;
x += xo; y += yo;
S_OutNum(self, (float)x);
S_OutNum(self, (float)y);
S_OutTok(self, "moveto", 1);
S_OutTok(self, "[ ", 0);
for( i = 0 ; i < textl ; i++ )
{
#ifdef USE_FT_PS_NAMES
char namebuf[256];
unsigned int ch = text[i]&0xFF;
unsigned long block_offset = 0;
PsOut_Get_FreeType_Glyph_Name(namebuf, pFont, ch+block_offset);
sprintf(buf, "/%s ", namebuf);
#else
sprintf(buf, "/ch%02x ", text[i]&0xFF);
#endif
S_OutTok(self, buf, 0);
}
if( cwidth != 0 )
{
if( self->FontSize == -1 )
{
sprintf(buf, "]{gs glyphshow gr %d 0 trmoveto}fa", cwidth);
}
else
{
sprintf(buf, "]{gs glyphshow gr %d 0 rm}fa", cwidth);
}
}
else
{
sprintf(buf, "]{glyphshow}fa");
}
S_OutTok(self, buf, 0);
}
void
PsOut_FreeType_Text16(FontPtr pFont, PsOutPtr self, int x, int y, unsigned short *text, int textl)
{
int i;
int xo = self->XOff,
yo = self->YOff;
unsigned short c,
c_hiByte,
c_lowByte,
fontPage;
long lastFontPage = -1;
char baseFontName[256];
char buf[256];
if( self->InFrame || self->InTile ) xo = yo = 0;
x += xo; y += yo;
strcpy(baseFontName, self->FontName);
S_OutNum(self, (float)x);
S_OutNum(self, (float)y);
S_OutTok(self, "moveto", 1);
for( i = 0 ; i < textl ; i++ )
{
c = text[i];
#if IMAGE_BYTE_ORDER == LSBFirst
c_hiByte = c & 0x00FF;
c_lowByte = (c >> 8) & 0x00FF;
#elif IMAGE_BYTE_ORDER == MSBFirst
c_hiByte = (c >> 8) & 0x00FF;
c_lowByte = c & 0x00FF;
#else
#error Unsupported byte order
#endif
fontPage = c_hiByte;
if( fontPage != lastFontPage )
{
if( fontPage > 0 )
{
sprintf(buf, "%s_%x", baseFontName, fontPage);
}
else
{
sprintf(buf, "%s", baseFontName);
}
if( self->FontSize == -1 )
{
PsOut_TextAttrsMtx(self, buf, self->FontMtx, FALSE);
}
else
{
PsOut_TextAttrs(self, buf, self->FontSize, FALSE);
}
lastFontPage = fontPage;
}
#ifdef USE_FT_PS_NAMES
{
char namebuf[256];
unsigned int ch = c_lowByte;
unsigned long block_offset = c_hiByte * 0x100 ;
int cwidth = FT_Get_CharcellMetricsCharacterWidth(pFont);
PsOut_Get_FreeType_Glyph_Name(namebuf, pFont, ch+block_offset);
if( cwidth != 0 )
{
if( self->FontSize == -1 )
{
sprintf(buf, "gs /%s glyphshow gr %d 0 trmoveto", namebuf, cwidth);
}
else
{
sprintf(buf, "gs /%s glyphshow gr %d 0 rm", namebuf, cwidth);
}
}
else
{
sprintf(buf, "/%s glyphshow", namebuf);
}
}
#else
sprintf(buf, "/ch%02x glyphshow", c_lowByte);
#endif
S_OutTok(self, buf, 1);
}
if( self->FontName ) xfree(self->FontName);
self->FontName = (char *)xalloc(strlen(baseFontName)+1);
strcpy(self->FontName, baseFontName);
}