diff options
author | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 14:39:34 +0300 |
---|---|---|
committer | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 16:42:24 +0300 |
commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/matplotlib/py3/extern/ttconv | |
parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
download | ydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/matplotlib/py3/extern/ttconv')
-rw-r--r-- | contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h | 102 | ||||
-rw-r--r-- | contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp | 1401 | ||||
-rw-r--r-- | contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp | 693 | ||||
-rw-r--r-- | contrib/python/matplotlib/py3/extern/ttconv/truetype.h | 129 | ||||
-rw-r--r-- | contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp | 71 | ||||
-rw-r--r-- | contrib/python/matplotlib/py3/extern/ttconv/ya.make | 13 |
6 files changed, 2409 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h new file mode 100644 index 0000000000..8c0b6c1955 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h @@ -0,0 +1,102 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* +** ~ppr/src/include/pprdrv.h +** Copyright 1995, Trinity College Computing Center. +** Written by David Chappell. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** This file last revised 5 December 1995. +*/ + +#include <vector> +#include <cassert> + +/* + * Encapsulates all of the output to write to an arbitrary output + * function. This both removes the hardcoding of output to go to stdout + * and makes output thread-safe. Michael Droettboom [06-07-07] + */ +class TTStreamWriter +{ + private: + // Private copy and assignment + TTStreamWriter& operator=(const TTStreamWriter& other); + TTStreamWriter(const TTStreamWriter& other); + + public: + TTStreamWriter() { } + virtual ~TTStreamWriter() { } + + virtual void write(const char*) = 0; + + virtual void printf(const char* format, ...); + virtual void put_char(int val); + virtual void puts(const char* a); + virtual void putline(const char* a); +}; + +void replace_newlines_with_spaces(char* a); + +/* + * A simple class for all ttconv exceptions. + */ +class TTException +{ + const char* message; + TTException& operator=(const TTStreamWriter& other); + TTException(const TTStreamWriter& other); + +public: + TTException(const char* message_) : message(message_) { } + const char* getMessage() + { + return message; + } +}; + +/* +** No debug code will be included if this +** is not defined: +*/ +/* #define DEBUG 1 */ + +/* +** Uncomment the defines for the debugging +** code you want to have included. +*/ +#ifdef DEBUG +#define DEBUG_TRUETYPE /* truetype fonts, conversion to Postscript */ +#endif + +#if DEBUG_TRUETYPE +#define debug(...) printf(__VA_ARGS__) +#else +#define debug(...) +#endif + +/* Do not change anything below this line. */ + +enum font_type_enum +{ + PS_TYPE_3 = 3, + PS_TYPE_42 = 42, + PS_TYPE_42_3_HYBRID = 43, +}; + +/* routines in pprdrv_tt.c */ +void insert_ttfont(const char *filename, TTStreamWriter& stream, font_type_enum target_type, std::vector<int>& glyph_ids); + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp new file mode 100644 index 0000000000..a0c724c8aa --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp @@ -0,0 +1,1401 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* +** ~ppr/src/pprdrv/pprdrv_tt.c +** Copyright 1995, Trinity College Computing Center. +** Written by David Chappell. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** TrueType font support. These functions allow PPR to generate +** PostScript fonts from Microsoft compatible TrueType font files. +** +** Last revised 19 December 1995. +*/ + +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include "pprdrv.h" +#include "truetype.h" +#include <sstream> +#ifdef _POSIX_C_SOURCE +# undef _POSIX_C_SOURCE +#endif +#ifndef _AIX +#ifdef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif +#endif +#include <Python.h> + +/*========================================================================== +** Convert the indicated Truetype font file to a type 42 or type 3 +** PostScript font and insert it in the output stream. +** +** All the routines from here to the end of file file are involved +** in this process. +==========================================================================*/ + +/*--------------------------------------- +** Endian conversion routines. +** These routines take a BYTE pointer +** and return a value formed by reading +** bytes starting at that point. +** +** These routines read the big-endian +** values which are used in TrueType +** font files. +---------------------------------------*/ + +/* +** Get an Unsigned 32 bit number. +*/ +ULONG getULONG(BYTE *p) +{ + int x; + ULONG val=0; + + for (x=0; x<4; x++) + { + val *= 0x100; + val += p[x]; + } + + return val; +} /* end of ftohULONG() */ + +/* +** Get an unsigned 16 bit number. +*/ +USHORT getUSHORT(BYTE *p) +{ + int x; + USHORT val=0; + + for (x=0; x<2; x++) + { + val *= 0x100; + val += p[x]; + } + + return val; +} /* end of getUSHORT() */ + +/* +** Get a 32 bit fixed point (16.16) number. +** A special structure is used to return the value. +*/ +Fixed getFixed(BYTE *s) +{ + Fixed val={0,0}; + + val.whole = ((s[0] * 256) + s[1]); + val.fraction = ((s[2] * 256) + s[3]); + + return val; +} /* end of getFixed() */ + +/*----------------------------------------------------------------------- +** Load a TrueType font table into memory and return a pointer to it. +** The font's "file" and "offset_table" fields must be set before this +** routine is called. +** +** This first argument is a TrueType font structure, the second +** argument is the name of the table to retrieve. A table name +** is always 4 characters, though the last characters may be +** padding spaces. +-----------------------------------------------------------------------*/ +BYTE *GetTable(struct TTFONT *font, const char *name) +{ + BYTE *ptr; + ULONG x; + debug("GetTable(file,font,\"%s\")",name); + + /* We must search the table directory. */ + ptr = font->offset_table + 12; + x=0; + while (true) + { + if ( strncmp((const char*)ptr,name,4) == 0 ) + { + ULONG offset,length; + BYTE *table; + + offset = getULONG( ptr + 8 ); + length = getULONG( ptr + 12 ); + table = (BYTE*)calloc( sizeof(BYTE), length + 2 ); + + try + { + debug("Loading table \"%s\" from offset %d, %d bytes",name,offset,length); + + if ( fseek( font->file, (long)offset, SEEK_SET ) ) + { + throw TTException("TrueType font may be corrupt (reason 3)"); + } + + if ( fread(table,sizeof(BYTE),length,font->file) != (sizeof(BYTE) * length)) + { + throw TTException("TrueType font may be corrupt (reason 4)"); + } + } + catch (TTException& ) + { + free(table); + throw; + } + /* Always NUL-terminate; add two in case of UTF16 strings. */ + table[length] = '\0'; + table[length + 1] = '\0'; + return table; + } + + x++; + ptr += 16; + if (x == font->numTables) + { + throw TTException("TrueType font is missing table"); + } + } + +} /* end of GetTable() */ + +static void utf16be_to_ascii(char *dst, char *src, size_t length) { + ++src; + for (; *src != 0 && length; dst++, src += 2, --length) { + *dst = *src; + } +} + +/*-------------------------------------------------------------------- +** Load the 'name' table, get information from it, +** and store that information in the font structure. +** +** The 'name' table contains information such as the name of +** the font, and it's PostScript name. +--------------------------------------------------------------------*/ +void Read_name(struct TTFONT *font) +{ + BYTE *table_ptr,*ptr2; + int numrecords; /* Number of strings in this table */ + BYTE *strings; /* pointer to start of string storage */ + int x; + int platform; /* Current platform id */ + int nameid; /* name id, */ + int offset,length; /* offset and length of string. */ + debug("Read_name()"); + + table_ptr = NULL; + + /* Set default values to avoid future references to undefined + * pointers. Allocate each of PostName, FullName, FamilyName, + * Version, and Style separately so they can be freed safely. */ + for (char **ptr = &(font->PostName); ptr != NULL; ) + { + *ptr = (char*) calloc(sizeof(char), strlen("unknown")+1); + strcpy(*ptr, "unknown"); + if (ptr == &(font->PostName)) ptr = &(font->FullName); + else if (ptr == &(font->FullName)) ptr = &(font->FamilyName); + else if (ptr == &(font->FamilyName)) ptr = &(font->Version); + else if (ptr == &(font->Version)) ptr = &(font->Style); + else ptr = NULL; + } + font->Copyright = font->Trademark = (char*)NULL; + + table_ptr = GetTable(font, "name"); /* pointer to table */ + try + { + numrecords = getUSHORT( table_ptr + 2 ); /* number of names */ + strings = table_ptr + getUSHORT( table_ptr + 4 ); /* start of string storage */ + + ptr2 = table_ptr + 6; + for (x=0; x < numrecords; x++,ptr2+=12) + { + platform = getUSHORT(ptr2); + nameid = getUSHORT(ptr2+6); + length = getUSHORT(ptr2+8); + offset = getUSHORT(ptr2+10); + debug("platform %d, encoding %d, language 0x%x, name %d, offset %d, length %d", + platform,encoding,language,nameid,offset,length); + + /* Copyright notice */ + if ( platform == 1 && nameid == 0 ) + { + font->Copyright = (char*)calloc(sizeof(char),length+1); + strncpy(font->Copyright,(const char*)strings+offset,length); + font->Copyright[length]='\0'; + replace_newlines_with_spaces(font->Copyright); + debug("font->Copyright=\"%s\"",font->Copyright); + continue; + } + + + /* Font Family name */ + if ( platform == 1 && nameid == 1 ) + { + free(font->FamilyName); + font->FamilyName = (char*)calloc(sizeof(char),length+1); + strncpy(font->FamilyName,(const char*)strings+offset,length); + font->FamilyName[length]='\0'; + replace_newlines_with_spaces(font->FamilyName); + debug("font->FamilyName=\"%s\"",font->FamilyName); + continue; + } + + + /* Font Family name */ + if ( platform == 1 && nameid == 2 ) + { + free(font->Style); + font->Style = (char*)calloc(sizeof(char),length+1); + strncpy(font->Style,(const char*)strings+offset,length); + font->Style[length]='\0'; + replace_newlines_with_spaces(font->Style); + debug("font->Style=\"%s\"",font->Style); + continue; + } + + + /* Full Font name */ + if ( platform == 1 && nameid == 4 ) + { + free(font->FullName); + font->FullName = (char*)calloc(sizeof(char),length+1); + strncpy(font->FullName,(const char*)strings+offset,length); + font->FullName[length]='\0'; + replace_newlines_with_spaces(font->FullName); + debug("font->FullName=\"%s\"",font->FullName); + continue; + } + + + /* Version string */ + if ( platform == 1 && nameid == 5 ) + { + free(font->Version); + font->Version = (char*)calloc(sizeof(char),length+1); + strncpy(font->Version,(const char*)strings+offset,length); + font->Version[length]='\0'; + replace_newlines_with_spaces(font->Version); + debug("font->Version=\"%s\"",font->Version); + continue; + } + + + /* PostScript name */ + if ( platform == 1 && nameid == 6 ) + { + free(font->PostName); + font->PostName = (char*)calloc(sizeof(char),length+1); + strncpy(font->PostName,(const char*)strings+offset,length); + font->PostName[length]='\0'; + replace_newlines_with_spaces(font->PostName); + debug("font->PostName=\"%s\"",font->PostName); + continue; + } + + /* Microsoft-format PostScript name */ + if ( platform == 3 && nameid == 6 ) + { + free(font->PostName); + font->PostName = (char*)calloc(sizeof(char),length+1); + utf16be_to_ascii(font->PostName, (char *)strings+offset, length); + font->PostName[length/2]='\0'; + replace_newlines_with_spaces(font->PostName); + debug("font->PostName=\"%s\"",font->PostName); + continue; + } + + + /* Trademark string */ + if ( platform == 1 && nameid == 7 ) + { + font->Trademark = (char*)calloc(sizeof(char),length+1); + strncpy(font->Trademark,(const char*)strings+offset,length); + font->Trademark[length]='\0'; + replace_newlines_with_spaces(font->Trademark); + debug("font->Trademark=\"%s\"",font->Trademark); + continue; + } + } + } + catch (TTException& ) + { + free(table_ptr); + throw; + } + + free(table_ptr); +} /* end of Read_name() */ + +/*--------------------------------------------------------------------- +** Write the header for a PostScript font. +---------------------------------------------------------------------*/ +void ttfont_header(TTStreamWriter& stream, struct TTFONT *font) +{ + int VMMin; + int VMMax; + + /* + ** To show that it is a TrueType font in PostScript format, + ** we will begin the file with a specific string. + ** This string also indicates the version of the TrueType + ** specification on which the font is based and the + ** font manufacturer's revision number for the font. + */ + if ( font->target_type == PS_TYPE_42 || + font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("%%!PS-TrueTypeFont-%d.%d-%d.%d\n", + font->TTVersion.whole, font->TTVersion.fraction, + font->MfrRevision.whole, font->MfrRevision.fraction); + } + + /* If it is not a Type 42 font, we will use a different format. */ + else + { + stream.putline("%!PS-Adobe-3.0 Resource-Font"); + } /* See RBIIp 641 */ + + /* We will make the title the name of the font. */ + stream.printf("%%%%Title: %s\n",font->FullName); + + /* If there is a Copyright notice, put it here too. */ + if ( font->Copyright != (char*)NULL ) + { + stream.printf("%%%%Copyright: %s\n",font->Copyright); + } + + /* We created this file. */ + if ( font->target_type == PS_TYPE_42 ) + { + stream.putline("%%Creator: Converted from TrueType to type 42 by PPR"); + } + else if (font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.putline("%%Creator: Converted from TypeType to type 42/type 3 hybrid by PPR"); + } + else + { + stream.putline("%%Creator: Converted from TrueType to type 3 by PPR"); + } + + /* If VM usage information is available, print it. */ + if ( font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID) + { + VMMin = (int)getULONG( font->post_table + 16 ); + VMMax = (int)getULONG( font->post_table + 20 ); + if ( VMMin > 0 && VMMax > 0 ) + stream.printf("%%%%VMUsage: %d %d\n",VMMin,VMMax); + } + + /* Start the dictionary which will eventually */ + /* become the font. */ + if (font->target_type == PS_TYPE_42) + { + stream.putline("15 dict begin"); + } + else + { + stream.putline("25 dict begin"); + + /* Type 3 fonts will need some subroutines here. */ + stream.putline("/_d{bind def}bind def"); + stream.putline("/_m{moveto}_d"); + stream.putline("/_l{lineto}_d"); + stream.putline("/_cl{closepath eofill}_d"); + stream.putline("/_c{curveto}_d"); + stream.putline("/_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d"); + stream.putline("/_e{exec}_d"); + } + + stream.printf("/FontName /%s def\n",font->PostName); + stream.putline("/PaintType 0 def"); + + if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.putline("/FontMatrix[1 0 0 1 0 0]def"); + } + else + { + stream.putline("/FontMatrix[.001 0 0 .001 0 0]def"); + } + + stream.printf("/FontBBox[%d %d %d %d]def\n",font->llx-1,font->lly-1,font->urx,font->ury); + if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("/FontType 42 def\n", font->target_type ); + } + else + { + stream.printf("/FontType 3 def\n", font->target_type ); + } +} /* end of ttfont_header() */ + +/*------------------------------------------------------------- +** Define the encoding array for this font. +** Since we don't really want to deal with converting all of +** the possible font encodings in the wild to a standard PS +** one, we just explicitly create one for each font. +-------------------------------------------------------------*/ +void ttfont_encoding(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids, font_type_enum target_type) +{ + if (target_type == PS_TYPE_3 || target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("/Encoding [ "); + + for (std::vector<int>::const_iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + const char* name = ttfont_CharStrings_getname(font, *i); + stream.printf("/%s ", name); + } + + stream.printf("] def\n"); + } + else + { + stream.putline("/Encoding StandardEncoding def"); + } +} /* end of ttfont_encoding() */ + +/*----------------------------------------------------------- +** Create the optional "FontInfo" sub-dictionary. +-----------------------------------------------------------*/ +void ttfont_FontInfo(TTStreamWriter& stream, struct TTFONT *font) +{ + Fixed ItalicAngle; + + /* We create a sub dictionary named "FontInfo" where we */ + /* store information which though it is not used by the */ + /* interpreter, is useful to some programs which will */ + /* be printing with the font. */ + stream.putline("/FontInfo 10 dict dup begin"); + + /* These names come from the TrueType font's "name" table. */ + stream.printf("/FamilyName (%s) def\n",font->FamilyName); + stream.printf("/FullName (%s) def\n",font->FullName); + + if ( font->Copyright != (char*)NULL || font->Trademark != (char*)NULL ) + { + stream.printf("/Notice (%s", + font->Copyright != (char*)NULL ? font->Copyright : ""); + stream.printf("%s%s) def\n", + font->Trademark != (char*)NULL ? " " : "", + font->Trademark != (char*)NULL ? font->Trademark : ""); + } + + /* This information is not quite correct. */ + stream.printf("/Weight (%s) def\n",font->Style); + + /* Some fonts have this as "version". */ + stream.printf("/Version (%s) def\n",font->Version); + + /* Some information from the "post" table. */ + ItalicAngle = getFixed( font->post_table + 4 ); + stream.printf("/ItalicAngle %d.%d def\n",ItalicAngle.whole,ItalicAngle.fraction); + stream.printf("/isFixedPitch %s def\n", getULONG( font->post_table + 12 ) ? "true" : "false" ); + stream.printf("/UnderlinePosition %d def\n", (int)getFWord( font->post_table + 8 ) ); + stream.printf("/UnderlineThickness %d def\n", (int)getFWord( font->post_table + 10 ) ); + stream.putline("end readonly def"); +} /* end of ttfont_FontInfo() */ + +/*------------------------------------------------------------------- +** sfnts routines +** These routines generate the PostScript "sfnts" array which +** contains one or more strings which contain a reduced version +** of the TrueType font. +** +** A number of functions are required to accomplish this rather +** complicated task. +-------------------------------------------------------------------*/ +int string_len; +int line_len; +bool in_string; + +/* +** This is called once at the start. +*/ +void sfnts_start(TTStreamWriter& stream) +{ + stream.puts("/sfnts[<"); + in_string=true; + string_len=0; + line_len=8; +} /* end of sfnts_start() */ + +/* +** Write a BYTE as a hexadecimal value as part of the sfnts array. +*/ +void sfnts_pputBYTE(TTStreamWriter& stream, BYTE n) +{ + static const char hexdigits[]="0123456789ABCDEF"; + + if (!in_string) + { + stream.put_char('<'); + string_len=0; + line_len++; + in_string=true; + } + + stream.put_char( hexdigits[ n / 16 ] ); + stream.put_char( hexdigits[ n % 16 ] ); + string_len++; + line_len+=2; + + if (line_len > 70) + { + stream.put_char('\n'); + line_len=0; + } + +} /* end of sfnts_pputBYTE() */ + +/* +** Write a USHORT as a hexadecimal value as part of the sfnts array. +*/ +void sfnts_pputUSHORT(TTStreamWriter& stream, USHORT n) +{ + sfnts_pputBYTE(stream, n / 256); + sfnts_pputBYTE(stream, n % 256); +} /* end of sfnts_pputUSHORT() */ + +/* +** Write a ULONG as part of the sfnts array. +*/ +void sfnts_pputULONG(TTStreamWriter& stream, ULONG n) +{ + int x1,x2,x3; + + x1 = n % 256; + n /= 256; + x2 = n % 256; + n /= 256; + x3 = n % 256; + n /= 256; + + sfnts_pputBYTE(stream, n); + sfnts_pputBYTE(stream, x3); + sfnts_pputBYTE(stream, x2); + sfnts_pputBYTE(stream, x1); +} /* end of sfnts_pputULONG() */ + +/* +** This is called whenever it is +** necessary to end a string in the sfnts array. +** +** (The array must be broken into strings which are +** no longer than 64K characters.) +*/ +void sfnts_end_string(TTStreamWriter& stream) +{ + if (in_string) + { + string_len=0; /* fool sfnts_pputBYTE() */ + +#ifdef DEBUG_TRUETYPE_INLINE + puts("\n% dummy byte:\n"); +#endif + + sfnts_pputBYTE(stream, 0); /* extra byte for pre-2013 compatibility */ + stream.put_char('>'); + line_len++; + } + in_string=false; +} /* end of sfnts_end_string() */ + +/* +** This is called at the start of each new table. +** The argement is the length in bytes of the table +** which will follow. If the new table will not fit +** in the current string, a new one is started. +*/ +void sfnts_new_table(TTStreamWriter& stream, ULONG length) +{ + if ( (string_len + length) > 65528 ) + sfnts_end_string(stream); +} /* end of sfnts_new_table() */ + +/* +** We may have to break up the 'glyf' table. That is the reason +** why we provide this special routine to copy it into the sfnts +** array. +*/ +void sfnts_glyf_table(TTStreamWriter& stream, struct TTFONT *font, ULONG oldoffset, ULONG correct_total_length) +{ + ULONG off; + ULONG length; + int c; + ULONG total=0; /* running total of bytes written to table */ + int x; + bool loca_is_local=false; + debug("sfnts_glyf_table(font,%d)", (int)correct_total_length); + + if (font->loca_table == NULL) + { + font->loca_table = GetTable(font,"loca"); + loca_is_local = true; + } + + /* Seek to proper position in the file. */ + fseek( font->file, oldoffset, SEEK_SET ); + + /* Copy the glyphs one by one */ + for (x=0; x < font->numGlyphs; x++) + { + /* Read the glyph offset from the index-to-location table. */ + if (font->indexToLocFormat == 0) + { + off = getUSHORT( font->loca_table + (x * 2) ); + off *= 2; + length = getUSHORT( font->loca_table + ((x+1) * 2) ); + length *= 2; + length -= off; + } + else + { + off = getULONG( font->loca_table + (x * 4) ); + length = getULONG( font->loca_table + ((x+1) * 4) ); + length -= off; + } + debug("glyph length=%d",(int)length); + + /* Start new string if necessary. */ + sfnts_new_table( stream, (int)length ); + + /* + ** Make sure the glyph is padded out to a + ** two byte boundary. + */ + if ( length % 2 ) { + throw TTException("TrueType font contains a 'glyf' table without 2 byte padding"); + } + + /* Copy the bytes of the glyph. */ + while ( length-- ) + { + if ( (c = fgetc(font->file)) == EOF ) { + throw TTException("TrueType font may be corrupt (reason 6)"); + } + + sfnts_pputBYTE(stream, c); + total++; /* add to running total */ + } + + } + + if (loca_is_local) + { + free(font->loca_table); + font->loca_table = NULL; + } + + /* Pad out to full length from table directory */ + while ( total < correct_total_length ) + { + sfnts_pputBYTE(stream, 0); + total++; + } + +} /* end of sfnts_glyf_table() */ + +/* +** Here is the routine which ties it all together. +** +** Create the array called "sfnts" which +** holds the actual TrueType data. +*/ +void ttfont_sfnts(TTStreamWriter& stream, struct TTFONT *font) +{ + static const char *table_names[] = /* The names of all tables */ + { + /* which it is worth while */ + "cvt ", /* to include in a Type 42 */ + "fpgm", /* PostScript font. */ + "glyf", + "head", + "hhea", + "hmtx", + "loca", + "maxp", + "prep" + } ; + + struct /* The location of each of */ + { + ULONG oldoffset; /* the above tables. */ + ULONG newoffset; + ULONG length; + ULONG checksum; + } tables[9]; + + BYTE *ptr; /* A pointer into the origional table directory. */ + ULONG x,y; /* General use loop countes. */ + int c; /* Input character. */ + int diff; + ULONG nextoffset; + int count; /* How many `important' tables did we find? */ + + ptr = font->offset_table + 12; + nextoffset=0; + count=0; + + /* + ** Find the tables we want and store there vital + ** statistics in tables[]. + */ + ULONG num_tables_read = 0; /* Number of tables read from the directory */ + for (x = 0; x < 9; x++) { + do { + if (num_tables_read < font->numTables) { + /* There are still tables to read from ptr */ + diff = strncmp((char*)ptr, table_names[x], 4); + + if (diff > 0) { /* If we are past it. */ + tables[x].length = 0; + diff = 0; + } else if (diff < 0) { /* If we haven't hit it yet. */ + ptr += 16; + num_tables_read++; + } else if (diff == 0) { /* Here it is! */ + tables[x].newoffset = nextoffset; + tables[x].checksum = getULONG( ptr + 4 ); + tables[x].oldoffset = getULONG( ptr + 8 ); + tables[x].length = getULONG( ptr + 12 ); + nextoffset += ( ((tables[x].length + 3) / 4) * 4 ); + count++; + ptr += 16; + num_tables_read++; + } + } else { + /* We've read the whole table directory already */ + /* Some tables couldn't be found */ + tables[x].length = 0; + break; /* Proceed to next tables[x] */ + } + } while (diff != 0); + + } /* end of for loop which passes over the table directory */ + + /* Begin the sfnts array. */ + sfnts_start(stream); + + /* Generate the offset table header */ + /* Start by copying the TrueType version number. */ + ptr = font->offset_table; + for (x=0; x < 4; x++) + { + sfnts_pputBYTE( stream, *(ptr++) ); + } + + /* Now, generate those silly numTables numbers. */ + sfnts_pputUSHORT(stream, count); /* number of tables */ + + int search_range = 1; + int entry_sel = 0; + + while (search_range <= count) { + search_range <<= 1; + entry_sel++; + } + entry_sel = entry_sel > 0 ? entry_sel - 1 : 0; + search_range = (search_range >> 1) * 16; + int range_shift = count * 16 - search_range; + + sfnts_pputUSHORT(stream, search_range); /* searchRange */ + sfnts_pputUSHORT(stream, entry_sel); /* entrySelector */ + sfnts_pputUSHORT(stream, range_shift); /* rangeShift */ + + debug("only %d tables selected",count); + + /* Now, emmit the table directory. */ + for (x=0; x < 9; x++) + { + if ( tables[x].length == 0 ) /* Skip missing tables */ + { + continue; + } + + /* Name */ + sfnts_pputBYTE( stream, table_names[x][0] ); + sfnts_pputBYTE( stream, table_names[x][1] ); + sfnts_pputBYTE( stream, table_names[x][2] ); + sfnts_pputBYTE( stream, table_names[x][3] ); + + /* Checksum */ + sfnts_pputULONG( stream, tables[x].checksum ); + + /* Offset */ + sfnts_pputULONG( stream, tables[x].newoffset + 12 + (count * 16) ); + + /* Length */ + sfnts_pputULONG( stream, tables[x].length ); + } + + /* Now, send the tables */ + for (x=0; x < 9; x++) + { + if ( tables[x].length == 0 ) /* skip tables that aren't there */ + { + continue; + } + debug("emmiting table '%s'",table_names[x]); + + /* 'glyf' table gets special treatment */ + if ( strcmp(table_names[x],"glyf")==0 ) + { + sfnts_glyf_table(stream,font,tables[x].oldoffset,tables[x].length); + } + else /* Other tables may not exceed */ + { + /* 65535 bytes in length. */ + if ( tables[x].length > 65535 ) + { + throw TTException("TrueType font has a table which is too long"); + } + + /* Start new string if necessary. */ + sfnts_new_table(stream, tables[x].length); + + /* Seek to proper position in the file. */ + fseek( font->file, tables[x].oldoffset, SEEK_SET ); + + /* Copy the bytes of the table. */ + for ( y=0; y < tables[x].length; y++ ) + { + if ( (c = fgetc(font->file)) == EOF ) + { + throw TTException("TrueType font may be corrupt (reason 7)"); + } + + sfnts_pputBYTE(stream, c); + } + } + + /* Padd it out to a four byte boundary. */ + y=tables[x].length; + while ( (y % 4) != 0 ) + { + sfnts_pputBYTE(stream, 0); + y++; +#ifdef DEBUG_TRUETYPE_INLINE + puts("\n% pad byte:\n"); +#endif + } + + } /* End of loop for all tables */ + + /* Close the array. */ + sfnts_end_string(stream); + stream.putline("]def"); +} /* end of ttfont_sfnts() */ + +/*-------------------------------------------------------------- +** Create the CharStrings dictionary which will translate +** PostScript character names to TrueType font character +** indexes. +** +** If we are creating a type 3 instead of a type 42 font, +** this array will instead convert PostScript character names +** to executable proceedures. +--------------------------------------------------------------*/ +const char *Apple_CharStrings[]= +{ + ".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign", + "dollar","percent","ampersand","quotesingle","parenleft","parenright", + "asterisk","plus", "comma","hyphen","period","slash","zero","one","two", + "three","four","five","six","seven","eight","nine","colon","semicolon", + "less","equal","greater","question","at","A","B","C","D","E","F","G","H","I", + "J","K", "L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z", + "bracketleft","backslash","bracketright","asciicircum","underscore","grave", + "a","b","c","d","e","f","g","h","i","j","k", "l","m","n","o","p","q","r","s", + "t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde", + "Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis", + "aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla", + "eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex", + "idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde", + "uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent", + "sterling","section","bullet","paragraph","germandbls","registered", + "copyright","trademark","acute","dieresis","notequal","AE","Oslash", + "infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff", + "summation","product","pi","integral","ordfeminine","ordmasculine","Omega", + "ae","oslash","questiondown","exclamdown","logicalnot","radical","florin", + "approxequal","Delta","guillemotleft","guillemotright","ellipsis", + "nobreakspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash", + "quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge", + "ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright", + "fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase", + "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple", + "Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde", + "macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron", + "Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth", + "Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior", + "twosuperior","threesuperior","onehalf","onequarter","threequarters","franc", + "Gbreve","gbreve","Idot","Scedilla","scedilla","Cacute","cacute","Ccaron", + "ccaron","dmacron","markingspace","capslock","shift","propeller","enter", + "markingtabrtol","markingtabltor","control","markingdeleteltor", + "markingdeletertol","option","escape","parbreakltor","parbreakrtol", + "newpage","checkmark","linebreakltor","linebreakrtol","markingnobreakspace", + "diamond","appleoutline" +}; + +/* +** This routine is called by the one below. +** It is also called from pprdrv_tt2.c +*/ +const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex) +{ + int GlyphIndex; + static char temp[80]; + char *ptr; + ULONG len; + + Fixed post_format; + + /* The 'post' table format number. */ + post_format = getFixed( font->post_table ); + + if ( post_format.whole != 2 || post_format.fraction != 0 ) + { + /* We don't have a glyph name table, so generate a name. + This generated name must match exactly the name that is + generated by FT2Font in get_glyph_name */ + PyOS_snprintf(temp, 80, "uni%08x", charindex); + return temp; + } + + GlyphIndex = (int)getUSHORT( font->post_table + 34 + (charindex * 2) ); + + if ( GlyphIndex <= 257 ) /* If a standard Apple name, */ + { + return Apple_CharStrings[GlyphIndex]; + } + else /* Otherwise, use one */ + { + /* of the pascal strings. */ + GlyphIndex -= 258; + + /* Set pointer to start of Pascal strings. */ + ptr = (char*)(font->post_table + 34 + (font->numGlyphs * 2)); + + len = (ULONG)*(ptr++); /* Step thru the strings */ + while (GlyphIndex--) /* until we get to the one */ + { + /* that we want. */ + ptr += len; + len = (ULONG)*(ptr++); + } + + if ( len >= sizeof(temp) ) + { + throw TTException("TrueType font file contains a very long PostScript name"); + } + + strncpy(temp,ptr,len); /* Copy the pascal string into */ + temp[len]='\0'; /* a buffer and make it ASCIIz. */ + + return temp; + } +} /* end of ttfont_CharStrings_getname() */ + +/* +** This is the central routine of this section. +*/ +void ttfont_CharStrings(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids) +{ + Fixed post_format; + + /* The 'post' table format number. */ + post_format = getFixed( font->post_table ); + + /* Emmit the start of the PostScript code to define the dictionary. */ + stream.printf("/CharStrings %d dict dup begin\n", glyph_ids.size()+1); + /* Section 5.8.2 table 5.7 of the PS Language Ref says a CharStrings dictionary must contain an entry for .notdef */ + stream.printf("/.notdef 0 def\n"); + + /* Emmit one key-value pair for each glyph. */ + for (std::vector<int>::const_iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + if ((font->target_type == PS_TYPE_42 || + font->target_type == PS_TYPE_42_3_HYBRID) + && *i < 256) /* type 42 */ + { + stream.printf("/%s %d def\n",ttfont_CharStrings_getname(font, *i), *i); + } + else /* type 3 */ + { + stream.printf("/%s{",ttfont_CharStrings_getname(font, *i)); + + tt_type3_charproc(stream, font, *i); + + stream.putline("}_d"); /* "} bind def" */ + } + } + + stream.putline("end readonly def"); +} /* end of ttfont_CharStrings() */ + +/*---------------------------------------------------------------- +** Emmit the code to finish up the dictionary and turn +** it into a font. +----------------------------------------------------------------*/ +void ttfont_trailer(TTStreamWriter& stream, struct TTFONT *font) +{ + /* If we are generating a type 3 font, we need to provide */ + /* a BuildGlyph and BuildChar proceedures. */ + if (font->target_type == PS_TYPE_3 || + font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.put_char('\n'); + + stream.putline("/BuildGlyph"); + stream.putline(" {exch begin"); /* start font dictionary */ + stream.putline(" CharStrings exch"); + stream.putline(" 2 copy known not{pop /.notdef}if"); + stream.putline(" true 3 1 roll get exec"); + stream.putline(" end}_d"); + + stream.put_char('\n'); + + /* This proceedure is for compatibility with */ + /* level 1 interpreters. */ + stream.putline("/BuildChar {"); + stream.putline(" 1 index /Encoding get exch get"); + stream.putline(" 1 index /BuildGlyph get exec"); + stream.putline("}_d"); + + stream.put_char('\n'); + } + + /* If we are generating a type 42 font, we need to check to see */ + /* if this PostScript interpreter understands type 42 fonts. If */ + /* it doesn't, we will hope that the Apple TrueType rasterizer */ + /* has been loaded and we will adjust the font accordingly. */ + /* I found out how to do this by examining a TrueType font */ + /* generated by a Macintosh. That is where the TrueType interpreter */ + /* setup instructions and part of BuildGlyph came from. */ + if (font->target_type == PS_TYPE_42 || + font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.put_char('\n'); + + /* If we have no "resourcestatus" command, or FontType 42 */ + /* is unknown, leave "true" on the stack. */ + stream.putline("systemdict/resourcestatus known"); + stream.putline(" {42 /FontType resourcestatus"); + stream.putline(" {pop pop false}{true}ifelse}"); + stream.putline(" {true}ifelse"); + + /* If true, execute code to produce an error message if */ + /* we can't find Apple's TrueDict in VM. */ + stream.putline("{/TrueDict where{pop}{(%%[ Error: no TrueType rasterizer ]%%)= flush}ifelse"); + + /* Since we are expected to use Apple's TrueDict TrueType */ + /* reasterizer, change the font type to 3. */ + stream.putline("/FontType 3 def"); + + /* Define a string to hold the state of the Apple */ + /* TrueType interpreter. */ + stream.putline(" /TrueState 271 string def"); + + /* It looks like we get information about the resolution */ + /* of the printer and store it in the TrueState string. */ + stream.putline(" TrueDict begin sfnts save"); + stream.putline(" 72 0 matrix defaultmatrix dtransform dup"); + stream.putline(" mul exch dup mul add sqrt cvi 0 72 matrix"); + stream.putline(" defaultmatrix dtransform dup mul exch dup"); + stream.putline(" mul add sqrt cvi 3 -1 roll restore"); + stream.putline(" TrueState initer end"); + + /* This BuildGlyph procedure will look the name up in the */ + /* CharStrings array, and then check to see if what it gets */ + /* is a procedure. If it is, it executes it, otherwise, it */ + /* lets the TrueType rasterizer loose on it. */ + + /* When this proceedure is executed the stack contains */ + /* the font dictionary and the character name. We */ + /* exchange arguments and move the dictionary to the */ + /* dictionary stack. */ + stream.putline(" /BuildGlyph{exch begin"); + /* stack: charname */ + + /* Put two copies of CharStrings on the stack and consume */ + /* one testing to see if the charname is defined in it, */ + /* leave the answer on the stack. */ + stream.putline(" CharStrings dup 2 index known"); + /* stack: charname CharStrings bool */ + + /* Exchange the CharStrings dictionary and the charname, */ + /* but if the answer was false, replace the character name */ + /* with ".notdef". */ + stream.putline(" {exch}{exch pop /.notdef}ifelse"); + /* stack: CharStrings charname */ + + /* Get the value from the CharStrings dictionary and see */ + /* if it is executable. */ + stream.putline(" get dup xcheck"); + /* stack: CharStrings_entry */ + + /* If is a proceedure. Execute according to RBIIp 277-278. */ + stream.putline(" {currentdict systemdict begin begin exec end end}"); + + /* Is a TrueType character index, let the rasterizer at it. */ + stream.putline(" {TrueDict begin /bander load cvlit exch TrueState render end}"); + + stream.putline(" ifelse"); + + /* Pop the font's dictionary off the stack. */ + stream.putline(" end}bind def"); + + /* This is the level 1 compatibility BuildChar procedure. */ + /* See RBIIp 281. */ + stream.putline(" /BuildChar{"); + stream.putline(" 1 index /Encoding get exch get"); + stream.putline(" 1 index /BuildGlyph get exec"); + stream.putline(" }bind def"); + + /* Here we close the condition which is true */ + /* if the printer has no built-in TrueType */ + /* rasterizer. */ + stream.putline("}if"); + stream.put_char('\n'); + } /* end of if Type 42 not understood. */ + + stream.putline("FontName currentdict end definefont pop"); + /* stream.putline("%%EOF"); */ +} /* end of ttfont_trailer() */ + +/*------------------------------------------------------------------ +** This is the externally callable routine which inserts the font. +------------------------------------------------------------------*/ + +void read_font(const char *filename, font_type_enum target_type, std::vector<int>& glyph_ids, TTFONT& font) +{ + BYTE *ptr; + + /* Decide what type of PostScript font we will be generating. */ + font.target_type = target_type; + + if (font.target_type == PS_TYPE_42) + { + bool has_low = false; + bool has_high = false; + + for (std::vector<int>::const_iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + if (*i > 255) + { + has_high = true; + if (has_low) break; + } + else + { + has_low = true; + if (has_high) break; + } + } + + if (has_high && has_low) + { + font.target_type = PS_TYPE_42_3_HYBRID; + } + else if (has_high && !has_low) + { + font.target_type = PS_TYPE_3; + } + } + + /* Save the file name for error messages. */ + font.filename=filename; + + /* Open the font file */ + if ( (font.file = fopen(filename,"rb")) == (FILE*)NULL ) + { + throw TTException("Failed to open TrueType font"); + } + + /* Allocate space for the unvarying part of the offset table. */ + assert(font.offset_table == NULL); + font.offset_table = (BYTE*)calloc( 12, sizeof(BYTE) ); + + /* Read the first part of the offset table. */ + if ( fread( font.offset_table, sizeof(BYTE), 12, font.file ) != 12 ) + { + throw TTException("TrueType font may be corrupt (reason 1)"); + } + + /* Determine how many directory entries there are. */ + font.numTables = getUSHORT( font.offset_table + 4 ); + debug("numTables=%d",(int)font.numTables); + + /* Expand the memory block to hold the whole thing. */ + font.offset_table = (BYTE*)realloc( font.offset_table, sizeof(BYTE) * (12 + font.numTables * 16) ); + + /* Read the rest of the table directory. */ + if ( fread( font.offset_table + 12, sizeof(BYTE), (font.numTables*16), font.file ) != (font.numTables*16) ) + { + throw TTException("TrueType font may be corrupt (reason 2)"); + } + + /* Extract information from the "Offset" table. */ + font.TTVersion = getFixed( font.offset_table ); + + /* Load the "head" table and extract information from it. */ + ptr = GetTable(&font, "head"); + try + { + font.MfrRevision = getFixed( ptr + 4 ); /* font revision number */ + font.unitsPerEm = getUSHORT( ptr + 18 ); + font.HUPM = font.unitsPerEm / 2; + debug("unitsPerEm=%d",(int)font.unitsPerEm); + font.llx = topost2( getFWord( ptr + 36 ) ); /* bounding box info */ + font.lly = topost2( getFWord( ptr + 38 ) ); + font.urx = topost2( getFWord( ptr + 40 ) ); + font.ury = topost2( getFWord( ptr + 42 ) ); + font.indexToLocFormat = getSHORT( ptr + 50 ); /* size of 'loca' data */ + if (font.indexToLocFormat != 0 && font.indexToLocFormat != 1) + { + throw TTException("TrueType font is unusable because indexToLocFormat != 0"); + } + if ( getSHORT(ptr+52) != 0 ) + { + throw TTException("TrueType font is unusable because glyphDataFormat != 0"); + } + } + catch (TTException& ) + { + free(ptr); + throw; + } + free(ptr); + + /* Load information from the "name" table. */ + Read_name(&font); + + /* We need to have the PostScript table around. */ + assert(font.post_table == NULL); + font.post_table = GetTable(&font, "post"); + font.numGlyphs = getUSHORT( font.post_table + 32 ); + + /* If we are generating a Type 3 font, we will need to */ + /* have the 'loca' and 'glyf' tables arround while */ + /* we are generating the CharStrings. */ + if (font.target_type == PS_TYPE_3 || font.target_type == PS_TYPE_42_3_HYBRID) + { + BYTE *ptr; /* We need only one value */ + ptr = GetTable(&font, "hhea"); + font.numberOfHMetrics = getUSHORT(ptr + 34); + free(ptr); + + assert(font.loca_table == NULL); + font.loca_table = GetTable(&font,"loca"); + assert(font.glyf_table == NULL); + font.glyf_table = GetTable(&font,"glyf"); + assert(font.hmtx_table == NULL); + font.hmtx_table = GetTable(&font,"hmtx"); + } + + if (glyph_ids.size() == 0) + { + glyph_ids.clear(); + glyph_ids.reserve(font.numGlyphs); + for (int x = 0; x < font.numGlyphs; ++x) + { + glyph_ids.push_back(x); + } + } + else if (font.target_type == PS_TYPE_3 || + font.target_type == PS_TYPE_42_3_HYBRID) + { + ttfont_add_glyph_dependencies(&font, glyph_ids); + } + +} /* end of insert_ttfont() */ + +void insert_ttfont(const char *filename, TTStreamWriter& stream, + font_type_enum target_type, std::vector<int>& glyph_ids) +{ + struct TTFONT font; + + read_font(filename, target_type, glyph_ids, font); + + /* Write the header for the PostScript font. */ + ttfont_header(stream, &font); + + /* Define the encoding. */ + ttfont_encoding(stream, &font, glyph_ids, target_type); + + /* Insert FontInfo dictionary. */ + ttfont_FontInfo(stream, &font); + + /* If we are generating a type 42 font, */ + /* emmit the sfnts array. */ + if (font.target_type == PS_TYPE_42 || + font.target_type == PS_TYPE_42_3_HYBRID) + { + ttfont_sfnts(stream, &font); + } + + /* Emmit the CharStrings array. */ + ttfont_CharStrings(stream, &font, glyph_ids); + + /* Send the font trailer. */ + ttfont_trailer(stream, &font); + +} /* end of insert_ttfont() */ + +TTFONT::TTFONT() : + file(NULL), + PostName(NULL), + FullName(NULL), + FamilyName(NULL), + Style(NULL), + Copyright(NULL), + Version(NULL), + Trademark(NULL), + offset_table(NULL), + post_table(NULL), + loca_table(NULL), + glyf_table(NULL), + hmtx_table(NULL) +{ + +} + +TTFONT::~TTFONT() +{ + if (file) + { + fclose(file); + } + free(PostName); + free(FullName); + free(FamilyName); + free(Style); + free(Copyright); + free(Version); + free(Trademark); + free(offset_table); + free(post_table); + free(loca_table); + free(glyf_table); + free(hmtx_table); +} + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp new file mode 100644 index 0000000000..ec2298c8c4 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp @@ -0,0 +1,693 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* +** ~ppr/src/pprdrv/pprdrv_tt2.c +** Copyright 1995, Trinity College Computing Center. +** Written by David Chappell. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** TrueType font support. These functions allow PPR to generate +** PostScript fonts from Microsoft compatible TrueType font files. +** +** The functions in this file do most of the work to convert a +** TrueType font to a type 3 PostScript font. +** +** Most of the material in this file is derived from a program called +** "ttf2ps" which L. S. Ng posted to the usenet news group +** "comp.sources.postscript". The author did not provide a copyright +** notice or indicate any restrictions on use. +** +** Last revised 11 July 1995. +*/ + +#include <cstdlib> +#include <cmath> +#include <cstring> +#include <memory> +#include "pprdrv.h" +#include "truetype.h" +#include <algorithm> +#include <stack> +#include <list> + +class GlyphToType3 +{ +private: + GlyphToType3& operator=(const GlyphToType3& other); + GlyphToType3(const GlyphToType3& other); + + /* The PostScript bounding box. */ + int llx,lly,urx,ury; + int advance_width; + + /* Variables to hold the character data. */ + int *epts_ctr; /* array of contour endpoints */ + int num_pts, num_ctr; /* number of points, number of coutours */ + FWord *xcoor, *ycoor; /* arrays of x and y coordinates */ + BYTE *tt_flags; /* array of TrueType flags */ + + int stack_depth; /* A book-keeping variable for keeping track of the depth of the PS stack */ + + void load_char(TTFONT* font, BYTE *glyph); + void stack(TTStreamWriter& stream, int new_elem); + void stack_end(TTStreamWriter& stream); + void PSConvert(TTStreamWriter& stream); + void PSCurveto(TTStreamWriter& stream, + FWord x0, FWord y0, + FWord x1, FWord y1, + FWord x2, FWord y2); + void PSMoveto(TTStreamWriter& stream, int x, int y); + void PSLineto(TTStreamWriter& stream, int x, int y); + void do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph); + +public: + GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded = false); + ~GlyphToType3(); +}; + +// Each point on a TrueType contour is either on the path or off it (a +// control point); here's a simple representation for building such +// contours. Added by Jouni Seppänen 2012-05-27. +enum Flag { ON_PATH, OFF_PATH }; +struct FlaggedPoint +{ + enum Flag flag; + FWord x; + FWord y; + FlaggedPoint(Flag flag_, FWord x_, FWord y_): flag(flag_), x(x_), y(y_) {}; +}; + +/* +** This routine is used to break the character +** procedure up into a number of smaller +** procedures. This is necessary so as not to +** overflow the stack on certain level 1 interpreters. +** +** Prepare to push another item onto the stack, +** starting a new proceedure if necessary. +** +** Not all the stack depth calculations in this routine +** are perfectly accurate, but they do the job. +*/ +void GlyphToType3::stack(TTStreamWriter& stream, int new_elem) +{ + if ( num_pts > 25 ) /* Only do something of we will have a log of points. */ + { + if (stack_depth == 0) + { + stream.put_char('{'); + stack_depth=1; + } + + stack_depth += new_elem; /* Account for what we propose to add */ + + if (stack_depth > 100) + { + stream.puts("}_e{"); + stack_depth = 3 + new_elem; /* A rough estimate */ + } + } +} /* end of stack() */ + +void GlyphToType3::stack_end(TTStreamWriter& stream) /* called at end */ +{ + if ( stack_depth ) + { + stream.puts("}_e"); + stack_depth=0; + } +} /* end of stack_end() */ + +/* +** We call this routine to emmit the PostScript code +** for the character we have loaded with load_char(). +*/ +void GlyphToType3::PSConvert(TTStreamWriter& stream) +{ + int j, k; + + /* Step thru the contours. + * j = index to xcoor, ycoor, tt_flags (point data) + * k = index to epts_ctr (which points belong to the same contour) */ + for(j = k = 0; k < num_ctr; k++) + { + // A TrueType contour consists of on-path and off-path points. + // Two consecutive on-path points are to be joined with a + // line; off-path points between on-path points indicate a + // quadratic spline, where the off-path point is the control + // point. Two consecutive off-path points have an implicit + // on-path point midway between them. + std::list<FlaggedPoint> points; + + // Represent flags and x/y coordinates as a C++ list + for (; j <= epts_ctr[k]; j++) + { + if (!(tt_flags[j] & 1)) { + points.push_back(FlaggedPoint(OFF_PATH, xcoor[j], ycoor[j])); + } else { + points.push_back(FlaggedPoint(ON_PATH, xcoor[j], ycoor[j])); + } + } + + if (points.size() == 0) { + // Don't try to access the last element of an empty list + continue; + } + + // For any two consecutive off-path points, insert the implied + // on-path point. + FlaggedPoint prev = points.back(); + for (std::list<FlaggedPoint>::iterator it = points.begin(); + it != points.end(); + it++) + { + if (prev.flag == OFF_PATH && it->flag == OFF_PATH) + { + points.insert(it, + FlaggedPoint(ON_PATH, + (prev.x + it->x) / 2, + (prev.y + it->y) / 2)); + } + prev = *it; + } + // Handle the wrap-around: insert a point either at the beginning + // or at the end that has the same coordinates as the opposite point. + // This also ensures that the initial point is ON_PATH. + if (points.front().flag == OFF_PATH) + { + assert(points.back().flag == ON_PATH); + points.insert(points.begin(), points.back()); + } + else + { + assert(points.front().flag == ON_PATH); + points.push_back(points.front()); + } + + // The first point + stack(stream, 3); + PSMoveto(stream, points.front().x, points.front().y); + + // Step through the remaining points + std::list<FlaggedPoint>::const_iterator it = points.begin(); + for (it++; it != points.end(); /* incremented inside */) + { + const FlaggedPoint& point = *it; + if (point.flag == ON_PATH) + { + stack(stream, 3); + PSLineto(stream, point.x, point.y); + it++; + } else { + std::list<FlaggedPoint>::const_iterator prev = it, next = it; + prev--; + next++; + assert(prev->flag == ON_PATH); + assert(next->flag == ON_PATH); + stack(stream, 7); + PSCurveto(stream, + prev->x, prev->y, + point.x, point.y, + next->x, next->y); + it++; + it++; + } + } + } + + /* Now, we can fill the whole thing. */ + stack(stream, 1); + stream.puts("_cl"); +} /* end of PSConvert() */ + +void GlyphToType3::PSMoveto(TTStreamWriter& stream, int x, int y) +{ + stream.printf("%d %d _m\n", x, y); +} + +void GlyphToType3::PSLineto(TTStreamWriter& stream, int x, int y) +{ + stream.printf("%d %d _l\n", x, y); +} + +/* +** Emit a PostScript "curveto" command, assuming the current point +** is (x0, y0), the control point of a quadratic spline is (x1, y1), +** and the endpoint is (x2, y2). Note that this requires a conversion, +** since PostScript splines are cubic. +*/ +void GlyphToType3::PSCurveto(TTStreamWriter& stream, + FWord x0, FWord y0, + FWord x1, FWord y1, + FWord x2, FWord y2) +{ + double sx[3], sy[3], cx[3], cy[3]; + + sx[0] = x0; + sy[0] = y0; + sx[1] = x1; + sy[1] = y1; + sx[2] = x2; + sy[2] = y2; + cx[0] = (2*sx[1]+sx[0])/3; + cy[0] = (2*sy[1]+sy[0])/3; + cx[1] = (sx[2]+2*sx[1])/3; + cy[1] = (sy[2]+2*sy[1])/3; + cx[2] = sx[2]; + cy[2] = sy[2]; + stream.printf("%d %d %d %d %d %d _c\n", + (int)cx[0], (int)cy[0], (int)cx[1], (int)cy[1], + (int)cx[2], (int)cy[2]); +} + +/* +** Deallocate the structures which stored +** the data for the last simple glyph. +*/ +GlyphToType3::~GlyphToType3() +{ + free(tt_flags); /* The flags array */ + free(xcoor); /* The X coordinates */ + free(ycoor); /* The Y coordinates */ + free(epts_ctr); /* The array of contour endpoints */ +} + +/* +** Load the simple glyph data pointed to by glyph. +** The pointer "glyph" should point 10 bytes into +** the glyph data. +*/ +void GlyphToType3::load_char(TTFONT* font, BYTE *glyph) +{ + int x; + BYTE c, ct; + + /* Read the contour endpoints list. */ + epts_ctr = (int *)calloc(num_ctr,sizeof(int)); + for (x = 0; x < num_ctr; x++) + { + epts_ctr[x] = getUSHORT(glyph); + glyph += 2; + } + + /* From the endpoint of the last contour, we can */ + /* determine the number of points. */ + num_pts = epts_ctr[num_ctr-1]+1; +#ifdef DEBUG_TRUETYPE + debug("num_pts=%d",num_pts); + stream.printf("%% num_pts=%d\n",num_pts); +#endif + + /* Skip the instructions. */ + x = getUSHORT(glyph); + glyph += 2; + glyph += x; + + /* Allocate space to hold the data. */ + tt_flags = (BYTE *)calloc(num_pts,sizeof(BYTE)); + xcoor = (FWord *)calloc(num_pts,sizeof(FWord)); + ycoor = (FWord *)calloc(num_pts,sizeof(FWord)); + + /* Read the flags array, uncompressing it as we go. */ + /* There is danger of overflow here. */ + for (x = 0; x < num_pts; ) + { + tt_flags[x++] = c = *(glyph++); + + if (c&8) /* If next byte is repeat count, */ + { + ct = *(glyph++); + + if ( (x + ct) > num_pts ) + { + throw TTException("Error in TT flags"); + } + + while (ct--) + { + tt_flags[x++] = c; + } + } + } + + /* Read the x coordinates */ + for (x = 0; x < num_pts; x++) + { + if (tt_flags[x] & 2) /* one byte value with */ + { + /* external sign */ + c = *(glyph++); + xcoor[x] = (tt_flags[x] & 0x10) ? c : (-1 * (int)c); + } + else if (tt_flags[x] & 0x10) /* repeat last */ + { + xcoor[x] = 0; + } + else /* two byte signed value */ + { + xcoor[x] = getFWord(glyph); + glyph+=2; + } + } + + /* Read the y coordinates */ + for (x = 0; x < num_pts; x++) + { + if (tt_flags[x] & 4) /* one byte value with */ + { + /* external sign */ + c = *(glyph++); + ycoor[x] = (tt_flags[x] & 0x20) ? c : (-1 * (int)c); + } + else if (tt_flags[x] & 0x20) /* repeat last value */ + { + ycoor[x] = 0; + } + else /* two byte signed value */ + { + ycoor[x] = getUSHORT(glyph); + glyph+=2; + } + } + + /* Convert delta values to absolute values. */ + for (x = 1; x < num_pts; x++) + { + xcoor[x] += xcoor[x-1]; + ycoor[x] += ycoor[x-1]; + } + + for (x=0; x < num_pts; x++) + { + xcoor[x] = topost(xcoor[x]); + ycoor[x] = topost(ycoor[x]); + } + +} /* end of load_char() */ + +/* +** Emmit PostScript code for a composite character. +*/ +void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph) +{ + USHORT flags; + USHORT glyphIndex; + int arg1; + int arg2; + + /* Once around this loop for each component. */ + do + { + flags = getUSHORT(glyph); /* read the flags word */ + glyph += 2; + + glyphIndex = getUSHORT(glyph); /* read the glyphindex word */ + glyph += 2; + + if (flags & ARG_1_AND_2_ARE_WORDS) + { + /* The tt spec. seems to say these are signed. */ + arg1 = getSHORT(glyph); + glyph += 2; + arg2 = getSHORT(glyph); + glyph += 2; + } + else /* The tt spec. does not clearly indicate */ + { + /* whether these values are signed or not. */ + arg1 = *(signed char *)(glyph++); + arg2 = *(signed char *)(glyph++); + } + + if (flags & WE_HAVE_A_SCALE) + { + glyph += 2; + } + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) + { + glyph += 4; + } + else if (flags & WE_HAVE_A_TWO_BY_TWO) + { + glyph += 8; + } + else + { + } + + /* Debugging */ +#ifdef DEBUG_TRUETYPE + stream.printf("%% flags=%d, arg1=%d, arg2=%d\n", + (int)flags,arg1,arg2); +#endif + + /* If we have an (X,Y) shift and it is non-zero, */ + /* translate the coordinate system. */ + if ( flags & ARGS_ARE_XY_VALUES ) + { + if ( arg1 != 0 || arg2 != 0 ) + stream.printf("gsave %d %d translate\n", topost(arg1), topost(arg2) ); + } + else + { + stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2); + } + + /* Invoke the CharStrings procedure to print the component. */ + stream.printf("false CharStrings /%s get exec\n", + ttfont_CharStrings_getname(font, glyphIndex)); + + /* If we translated the coordinate system, */ + /* put it back the way it was. */ + if ( flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) ) + { + stream.puts("grestore "); + } + + } + while (flags & MORE_COMPONENTS); + +} /* end of do_composite() */ + +/* +** Return a pointer to a specific glyph's data. +*/ +BYTE *find_glyph_data(struct TTFONT *font, int charindex) +{ + ULONG off; + ULONG length; + + /* Read the glyph offset from the index to location table. */ + if (font->indexToLocFormat == 0) + { + off = getUSHORT( font->loca_table + (charindex * 2) ); + off *= 2; + length = getUSHORT( font->loca_table + ((charindex+1) * 2) ); + length *= 2; + length -= off; + } + else + { + off = getULONG( font->loca_table + (charindex * 4) ); + length = getULONG( font->loca_table + ((charindex+1) * 4) ); + length -= off; + } + + if (length > 0) + { + return font->glyf_table + off; + } + else + { + return (BYTE*)NULL; + } + +} /* end of find_glyph_data() */ + +GlyphToType3::GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded /* = false */) +{ + BYTE *glyph; + + tt_flags = NULL; + xcoor = NULL; + ycoor = NULL; + epts_ctr = NULL; + stack_depth = 0; + + /* Get a pointer to the data. */ + glyph = find_glyph_data( font, charindex ); + + /* If the character is blank, it has no bounding box, */ + /* otherwise read the bounding box. */ + if ( glyph == (BYTE*)NULL ) + { + llx=lly=urx=ury=0; /* A blank char has an all zero BoundingBox */ + num_ctr=0; /* Set this for later if()s */ + } + else + { + /* Read the number of contours. */ + num_ctr = getSHORT(glyph); + + /* Read PostScript bounding box. */ + llx = getFWord(glyph + 2); + lly = getFWord(glyph + 4); + urx = getFWord(glyph + 6); + ury = getFWord(glyph + 8); + + /* Advance the pointer. */ + glyph += 10; + } + + /* If it is a simple character, load its data. */ + if (num_ctr > 0) + { + load_char(font, glyph); + } + else + { + num_pts=0; + } + + /* Consult the horizontal metrics table to determine */ + /* the character width. */ + if ( charindex < font->numberOfHMetrics ) + { + advance_width = getuFWord( font->hmtx_table + (charindex * 4) ); + } + else + { + advance_width = getuFWord( font->hmtx_table + ((font->numberOfHMetrics-1) * 4) ); + } + + /* Execute setcachedevice in order to inform the font machinery */ + /* of the character bounding box and advance width. */ + stack(stream, 7); + if (font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("pop gsave .001 .001 scale %d 0 %d %d %d %d setcachedevice\n", + topost(advance_width), + topost(llx), topost(lly), topost(urx), topost(ury) ); + } + else + { + stream.printf("%d 0 %d %d %d %d _sc\n", + topost(advance_width), + topost(llx), topost(lly), topost(urx), topost(ury) ); + } + + /* If it is a simple glyph, convert it, */ + /* otherwise, close the stack business. */ + if ( num_ctr > 0 ) /* simple */ + { + PSConvert(stream); + } + else if ( num_ctr < 0 ) /* composite */ + { + do_composite(stream, font, glyph); + } + + if (font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("\ngrestore\n"); + } + + stack_end(stream); +} + +/* +** This is the routine which is called from pprdrv_tt.c. +*/ +void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex) +{ + GlyphToType3 glyph(stream, font, charindex); +} /* end of tt_type3_charproc() */ + +/* +** Some of the given glyph ids may refer to composite glyphs. +** This function adds all of the dependencies of those composite +** glyphs to the glyph id vector. Michael Droettboom [06-07-07] +*/ +void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_ids) +{ + std::sort(glyph_ids.begin(), glyph_ids.end()); + + std::stack<int> glyph_stack; + for (std::vector<int>::iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + glyph_stack.push(*i); + } + + while (glyph_stack.size()) + { + int gind = glyph_stack.top(); + glyph_stack.pop(); + + BYTE* glyph = find_glyph_data( font, gind ); + if (glyph != (BYTE*)NULL) + { + + int num_ctr = getSHORT(glyph); + if (num_ctr <= 0) // This is a composite glyph + { + + glyph += 10; + USHORT flags = 0; + + do + { + flags = getUSHORT(glyph); + glyph += 2; + gind = (int)getUSHORT(glyph); + glyph += 2; + + std::vector<int>::iterator insertion = + std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind); + if (insertion == glyph_ids.end() || *insertion != gind) + { + glyph_ids.insert(insertion, gind); + glyph_stack.push(gind); + } + + if (flags & ARG_1_AND_2_ARE_WORDS) + { + glyph += 4; + } + else + { + glyph += 2; + } + + if (flags & WE_HAVE_A_SCALE) + { + glyph += 2; + } + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) + { + glyph += 4; + } + else if (flags & WE_HAVE_A_TWO_BY_TWO) + { + glyph += 8; + } + } + while (flags & MORE_COMPONENTS); + } + } + } +} + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/truetype.h b/contrib/python/matplotlib/py3/extern/ttconv/truetype.h new file mode 100644 index 0000000000..86be14fe37 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/truetype.h @@ -0,0 +1,129 @@ +/* -*- mode: c; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +#include <stdio.h> + +/* +** ~ppr/src/include/typetype.h +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** This include file is shared by the source files +** "pprdrv/pprdrv_tt.c" and "pprdrv/pprdrv_tt2.c". +** +** Last modified 19 April 1995. +*/ + +/* Types used in TrueType font files. */ +#define BYTE unsigned char +#define USHORT unsigned short int +#define SHORT short signed int +#define ULONG unsigned int +#define FIXED long signed int +#define FWord short signed int +#define uFWord short unsigned int + +/* This structure stores a 16.16 bit fixed */ +/* point number. */ +typedef struct + { + short int whole; + unsigned short int fraction; + } Fixed; + +/* This structure tells what we have found out about */ +/* the current font. */ +struct TTFONT + { + // A quick-and-dirty way to create a minimum level of exception safety + // Added by Michael Droettboom + TTFONT(); + ~TTFONT(); + + const char *filename; /* Name of TT file */ + FILE *file; /* the open TT file */ + font_type_enum target_type; /* 42 or 3 for PS, or -3 for PDF */ + + ULONG numTables; /* number of tables present */ + char *PostName; /* Font's PostScript name */ + char *FullName; /* Font's full name */ + char *FamilyName; /* Font's family name */ + char *Style; /* Font's style string */ + char *Copyright; /* Font's copyright string */ + char *Version; /* Font's version string */ + char *Trademark; /* Font's trademark string */ + int llx,lly,urx,ury; /* bounding box */ + + Fixed TTVersion; /* Truetype version number from offset table */ + Fixed MfrRevision; /* Revision number of this font */ + + BYTE *offset_table; /* Offset table in memory */ + BYTE *post_table; /* 'post' table in memory */ + + BYTE *loca_table; /* 'loca' table in memory */ + BYTE *glyf_table; /* 'glyf' table in memory */ + BYTE *hmtx_table; /* 'hmtx' table in memory */ + + USHORT numberOfHMetrics; + int unitsPerEm; /* unitsPerEm converted to int */ + int HUPM; /* half of above */ + + int numGlyphs; /* from 'post' table */ + + int indexToLocFormat; /* short or long offsets */ +}; + +ULONG getULONG(BYTE *p); +USHORT getUSHORT(BYTE *p); +Fixed getFixed(BYTE *p); + +/* +** Get an funits word. +** since it is 16 bits long, we can +** use getUSHORT() to do the real work. +*/ +#define getFWord(x) (FWord)getUSHORT(x) +#define getuFWord(x) (uFWord)getUSHORT(x) + +/* +** We can get a SHORT by making USHORT signed. +*/ +#define getSHORT(x) (SHORT)getUSHORT(x) + +/* This is the one routine in pprdrv_tt.c that is */ +/* called from pprdrv_tt.c. */ +const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex); + +void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex); + +/* Added 06-07-07 Michael Droettboom */ +void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glypy_ids); + +/* This routine converts a number in the font's character coordinate */ +/* system to a number in a 1000 unit character system. */ +#define topost(x) (int)( ((int)(x) * 1000 + font->HUPM) / font->unitsPerEm ) +#define topost2(x) (int)( ((int)(x) * 1000 + font.HUPM) / font.unitsPerEm ) + +/* Composite glyph values. */ +#define ARG_1_AND_2_ARE_WORDS 1 +#define ARGS_ARE_XY_VALUES 2 +#define ROUND_XY_TO_GRID 4 +#define WE_HAVE_A_SCALE 8 +/* RESERVED 16 */ +#define MORE_COMPONENTS 32 +#define WE_HAVE_AN_X_AND_Y_SCALE 64 +#define WE_HAVE_A_TWO_BY_TWO 128 +#define WE_HAVE_INSTRUCTIONS 256 +#define USE_MY_METRICS 512 + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp b/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp new file mode 100644 index 0000000000..6028e1d45d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp @@ -0,0 +1,71 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* Very simple interface to the ppr TT routines */ +/* (c) Frank Siegert 1996 */ + +#include <cstdio> +#include <cstdarg> +#include <cstdlib> +#include "pprdrv.h" + +#define PRINTF_BUFFER_SIZE 512 +void TTStreamWriter::printf(const char* format, ...) +{ + va_list arg_list; + va_start(arg_list, format); + char buffer[PRINTF_BUFFER_SIZE]; + +#if defined(WIN32) || defined(_MSC_VER) + int size = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list); +#else + int size = vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list); +#endif + if (size >= PRINTF_BUFFER_SIZE) { + char* buffer2 = (char*)malloc(size); +#if defined(WIN32) || defined(_MSC_VER) + _vsnprintf(buffer2, size, format, arg_list); +#else + vsnprintf(buffer2, size, format, arg_list); +#endif + this->write(buffer2); + free(buffer2); + } else { + this->write(buffer); + } + + va_end(arg_list); +} + +void TTStreamWriter::put_char(int val) +{ + char c[2]; + c[0] = (char)val; + c[1] = 0; + this->write(c); +} + +void TTStreamWriter::puts(const char *a) +{ + this->write(a); +} + +void TTStreamWriter::putline(const char *a) +{ + this->write(a); + this->write("\n"); +} + +void replace_newlines_with_spaces(char *a) { + char* i = a; + while (*i != 0) { + if (*i == '\r' || *i == '\n') + *i = ' '; + i++; + } +} diff --git a/contrib/python/matplotlib/py3/extern/ttconv/ya.make b/contrib/python/matplotlib/py3/extern/ttconv/ya.make new file mode 100644 index 0000000000..bd5fca39b2 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/ya.make @@ -0,0 +1,13 @@ +PY23_LIBRARY() + +LICENSE(PSF-2.0) + +NO_COMPILER_WARNINGS() + +SRCS( + pprdrv_tt.cpp + pprdrv_tt2.cpp + ttutil.cpp +) + +END() |