File wine-fontenc.patch of Package wine
diff -ur wine-1.7.5/dlls/wineps.drv/download.c wine-1.7.5-fontenc/dlls/wineps.drv/download.c
--- wine-1.7.5/dlls/wineps.drv/download.c 2013-10-25 19:45:30.000000000 +0200
+++ wine-1.7.5-fontenc/dlls/wineps.drv/download.c 2013-12-07 06:10:42.567269442 +0100
@@ -391,7 +391,7 @@
case Type1:
for(i = 0; i < count; i++) {
- get_glyph_name(dev->hdc, glyphs[i], g_name);
+ T1_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);
}
diff -ur wine-1.7.5/dlls/wineps.drv/psdrv.h wine-1.7.5-fontenc/dlls/wineps.drv/psdrv.h
--- wine-1.7.5/dlls/wineps.drv/psdrv.h 2013-10-25 19:45:30.000000000 +0200
+++ wine-1.7.5-fontenc/dlls/wineps.drv/psdrv.h 2013-12-07 06:11:23.522780188 +0100
@@ -561,6 +561,9 @@
RECT *bbox, UINT emsize) DECLSPEC_HIDDEN;
extern BOOL T1_download_glyph(PHYSDEV dev, DOWNLOAD *pdl,
DWORD index, char *glyph_name) DECLSPEC_HIDDEN;
+
+extern void T1_get_glyph_name(HDC hdc, WORD index, char *name) DECLSPEC_HIDDEN;
+
extern void T1_free(TYPE1 *t1) DECLSPEC_HIDDEN;
extern TYPE42 *T42_download_header(PHYSDEV dev, char *ps_name,
diff -ur wine-1.7.5/dlls/wineps.drv/type1.c wine-1.7.5-fontenc/dlls/wineps.drv/type1.c
--- wine-1.7.5/dlls/wineps.drv/type1.c 2013-10-25 19:45:30.000000000 +0200
+++ wine-1.7.5-fontenc/dlls/wineps.drv/type1.c 2013-12-07 06:14:41.516242060 +0100
@@ -55,6 +55,563 @@
rmoveto = 21
};
+//#pragma pack(1)
+
+// Macros to swap from Big Endian to Little Endian
+#define SWAPWORD(x) MAKEWORD( \
+ HIBYTE(x), \
+ LOBYTE(x) \
+ )
+#define SWAPLONG(x) MAKELONG( \
+ SWAPWORD(HIWORD(x)), \
+ SWAPWORD(LOWORD(x)) \
+ )
+
+typedef struct _CMap4 // From the TrueType Spec. revision 1.66
+{
+ USHORT format; // Format number is set to 4.
+ USHORT length; // Length in bytes.
+ USHORT version; // Version number (starts at 0).
+ USHORT segCountX2; // 2 x segCount.
+ USHORT searchRange; // 2 x (2**floor(log2(segCount)))
+ USHORT entrySelector; // log2(searchRange/2)
+ USHORT rangeShift; // 2 x segCount - searchRange
+
+ USHORT Arrays[1]; // Placeholder symbol for address of arrays following
+} CMAP4, *LPCMAP4;
+
+/* CMAP table Data
+ From the TrueType Spec revision 1.66
+
+ USHORT Table Version #
+ USHORT Number of encoding tables
+*/
+#define CMAPHEADERSIZE (sizeof(USHORT)*2)
+
+
+/* ENCODING entry Data aka CMAPENCODING
+ From the TrueType Spec revision 1.66
+
+ USHORT Platform Id
+ USHORT Platform Specific Encoding Id
+ ULONG Byte Offset from beginning of table
+*/
+#define ENCODINGSIZE (sizeof(USHORT)*2 + sizeof(ULONG))
+
+typedef struct _CMapEncoding
+{
+ USHORT PlatformId;
+ USHORT EncodingId;
+ ULONG Offset;
+} CMAPENCODING;
+
+// Macro to pack a TrueType table name into a DWORD
+#define MAKETABLENAME(ch1, ch2, ch3, ch4) (\
+ (((DWORD)(ch4)) << 24) | \
+ (((DWORD)(ch3)) << 16) | \
+ (((DWORD)(ch2)) << 8) | \
+ ((DWORD)(ch1)) \
+ )
+
+/* public functions */
+USHORT GetTTUnicodeGlyphIndex(HDC hdc, USHORT ch);
+USHORT GetTTUnicodeCharCount(HDC hdc);
+
+
+// DWORD packed four letter table name for each GetFontData()
+// function call when working with the CMAP TrueType table
+DWORD dwCmapName = MAKETABLENAME( 'c','m','a','p' );
+
+USHORT *GetEndCountArray(LPBYTE pBuff)
+{
+ return (USHORT *)(pBuff + 7 * sizeof(USHORT)); // Per TT spec
+}
+
+USHORT *GetStartCountArray(LPBYTE pBuff)
+{
+ DWORD segCount = ((LPCMAP4)pBuff)->segCountX2/2;
+ return (USHORT *)( pBuff +
+ 8 * sizeof(USHORT) + // 7 header + 1 reserved USHORT
+ segCount*sizeof(USHORT) ); // Per TT spec
+}
+
+USHORT *GetIdDeltaArray(LPBYTE pBuff)
+{
+ DWORD segCount = ((LPCMAP4)pBuff)->segCountX2/2;
+ return (USHORT *)( pBuff +
+ 8 * sizeof(USHORT) + // 7 header + 1 reserved USHORT
+ segCount * 2 * sizeof(USHORT) ); // Per TT spec
+}
+
+USHORT *GetIdRangeOffsetArray(LPBYTE pBuff)
+{
+ DWORD segCount = ((LPCMAP4)pBuff)->segCountX2/2;
+ return (USHORT *)( pBuff +
+ 8 * sizeof(USHORT) + // 7 header + 1 reserved USHORT
+ segCount * 3 * sizeof(USHORT) ); // Per TT spec
+}
+
+
+void SwapArrays( LPCMAP4 pFormat4 )
+{
+ DWORD segCount = pFormat4->segCountX2/2; // Per TT Spec
+ DWORD i;
+ USHORT *pGlyphId,
+ *pEndOfBuffer,
+ *pstartCount = GetStartCountArray( (LPBYTE)pFormat4 ),
+ *pidDelta = GetIdDeltaArray( (LPBYTE)pFormat4 ),
+ *pidRangeOffset = GetIdRangeOffsetArray( (LPBYTE)pFormat4 ),
+ *pendCount = GetEndCountArray( (LPBYTE)pFormat4 );
+
+ // Swap the array elements for Intel.
+ for (i=0; i < segCount; i++)
+ {
+ pendCount[i] = SWAPWORD(pendCount[i]);
+ pstartCount[i] = SWAPWORD(pstartCount[i]);
+ pidDelta[i] = SWAPWORD(pidDelta[i]);
+ pidRangeOffset[i] = SWAPWORD(pidRangeOffset[i]);
+ }
+
+ // Swap the Glyph Id array
+ pGlyphId = pidRangeOffset + segCount; // Per TT spec
+ pEndOfBuffer = (USHORT*)((LPBYTE)pFormat4 + pFormat4->length);
+ for (;pGlyphId < pEndOfBuffer; pGlyphId++)
+ {
+ *pGlyphId = SWAPWORD(*pGlyphId);
+ }
+} /* end of function SwapArrays */
+
+BOOL GetFontEncoding (
+ HDC hdc,
+ CMAPENCODING * pEncoding,
+ int iEncoding
+ )
+/*
+ Note for this function to work correctly, structures must
+ have byte alignment.
+*/
+{
+ DWORD dwResult;
+ BOOL fSuccess = TRUE;
+
+ // Get the structure data from the TrueType font
+ dwResult = GetFontData (
+ hdc,
+ dwCmapName,
+ CMAPHEADERSIZE + ENCODINGSIZE*iEncoding,
+ pEncoding,
+ sizeof(CMAPENCODING) );
+ fSuccess = (dwResult == sizeof(CMAPENCODING));
+
+ // swap the Platform Id for Intel
+ pEncoding->PlatformId = SWAPWORD(pEncoding->PlatformId);
+
+ // swap the Specific Id for Intel
+ pEncoding->EncodingId = SWAPWORD(pEncoding->EncodingId);
+
+ // swap the subtable offset for Intel
+ pEncoding->Offset = SWAPLONG(pEncoding->Offset);
+
+ return fSuccess;
+
+} /* end of function GetFontEncoding */
+
+BOOL GetFontFormat4Header (
+ HDC hdc,
+ LPCMAP4 pFormat4,
+ DWORD dwOffset
+ )
+/*
+ Note for this function to work correctly, structures must
+ have byte alignment.
+*/
+{
+ BOOL fSuccess = TRUE;
+ DWORD dwResult;
+ int i;
+ USHORT *pField;
+
+ // Loop and Alias a writeable pointer to the field of interest
+ pField = (USHORT *)pFormat4;
+
+ for (i=0; i < 7; i++)
+ {
+ // Get the field from the subtable
+ dwResult = GetFontData (
+ hdc,
+ dwCmapName,
+ dwOffset + sizeof(USHORT)*i,
+ pField,
+ sizeof(USHORT) );
+
+ // swap it to make it right for Intel.
+ *pField = SWAPWORD(*pField);
+ // move on to the next
+ pField++;
+ // accumulate our success
+ fSuccess = (dwResult == sizeof(USHORT)) && fSuccess;
+ }
+
+ return fSuccess;
+
+} /* end of function GetFontFormat4Header */
+
+
+BOOL GetFontFormat4Subtable (
+ HDC hdc, // DC with TrueType font
+ LPCMAP4 pFormat4Subtable, // destination buffer
+ DWORD dwOffset // Offset within font
+ )
+{
+ DWORD dwResult;
+ USHORT length;
+
+
+ // Retrieve the header values in swapped order
+ if (!GetFontFormat4Header ( hdc,
+ pFormat4Subtable,
+ dwOffset ))
+ {
+ return FALSE;
+ }
+
+ // Get the rest of the table
+ length = pFormat4Subtable->length - (7 * sizeof(USHORT));
+ dwResult = GetFontData( hdc,
+ dwCmapName,
+ dwOffset + 7 * sizeof(USHORT), // pos of arrays
+ (LPBYTE)pFormat4Subtable->Arrays, // destination
+ length );
+
+ if ( dwResult != length)
+ {
+ // We really shouldn't ever get here
+ return FALSE;
+ }
+
+ // Swamp the arrays
+ SwapArrays( pFormat4Subtable );
+
+ return TRUE;
+}
+
+USHORT GetFontFormat4CharCount (
+ LPCMAP4 pFormat4 // pointer to a valid Format4 subtable
+ )
+{
+ USHORT i,
+ *pendCount = GetEndCountArray((LPBYTE) pFormat4),
+ *pstartCount = GetStartCountArray((LPBYTE) pFormat4),
+ *idRangeOffset = GetIdRangeOffsetArray( (LPBYTE) pFormat4 );
+
+ // Count the # of glyphs
+ USHORT nGlyphs = 0;
+
+ if ( pFormat4 == NULL )
+ return 0;
+
+ // by adding up the coverage of each segment
+ for (i=0; i < (pFormat4->segCountX2/2); i++)
+ {
+
+ if ( idRangeOffset[i] == 0)
+ {
+ // if per the TT spec, the idRangeOffset element is zero,
+ // all of the characters in this segment exist.
+ nGlyphs += pendCount[i] - pstartCount[i] +1;
+ }
+ else
+ {
+ // otherwise we have to test for glyph existence for
+ // each character in the segment.
+ USHORT idResult; //Intermediate id calc.
+ USHORT ch;
+
+ for (ch = pstartCount[i]; ch <= pendCount[i]; ch++)
+ {
+ // determine if a glyph exists
+ idResult = *(
+ idRangeOffset[i]/2 +
+ (ch - pstartCount[i]) +
+ &idRangeOffset[i]
+ ); // indexing equation from TT spec
+ if (idResult != 0)
+ // Yep, count it.
+ nGlyphs++;
+ }
+ }
+ }
+
+ return nGlyphs;
+} /* end of function GetFontFormat4CharCount */
+
+BOOL GetTTUnicodeCoverage (
+ HDC hdc, // DC with TT font
+ LPCMAP4 pBuffer, // Properly allocated buffer
+ DWORD cbSize, // Size of properly allocated buffer
+ DWORD *pcbNeeded // size of buffer needed
+ )
+/*
+ if cbSize is to small or zero, or if pBuffer is NULL the function
+ will fail and return the required buffer size in *pcbNeeded.
+
+ if another error occurs, the function will fail and *pcbNeeded will
+ be zero.
+
+ When the function succeeds, *pcbNeeded contains the number of bytes
+ copied to pBuffer.
+*/
+{
+ USHORT nEncodings; // # of encoding in the TT font
+ CMAPENCODING Encoding; // The current encoding
+ DWORD dwResult;
+ DWORD i,
+ iUnicode; // The Unicode encoding
+ CMAP4 Format4; // Unicode subtable format
+ LPCMAP4 pFormat4Subtable; // Working buffer for subtable
+
+ // Get the number of subtables in the CMAP table from the CMAP header
+ // The # of subtables is the second USHORT in the CMAP table, per the TT Spec.
+ dwResult = GetFontData ( hdc, dwCmapName, sizeof(USHORT), &nEncodings, sizeof(USHORT) );
+ nEncodings = SWAPWORD(nEncodings);
+
+ if ( dwResult != sizeof(USHORT) )
+ {
+ // Something is wrong, we probably got GDI_ERROR back
+ // Probably this means that the Device Context does not have
+ // a TrueType font selected into it.
+ return FALSE;
+ }
+
+ // Get the encodings and look for a Unicode Encoding
+ iUnicode = nEncodings;
+ for (i=0; i < nEncodings; i++)
+ {
+ // Get the encoding entry for each encoding
+ if (!GetFontEncoding ( hdc, &Encoding, i ))
+ {
+ *pcbNeeded = 0;
+ return FALSE;
+ }
+
+ // Take note of the Unicode encoding.
+ //
+ // A Unicode encoding per the TrueType specification has a
+ // Platform Id of 3 and a Platform specific encoding id of 1
+ // Note that Symbol fonts are supposed to have a Platform Id of 3
+ // and a specific id of 0. If the TrueType spec. suggestions were
+ // followed then the Symbol font's Format 4 encoding could also
+ // be considered Unicode because the mapping would be in the
+ // Private Use Area of Unicode. We assume this here and allow
+ // Symbol fonts to be interpreted. If they do not contain a
+ // Format 4, we bail later. If they do not have a Unicode
+ // character mapping, we'll get wrong results.
+ // Code could infer from the coverage whether 3-0 fonts are
+ // Unicode or not by examining the segments for placement within
+ // the Private Use Area Subrange.
+ if (Encoding.PlatformId == 3 &&
+ (Encoding.EncodingId == 1 || Encoding.EncodingId == 0) )
+ {
+ iUnicode = i; // Set the index to the Unicode encoding
+ }
+ }
+
+ // index out of range means failure to find a Unicode mapping
+ if (iUnicode >= nEncodings)
+ {
+ // No Unicode encoding found.
+ *pcbNeeded = 0;
+ return FALSE;
+ }
+
+ // Get the header entries(first 7 USHORTs) for the Unicode encoding.
+ if ( !GetFontFormat4Header ( hdc, &Format4, Encoding.Offset ) )
+ {
+ *pcbNeeded = 0;
+ return FALSE;
+ }
+
+ // Check to see if we retrieved a Format 4 table
+ if ( Format4.format != 4 )
+ {
+ // Bad, subtable is not format 4, bail.
+ // This could happen if the font is corrupt
+ // It could also happen if there is a new font format we
+ // don't understand.
+ *pcbNeeded = 0;
+ return FALSE;
+ }
+
+ // Figure buffer size and tell caller if buffer to small
+ *pcbNeeded = Format4.length;
+ if (*pcbNeeded > cbSize || pBuffer == NULL)
+ {
+ // Either test indicates caller needs to know
+ // the buffer size and the parameters are not setup
+ // to continue.
+ return FALSE;
+ }
+
+ // allocate a full working buffer
+ pFormat4Subtable = (LPCMAP4)malloc ( Format4.length );
+ if ( pFormat4Subtable == NULL)
+ {
+ // Bad things happening if we can't allocate memory
+ *pcbNeeded = 0;
+ return FALSE;
+ }
+
+ // get the entire subtable
+ if (!GetFontFormat4Subtable ( hdc, pFormat4Subtable, Encoding.Offset ))
+ {
+ // Bad things happening if we can't allocate memory
+ *pcbNeeded = 0;
+ return FALSE;
+ }
+
+ // Copy the retrieved table into the buffer
+ CopyMemory( pBuffer,
+ pFormat4Subtable,
+ pFormat4Subtable->length );
+
+ free ( pFormat4Subtable );
+ return TRUE;
+} /* end of function GetTTUnicodeCoverage */
+
+BOOL FindFormat4Segment (
+ LPCMAP4 pTable, // a valid Format4 subtable buffer
+ USHORT ch, // Unicode character to search for
+ USHORT *piSeg // out: index of segment containing ch
+ )
+/*
+ if the Unicode character ch is not contained in one of the
+ segments the function returns FALSE.
+
+ if the Unicode character ch is found in a segment, the index
+ of the segment is placed in*piSeg and the function returns
+ TRUE.
+*/
+{
+ USHORT i,
+ segCount = pTable->segCountX2/2;
+ USHORT *pendCount = GetEndCountArray((LPBYTE) pTable);
+ USHORT *pstartCount = GetStartCountArray((LPBYTE) pTable);
+
+ // Find segment that could contain the Unicode character code
+ for (i=0; i < segCount && pendCount[i] < ch; i++);
+
+ // We looked in them all, ch not there
+ if (i >= segCount)
+ return FALSE;
+
+ // character code not within the range of the segment
+ if (pstartCount[i] > ch)
+ return FALSE;
+
+ // this segment contains the character code
+ *piSeg = i;
+ return TRUE;
+} /* end of function FindFormat4Segment */
+
+USHORT GetTTUnicodeCharCount (
+ HDC hdc
+ )
+/*
+ Returns the number of Unicode character glyphs that
+ are in the TrueType font that is selected into the hdc.
+*/
+{
+ LPCMAP4 pUnicodeCMapTable;
+ USHORT cChar;
+ DWORD dwSize;
+
+ // Get the Unicode CMAP table from the TT font
+ GetTTUnicodeCoverage( hdc, NULL, 0, &dwSize );
+ pUnicodeCMapTable = (LPCMAP4)malloc( dwSize );
+ if (!GetTTUnicodeCoverage( hdc, pUnicodeCMapTable, dwSize, &dwSize ))
+ {
+ // possibly no Unicode cmap, not a TT font selected,...
+ free( pUnicodeCMapTable );
+ return 0;
+ }
+
+ cChar = GetFontFormat4CharCount( pUnicodeCMapTable );
+ free( pUnicodeCMapTable );
+
+ return cChar;
+} /* end of function GetTTUnicodeCharCount */
+
+
+USHORT GetTTUnicodeGlyphIndex (
+ HDC hdc, // DC with a TrueType font selected
+ USHORT ch // Unicode character to convert to Index
+ )
+/*
+ When the TrueType font contains a glyph for ch, the
+ function returns the glyph index for that character.
+
+ If an error occurs, or there is no glyph for ch, the
+ function will return the missing glyph index of zero.
+*/
+{
+ LPCMAP4 pUnicodeCMapTable;
+ DWORD dwSize;
+ USHORT iSegment;
+ USHORT *idRangeOffset;
+ USHORT *idDelta;
+ USHORT *startCount;
+ USHORT GlyphIndex = 0; // Initialize to missing glyph
+
+ // How big a buffer do we need for Unicode CMAP?
+ GetTTUnicodeCoverage( hdc, NULL, 0, &dwSize );
+ pUnicodeCMapTable = (LPCMAP4)malloc( dwSize );
+ if (!GetTTUnicodeCoverage( hdc, pUnicodeCMapTable, dwSize, &dwSize ))
+ {
+ // Either no Unicode cmap, or some other error occurred
+ // like font in DC is not TT.
+ free( pUnicodeCMapTable );
+ return 0; // return missing glyph on error
+ }
+
+ // Find the cmap segment that has the character code.
+ if (!FindFormat4Segment( pUnicodeCMapTable, ch, &iSegment ))
+ {
+ free( pUnicodeCMapTable );
+ return 0; // ch not in cmap, return missing glyph
+ }
+
+ // Get pointers to the cmap data
+ idRangeOffset = GetIdRangeOffsetArray( (LPBYTE) pUnicodeCMapTable );
+ idDelta = GetIdDeltaArray( (LPBYTE) pUnicodeCMapTable );
+ startCount = GetStartCountArray( (LPBYTE) pUnicodeCMapTable );
+
+ // Per TT spec, if the RangeOffset is zero,
+ if ( idRangeOffset[iSegment] == 0)
+ {
+ // calculate the glyph index directly
+ GlyphIndex = (idDelta[iSegment] + ch) % 65536;
+ }
+ else
+ {
+ // otherwise, use the glyph id array to get the index
+ USHORT idResult; //Intermediate id calc.
+
+ idResult = *(
+ idRangeOffset[iSegment]/2 +
+ (ch - startCount[iSegment]) +
+ &idRangeOffset[iSegment]
+ ); // indexing equation from TT spec
+ if (idResult)
+ // Per TT spec, nonzero means there is a glyph
+ GlyphIndex = (idDelta[iSegment] + idResult) % 65536;
+ else
+ // otherwise, return the missing glyph
+ GlyphIndex = 0;
+ }
+
+ free( pUnicodeCMapTable );
+ return GlyphIndex;
+} /* end of function GetTTUnicodeGlyphIndex */
#define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
( ( (DWORD)_x4 << 24 ) | \
@@ -533,9 +1090,26 @@
return outline->flags[pt] & 1;
}
+void T1_get_glyph_name(HDC hdc, WORD index, char *name)
+{
+ DWORD dsp, chr=-1;
+ int j;
+ for (j = 0; j < 512; j++)
+ {
+ dsp = GetTTUnicodeGlyphIndex(hdc, j);
+ if (dsp == index)
+ {
+ chr = j;
+ break;
+ }
+ }
+ sprintf(name, "g%04d", (chr == -1 ? index : chr));
+ return;
+}
+
BOOL T1_download_glyph(PHYSDEV dev, DOWNLOAD *pdl, DWORD index, char *glyph_name)
{
- DWORD len;
+ DWORD len, i, j, chr, dsp;
WORD cur_pt, cont;
char *buf;
TYPE1 *t1;
@@ -552,8 +1126,20 @@
static const char glyph_def_end[] =
"ND\n"
"end end\n";
-
- TRACE("%d %s\n", index, glyph_name);
+ /*
+ chr = -1;
+ for (j = 0; j < 512; j++)
+ {
+ dsp = GetTTUnicodeGlyphIndex(physDev->hdc, j);
+ if (dsp == index)
+ {
+ chr = j;
+ TRACE("Found mapping unicode mapping %d \n", chr);
+ break;
+ }
+ }
+ */
+ TRACE("Downloading glyph! %d %s\n", index, glyph_name);
assert(pdl->type == Type1);
t1 = pdl->typeinfo.Type1;
@@ -652,7 +1238,7 @@
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(glyph_def_begin) +
strlen(pdl->ps_name) + strlen(glyph_name) + 100);
- sprintf(buf, "%%%%glyph %04x\n", index);
+ sprintf(buf, "%%%%glyph %04d\n", index);
PSDRV_WriteSpool(dev, buf, strlen(buf));
len = str_get_bytes(charstring, &bytes);