📄 tkmacfont.c
字号:
CONST char *p, *term; int curX, termX, curIdx, sawNonSpace; MacFont *fontPtr; CGrafPtr saveWorld; GDHandle saveDevice; if (numChars == 0) { *lengthPtr = 0; return 0; } if (gWorld == NULL) { Rect rect = {0, 0, 1, 1}; if (NewGWorld(&gWorld, 0, &rect, NULL, NULL, 0) != noErr) { panic("NewGWorld failed in Tk_MeasureChars"); } } GetGWorld(&saveWorld, &saveDevice); SetGWorld(gWorld, NULL); fontPtr = (MacFont *) tkfont; TextFont(fontPtr->family); TextSize(fontPtr->size); TextFace(fontPtr->style); if (maxLength <= 0) { *lengthPtr = TextWidth(source, 0, numChars); SetGWorld(saveWorld, saveDevice); return numChars; } if (numChars > maxLength) { /* * Assume that all chars are at least 1 pixel wide, so there's no * need to measure more characters than there are pixels. This * assumption could be refined to an iterative approach that would * use that as a starting point and try more chars if necessary (if * there actually were some zero-width chars). */ numChars = maxLength; } if (numChars > SHRT_MAX) { /* * If they are trying to measure more than 32767 chars at one time, * it would require several separate measurements. */ numChars = SHRT_MAX; } widths = staticWidths; if (numChars >= sizeof(staticWidths) / sizeof(staticWidths[0])) { widths = (short *) ckalloc((numChars + 1) * sizeof(short)); } MeasureText((short) numChars, source, widths); if (widths[numChars] <= maxLength) { curX = widths[numChars]; curIdx = numChars; } else { p = term = source; curX = termX = 0; sawNonSpace = !isspace(UCHAR(*p)); for (curIdx = 1; ; curIdx++) { if (isspace(UCHAR(*p))) { if (sawNonSpace) { term = p; termX = widths[curIdx - 1]; sawNonSpace = 0; } } else { sawNonSpace = 1; } if (widths[curIdx] > maxLength) { curIdx--; curX = widths[curIdx]; break; } p++; } if (flags & TK_PARTIAL_OK) { curIdx++; curX = widths[curIdx]; } if ((curIdx == 0) && (flags & TK_AT_LEAST_ONE)) { /* * The space was too small to hold even one character. Since at * least one character must always fit on a line, return the width * of the first character. */ curX = TextWidth(source, 0, 1); curIdx = 1; } else if (flags & TK_WHOLE_WORDS) { /* * Break at last word that fits on the line. */ if ((flags & TK_AT_LEAST_ONE) && (term == source)) { /* * The space was too small to hold an entire word. This * is the only word on the line, so just return the part of th * word that fit. */ ; } else { curIdx = term - source; curX = termX; } } } if (widths != staticWidths) { ckfree((char *) widths); } *lengthPtr = curX; SetGWorld(saveWorld, saveDevice); return curIdx;}/* *--------------------------------------------------------------------------- * * Tk_DrawChars -- * * Draw a string of characters on the screen. * * Results: * None. * * Side effects: * Information gets drawn on the screen. * *--------------------------------------------------------------------------- */voidTk_DrawChars( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for drawing characters. */ Tk_Font tkfont, /* Font in which characters will be drawn; * must be the same as font used in GC. */ CONST char *source, /* Characters to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that * is passed to this function. If they are * not stripped out, they will be displayed as * regular printing characters. */ int numChars, /* Number of characters in string. */ int x, int y) /* Coordinates at which to place origin of * string when drawing. */{ MacFont *fontPtr; MacDrawable *macWin; RGBColor macColor, origColor; GWorldPtr destPort; CGrafPtr saveWorld; GDHandle saveDevice; short txFont, txFace, txSize; BitMapPtr stippleMap; fontPtr = (MacFont *) tkfont; macWin = (MacDrawable *) drawable; destPort = TkMacGetDrawablePort(drawable); GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); TkMacSetUpClippingRgn(drawable); TkMacSetUpGraphicsPort(gc); txFont = tcl_macQdPtr->thePort->txFont; txFace = tcl_macQdPtr->thePort->txFace; txSize = tcl_macQdPtr->thePort->txSize; GetForeColor(&origColor); if ((gc->fill_style == FillStippled || gc->fill_style == FillOpaqueStippled) && gc->stipple != None) { Pixmap pixmap; GWorldPtr bufferPort; stippleMap = TkMacMakeStippleMap(drawable, gc->stipple); pixmap = Tk_GetPixmap(display, drawable, stippleMap->bounds.right, stippleMap->bounds.bottom, 0); bufferPort = TkMacGetDrawablePort(pixmap); SetGWorld(bufferPort, NULL); TextFont(fontPtr->family); TextSize(fontPtr->size); TextFace(fontPtr->style); if (TkSetMacColor(gc->foreground, &macColor) == true) { RGBForeColor(&macColor); } ShowPen(); MoveTo((short) 0, (short) 0); FillRect(&stippleMap->bounds, &tcl_macQdPtr->white); MoveTo((short) x, (short) y); DrawText(source, 0, (short) numChars); SetGWorld(destPort, NULL); CopyDeepMask(&((GrafPtr) bufferPort)->portBits, stippleMap, &((GrafPtr) destPort)->portBits, &stippleMap->bounds, &stippleMap->bounds, &((GrafPtr) destPort)->portRect, srcOr, NULL); /* TODO: this doesn't work quite right - it does a blend. you can't * draw white text when you have a stipple. */ Tk_FreePixmap(display, pixmap); ckfree(stippleMap->baseAddr); ckfree((char *)stippleMap); } else { TextFont(fontPtr->family); TextSize(fontPtr->size); TextFace(fontPtr->style); if (TkSetMacColor(gc->foreground, &macColor) == true) { RGBForeColor(&macColor); } ShowPen(); MoveTo((short) (macWin->xOff + x), (short) (macWin->yOff + y)); DrawText(source, 0, (short) numChars); } TextFont(txFont); TextSize(txSize); TextFace(txFace); RGBForeColor(&origColor); SetGWorld(saveWorld, saveDevice);}/* *--------------------------------------------------------------------------- * * AllocMacFont -- * * Helper for TkpGetNativeFont() and TkpGetFontFromAttributes(). * Allocates and intializes the memory for a new TkFont that * wraps the platform-specific data. * * Results: * Returns pointer to newly constructed TkFont. * * The caller is responsible for initializing the fields of the * TkFont that are used exclusively by the generic TkFont code, and * for releasing those fields before calling TkpDeleteFont(). * * Side effects: * Memory allocated. * *--------------------------------------------------------------------------- */ static TkFont *AllocMacFont( TkFont *tkFontPtr, /* If non-NULL, store the information in * this existing TkFont structure, rather than * allocating a new structure to hold the * font; the existing contents of the font * will be released. If NULL, a new TkFont * structure is allocated. */ Tk_Window tkwin, /* For display where font will be used. */ int family, /* Macintosh font family. */ int size, /* Point size for Macintosh font. */ int style) /* Macintosh style bits. */{ char buf[257]; FontInfo fi; MacFont *fontPtr; TkFontAttributes *faPtr; TkFontMetrics *fmPtr; CGrafPtr saveWorld; GDHandle saveDevice; if (gWorld == NULL) { Rect rect = {0, 0, 1, 1}; if (NewGWorld(&gWorld, 0, &rect, NULL, NULL, 0) != noErr) { panic("NewGWorld failed in AllocMacFont"); } } GetGWorld(&saveWorld, &saveDevice); SetGWorld(gWorld, NULL); if (tkFontPtr == NULL) { fontPtr = (MacFont *) ckalloc(sizeof(MacFont)); } else { fontPtr = (MacFont *) tkFontPtr; } fontPtr->font.fid = (Font) fontPtr; faPtr = &fontPtr->font.fa; GetFontName(family, (StringPtr) buf); buf[UCHAR(buf[0]) + 1] = '\0'; faPtr->family = Tk_GetUid(buf + 1); faPtr->pointsize = size; faPtr->weight = (style & bold) ? TK_FW_BOLD : TK_FW_NORMAL; faPtr->slant = (style & italic) ? TK_FS_ITALIC : TK_FS_ROMAN; faPtr->underline = ((style & underline) != 0); faPtr->overstrike = 0; fmPtr = &fontPtr->font.fm; TextFont(family); TextSize(size); TextFace(style); GetFontInfo(&fi); fmPtr->ascent = fi.ascent; fmPtr->descent = fi.descent; fmPtr->maxWidth = fi.widMax; fmPtr->fixed = (CharWidth('i') == CharWidth('w')); fontPtr->family = (short) family; fontPtr->size = (short) size; fontPtr->style = (short) style; SetGWorld(saveWorld, saveDevice); return (TkFont *) fontPtr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -