diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2010-01-03 16:24:11 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2010-01-03 16:24:11 (GMT) |
commit | 497b85748d56fb3aa77b7f62ea9eaf98d49f6e22 (patch) | |
tree | da5c9fd647a371b5d775043a16d581a195e74f82 /generic | |
parent | bcf3d9f03773bc0637c730660eb32b008a923422 (diff) | |
download | tk-497b85748d56fb3aa77b7f62ea9eaf98d49f6e22.zip tk-497b85748d56fb3aa77b7f62ea9eaf98d49f6e22.tar.gz tk-497b85748d56fb3aa77b7f62ea9eaf98d49f6e22.tar.bz2 |
Simplify the postscript generation.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkCanvPs.c | 28 | ||||
-rw-r--r-- | generic/tkFont.c | 178 |
2 files changed, 105 insertions, 101 deletions
diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c index d397b9a..33bc89d 100644 --- a/generic/tkCanvPs.c +++ b/generic/tkCanvPs.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvPs.c,v 1.27 2009/05/01 15:04:03 dkf Exp $ + * RCS: @(#) $Id: tkCanvPs.c,v 1.28 2010/01/03 16:24:13 dkf Exp $ */ #include "tkInt.h" @@ -178,7 +178,7 @@ TkCanvPostscriptCmd( Tcl_HashSearch search; Tcl_HashEntry *hPtr; Tcl_DString buffer; - static const char *psenccmd = "::tk::ensure_psenc_is_loaded"; + Tcl_Obj *preambleObj; int deltaX = 0, deltaY = 0; /* Offset of lower-left corner of area to be * marked up, measured in canvas units from * the positioning point on the page (reflects @@ -186,14 +186,28 @@ TkCanvPostscriptCmd( * only to stop compiler warnings. */ /* - * Initialize the data structure describing Postscript generation, then - * process all the arguments to fill the data structure in. + * Get the generic preamble. We only ever bother with the ASCII encoding; + * the others just make life too complicated and never actually worked as + * such. */ - result = Tcl_EvalEx(interp, psenccmd, -1, TCL_EVAL_GLOBAL); + result = Tcl_Eval(interp, "::tk::ensure_psenc_is_loaded"); if (result != TCL_OK) { return result; } + preambleObj = Tcl_GetVar2Ex(interp, "::tk::ps_preamble", NULL, + TCL_LEAVE_ERR_MSG); + if (preambleObj == NULL) { + return TCL_ERROR; + } + Tcl_IncrRefCount(preambleObj); + Tcl_ResetResult(interp); + + /* + * Initialize the data structure describing Postscript generation, then + * process all the arguments to fill the data structure in. + */ + oldInfoPtr = canvasPtr->psInfo; canvasPtr->psInfo = (Tk_PostscriptInfo) psInfoPtr; psInfo.x = canvasPtr->xOrigin; @@ -460,8 +474,7 @@ TkCanvPostscriptCmd( * Insert the prolog */ - Tcl_AppendResult(interp, Tcl_GetVar(interp, "::tk::ps_preamable", - TCL_GLOBAL_ONLY), NULL); + Tcl_AppendResult(interp, Tcl_GetString(preambleObj), NULL); if (psInfo.chan != NULL) { Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1); @@ -602,6 +615,7 @@ TkCanvPostscriptCmd( } Tcl_DeleteHashTable(&psInfo.fontTable); canvasPtr->psInfo = (Tk_PostscriptInfo) oldInfoPtr; + Tcl_DecrRefCount(preambleObj); return result; } diff --git a/generic/tkFont.c b/generic/tkFont.c index 749f64b..76895e3 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -10,13 +10,13 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFont.c,v 1.62 2010/01/02 22:52:38 dkf Exp $ + * RCS: @(#) $Id: tkFont.c,v 1.63 2010/01/03 16:24:13 dkf Exp $ */ #include "tkInt.h" #include "tkFont.h" -#define ROUND16(x) ((short)((x) + 0.5)) +#define ROUND16(x) ((short)((x) + 0.5)) /* * The following structure is used to keep track of all the fonts that exist @@ -417,9 +417,8 @@ TkFontPkgFree( TkFontInfo *fiPtr = mainPtr->fontInfoPtr; Tcl_HashEntry *hPtr, *searchPtr; Tcl_HashSearch search; - int fontsLeft; + int fontsLeft = 0; - fontsLeft = 0; for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search); searchPtr != NULL; searchPtr = Tcl_NextHashEntry(&search)) { @@ -440,7 +439,7 @@ TkFontPkgFree( hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); while (hPtr != NULL) { - ckfree((char *) Tcl_GetHashValue(hPtr)); + ckfree(Tcl_GetHashValue(hPtr)); hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fiPtr->namedTable); @@ -476,7 +475,7 @@ Tk_FontObjCmd( { int index; Tk_Window tkwin = clientData; - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; static const char *const optionStrings[] = { "actual", "configure", "create", "delete", "families", "measure", "metrics", "names", @@ -487,8 +486,6 @@ Tk_FontObjCmd( FONT_FAMILIES, FONT_MEASURE, FONT_METRICS, FONT_NAMES }; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); return TCL_ERROR; @@ -640,13 +637,12 @@ Tk_FontObjCmd( return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); } case FONT_CREATE: { - int skip, i; + int skip = 3, i; const char *name; char buf[16 + TCL_INTEGER_SPACE]; TkFontAttributes fa; Tcl_HashEntry *namedHashPtr; - skip = 3; if (objc < 3) { name = NULL; } else { @@ -701,9 +697,8 @@ Tk_FontObjCmd( return result; } case FONT_FAMILIES: { - int skip; + int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); - skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); if (skip < 0) { return TCL_ERROR; } @@ -726,7 +721,8 @@ Tk_FontObjCmd( } } if (objc - skip != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "font ?-displayof window? text"); + Tcl_WrongNumArgs(interp, 2, objv, + "font ?-displayof window? text"); return TCL_ERROR; } tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); @@ -844,9 +840,8 @@ UpdateDependentFonts( Tcl_HashEntry *cacheHashPtr; Tcl_HashSearch search; TkFont *fontPtr; - NamedFont *nfPtr; + NamedFont *nfPtr = Tcl_GetHashValue(namedHashPtr); - nfPtr = Tcl_GetHashValue(namedHashPtr); if (nfPtr->refCount == 0) { /* * Well nobody's using this named font, so don't have to tell any @@ -948,15 +943,12 @@ TkCreateNamedFont( const char *name, /* Name for the new named font. */ TkFontAttributes *faPtr) /* Attributes for the new named font. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; Tcl_HashEntry *namedHashPtr; int isNew; NamedFont *nfPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &isNew); - if (!isNew) { nfPtr = Tcl_GetHashValue(namedHashPtr); if (nfPtr->deletePending == 0) { @@ -1005,12 +997,10 @@ TkDeleteNamedFont( Tk_Window tkwin, /* A window associated with interp. */ const char *name) /* Name for the new named font. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; NamedFont *nfPtr; Tcl_HashEntry *namedHashPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, name); if (namedHashPtr == NULL) { if (interp) { @@ -1061,7 +1051,7 @@ Tk_GetFont( Tk_Font tkfont; Tcl_Obj *strPtr; - strPtr = Tcl_NewStringObj((char *) string, -1); + strPtr = Tcl_NewStringObj(string, -1); Tcl_IncrRefCount(strPtr); tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr); Tcl_DecrRefCount(strPtr); @@ -1097,19 +1087,17 @@ Tk_AllocFontFromObj( Tcl_Obj *objPtr) /* Object describing font, as: named font, * native format, or parseable string. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; Tcl_HashEntry *cacheHashPtr, *namedHashPtr; TkFont *fontPtr, *firstFontPtr, *oldFontPtr; int isNew, descent; NamedFont *nfPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; if (objPtr->typePtr != &tkFontObjType) { SetFontFromAny(interp, objPtr); } oldFontPtr = objPtr->internalRep.twoPtrValue.ptr1; - if (oldFontPtr != NULL) { if (oldFontPtr->resourceRefCount == 0) { /* @@ -1277,7 +1265,8 @@ Tk_AllocFontFromObj( Tk_Font Tk_GetFontFromObj( - Tk_Window tkwin, /* The window that the font will be used in. */ + Tk_Window tkwin, /* The window that the font will be used + * in. */ Tcl_Obj *objPtr) /* The object from which to get the font. */ { TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; @@ -1289,7 +1278,6 @@ Tk_GetFontFromObj( } fontPtr = objPtr->internalRep.twoPtrValue.ptr1; - if (fontPtr != NULL) { if (fontPtr->resourceRefCount == 0) { /* @@ -1393,9 +1381,8 @@ const char * Tk_NameOfFont( Tk_Font tkfont) /* Font whose name is desired. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; return fontPtr->cacheHashPtr->key.string; } @@ -1420,13 +1407,12 @@ void Tk_FreeFont( Tk_Font tkfont) /* Font to be released. */ { - TkFont *fontPtr, *prevPtr; + TkFont *fontPtr = (TkFont *) tkfont, *prevPtr; NamedFont *nfPtr; - if (tkfont == NULL) { + if (fontPtr == NULL) { return; } - fontPtr = (TkFont *) tkfont; fontPtr->resourceRefCount--; if (fontPtr->resourceRefCount > 0) { return; @@ -1591,9 +1577,8 @@ Tk_FontId( Tk_Font tkfont) /* Font that is going to be selected into * GC. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; return fontPtr->fid; } @@ -1665,13 +1650,12 @@ Tk_PostscriptFontName( * which the name of the Postscript font that * corresponds to tkfont will be appended. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; Tk_Uid family, weightString, slantString; char *src, *dest; int upper, len; len = Tcl_DStringLength(dsPtr); - fontPtr = (TkFont *) tkfont; /* * Convert the case-insensitive Tk_Font family name to the case-sensitive @@ -1897,11 +1881,9 @@ TkUnderlineCharsInContext( int lastByte) /* Index of first byte after the last * character. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; int startX, endX; - fontPtr = (TkFont *) tkfont; - TkpMeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0, &startX); TkpMeasureCharsInContext(tkfont, string, numBytes, 0, lastByte, -1, 0, @@ -1960,7 +1942,7 @@ Tk_ComputeTextLayout( int *widthPtr, /* Filled with width of string. */ int *heightPtr) /* Filled with height of string. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; const char *start, *end, *special; int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight; int baseline, height, curX, newX, maxWidth, *lineLengths; @@ -1971,7 +1953,6 @@ Tk_ComputeTextLayout( Tcl_DStringInit(&lineBuffer); - fontPtr = (TkFont *) tkfont; if ((fontPtr == NULL) || (string == NULL)) { if (widthPtr != NULL) { *widthPtr = 0; @@ -2280,7 +2261,8 @@ void Tk_DrawTextLayout( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context to use for drawing text. */ + GC gc, /* Graphics context to use for drawing + * text. */ Tk_TextLayout layout, /* Layout information, from a previous call to * Tk_ComputeTextLayout(). */ int x, int y, /* Upper-left hand corner of rectangle in @@ -2337,7 +2319,8 @@ void TkDrawAngledTextLayout( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context to use for drawing text. */ + GC gc, /* Graphics context to use for drawing + * text. */ Tk_TextLayout layout, /* Layout information, from a previous call to * Tk_ComputeTextLayout(). */ int x, int y, /* Upper-left hand corner of rectangle in @@ -2454,7 +2437,8 @@ void TkUnderlineAngledTextLayout( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context to use for drawing text. */ + GC gc, /* Graphics context to use for drawing + * text. */ Tk_TextLayout layout, /* Layout information, from a previous call to * Tk_ComputeTextLayout(). */ int x, int y, /* Upper-left hand corner of rectangle in @@ -2552,7 +2536,7 @@ Tk_PointToChar( * to the upper-left corner of the text * layout. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr, *lastPtr; TkFont *fontPtr; int i, n, dummy, baseline, pos, numChars; @@ -2570,7 +2554,6 @@ Tk_PointToChar( * Find which line contains the point. */ - layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; lastPtr = chunkPtr = layoutPtr->chunks; numChars = 0; @@ -2700,7 +2683,7 @@ Tk_CharBbox( * bounding box for the character specified by * index, if non-NULL. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; int i, x = 0, w; Tk_Font tkfont; @@ -2711,7 +2694,6 @@ Tk_CharBbox( return 0; } - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; tkfont = layoutPtr->tkfont; fontPtr = (TkFont *) tkfont; @@ -2812,11 +2794,10 @@ Tk_DistanceToTextLayout( * (in pixels). */ { int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; - TextLayout *layoutPtr; TkFont *fontPtr; - layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; ascent = fontPtr->fm.ascent; descent = fontPtr->fm.descent; @@ -2900,7 +2881,7 @@ Tk_IntersectTextLayout( * rectangular area, in pixels. */ { int result, i, x1, y1, x2, y2; - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; TkFont *fontPtr; int left, top, right, bottom; @@ -2912,7 +2893,6 @@ Tk_IntersectTextLayout( * and see if they were all inside or all outside. */ - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; fontPtr = (TkFont *) layoutPtr->tkfont; @@ -3006,9 +2986,7 @@ static inline int sign( double value) { - if (value < 0.0) return -1; - if (value > 0.0) return 1; - return 0; + return (value < 0.0) ? -1 : (value > 0.0) ? 1 : 0; } static inline int @@ -3149,6 +3127,7 @@ TkIntersectAngledTextLayout( for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) { double cx[4], cy[4]; + if (chunkPtr->start[0] == '\n') { /* * Newline characters are not counted when computing area @@ -3199,6 +3178,7 @@ TkIntersectAngledTextLayout( for (j=0 ; j<4 ; j++) { int k = (j+1) % 4; + if ( SidesIntersect(rx[j],ry[j], rx[k],ry[k], x1,y1, x2,y1) || SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y1, x2,y2) || SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y2, x1,y2) || @@ -3258,16 +3238,14 @@ Tk_TextLayoutToPostscript( Tcl_Interp *interp, /* Filled with Postscript code. */ Tk_TextLayout layout) /* The layout to be rendered. */ { + TextLayout *layoutPtr = (TextLayout *) layout; #define MAXUSE 128 - char buf[MAXUSE+30], uindex[5] = "\0\0\0\0", one_char[5]; + char buf[MAXUSE+30]; LayoutChunk *chunkPtr; - int i, j, used, c, baseline, charsize; + int i, j, used, baseline, charsize; Tcl_UniChar ch; - const char *p, *last_p, *glyphname; - TextLayout *layoutPtr; - int bytecount=0; + const char *p, *glyphname; - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; baseline = chunkPtr->y; used = 0; @@ -3291,54 +3269,66 @@ Tk_TextLayoutToPostscript( p = chunkPtr->start; for (j = 0; j < chunkPtr->numDisplayChars; j++) { /* - * INTL: For now we just treat the characters as binary data - * and display the lower byte. Eventually this should be - * revised to handle international postscript fonts. + * INTL: We only handle symbols that have an encoding as a + * flyph from the standard set defined by Adobe. The rest get + * punted. Eventually this should be revised to handle more + * sophsticiated international postscript fonts. */ - last_p = p; - p += (charsize = Tcl_UtfToUniChar(p,&ch)); - Tcl_UtfToExternal(interp, NULL, last_p, charsize, 0, NULL, - one_char, 4, NULL, &bytecount, NULL); - if (bytecount == 1) { - c = UCHAR(one_char[0]); - /* c = UCHAR( ch & 0xFF) */; - if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20) - || (c >= UCHAR(0x7f))) { - /* - * Tricky point: the "03" is necessary in the sprintf - * below, so that a full three digits of octal are - * always generated. Without the "03", a number - * following this sequence could be interpreted by - * Postscript as part of this sequence. - */ + charsize = Tcl_UtfToUniChar(p, &ch); + p += charsize; - sprintf(buf + used, "\\%03o", c); - used += 4; - } else { - buf[used++] = c; - } + if ((ch == '(') || (ch == ')') || (ch == '\\') + || (ch < 0x20)) { + /* + * Tricky point: the "03" is necessary in the sprintf + * below, so that a full three digits of octal are always + * generated. Without the "03", a number following this + * sequence could be interpreted by Postscript as part of + * this sequence. + */ + + sprintf(buf + used, "\\%03o", ch); + used += 4; + } else if (ch <= 0x7f) { + /* + * Normal ASCII character. + */ + + buf[used++] = ch; } else { + char uindex[5]; + /* - * This character doesn't belong to system character set. - * So, we must use full glyph name. + * This character doesn't belong to the ASCII character + * set, so we use the full glyph name. */ sprintf(uindex, "%04X", ch); /* endianness? */ - glyphname = Tcl_GetVar2(interp,"::tk::psglyphs",uindex,0); + glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, + 0); if (glyphname) { - if (used > 0 && buf [used-1] == '(') { - --used; + if (used > 0 && buf[used-1] == '(') { + used--; } else { buf[used++] = ')'; } buf[used++] = '/'; - while ((*glyphname) && (used < (MAXUSE+27))) { - buf[used++] = *glyphname++ ; + while ((*glyphname) && (used < MAXUSE+27)) { + buf[used++] = *glyphname++; } buf[used++] = '('; - } + } else { + /* + * No known mapping for the character into the space + * of PostScript glyphs. Ignore it. :-( + */ +#ifdef TK_DEBUG_POSTSCRIPT_OUTPUT + fprintf(stderr, "Warning: no mapping to PostScript " + "glyphs for \\u%04x\n", ch); +#endif + } } if (used >= MAXUSE) { buf[used] = '\0'; |