⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tktextimage.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * tkImage.c -- * *	This file contains code that allows images to be *	nested inside text widgets.  It also implements the "image" *	widget command for texts. * * Copyright (c) 1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkTextImage.c 1.7 97/08/25 15:47:27 */#include "tk.h"#include "tkText.h"#include "tkPort.h"/* * Definitions for alignment values: */#define ALIGN_BOTTOM		0#define ALIGN_CENTER		1#define ALIGN_TOP		2#define ALIGN_BASELINE		3/* * Macro that determines the size of an embedded image segment: */#define EI_SEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \	+ sizeof(TkTextEmbImage)))/* * Prototypes for procedures defined in this file: */static int		AlignParseProc _ANSI_ARGS_((ClientData clientData,			    Tcl_Interp *interp, Tk_Window tkwin, char *value,			    char *widgRec, int offset));static char *		AlignPrintProc _ANSI_ARGS_((ClientData clientData,			    Tk_Window tkwin, char *widgRec, int offset,			    Tcl_FreeProc **freeProcPtr));static TkTextSegment *	EmbImageCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,			    TkTextLine *linePtr));static void		EmbImageCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,			    TkTextLine *linePtr));static void		EmbImageBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,			    int index, int y, int lineHeight, int baseline,			    int *xPtr, int *yPtr, int *widthPtr,			    int *heightPtr));static int		EmbImageConfigure _ANSI_ARGS_((TkText *textPtr,			    TkTextSegment *eiPtr, int argc, char **argv));static int		EmbImageDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,			    TkTextLine *linePtr, int treeGone));static void		EmbImageDisplayProc _ANSI_ARGS_((			    TkTextDispChunk *chunkPtr, int x, int y,			    int lineHeight, int baseline, Display *display,			    Drawable dst, int screenY));static int		EmbImageLayoutProc _ANSI_ARGS_((TkText *textPtr,			    TkTextIndex *indexPtr, TkTextSegment *segPtr,			    int offset, int maxX, int maxChars,			    int noCharsYet, Tk_Uid wrapMode,			    TkTextDispChunk *chunkPtr));static void		EmbImageProc _ANSI_ARGS_((ClientData clientData,			    int x, int y, int width, int height,			    int imageWidth, int imageHeight));/* * The following structure declares the "embedded image" segment type. */static Tk_SegType tkTextEmbImageType = {    "image",					/* name */    0,						/* leftGravity */    (Tk_SegSplitProc *) NULL,			/* splitProc */    EmbImageDeleteProc,				/* deleteProc */    EmbImageCleanupProc,			/* cleanupProc */    (Tk_SegLineChangeProc *) NULL,		/* lineChangeProc */    EmbImageLayoutProc,				/* layoutProc */    EmbImageCheckProc				/* checkProc */};/* * Information used for parsing image configuration options: */static Tk_CustomOption alignOption = {AlignParseProc, AlignPrintProc,	(ClientData) NULL};static Tk_ConfigSpec configSpecs[] = {    {TK_CONFIG_CUSTOM, "-align", (char *) NULL, (char *) NULL,	"center", 0, TK_CONFIG_DONT_SET_DEFAULT, &alignOption},    {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,	"0", Tk_Offset(TkTextEmbImage, padX),	TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,	"0", Tk_Offset(TkTextEmbImage, padY),	TK_CONFIG_DONT_SET_DEFAULT},    {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL,	(char *) NULL, Tk_Offset(TkTextEmbImage, imageString),	TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},    {TK_CONFIG_STRING, "-name", (char *) NULL, (char *) NULL,	(char *) NULL, Tk_Offset(TkTextEmbImage, imageName),	TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,	(char *) NULL, 0, 0}};/* *-------------------------------------------------------------- * * TkTextImageCmd -- * *	This procedure implements the "image" widget command *	for text widgets.  See the user documentation for details *	on what it does. * * Results: *	A standard Tcl result or error. * * Side effects: *	See the user documentation. * *-------------------------------------------------------------- */intTkTextImageCmd(textPtr, interp, argc, argv)    register TkText *textPtr;	/* Information about text widget. */    Tcl_Interp *interp;		/* Current interpreter. */    int argc;			/* Number of arguments. */    char **argv;		/* Argument strings.  Someone else has already				 * parsed this command enough to know that				 * argv[1] is "image". */{    size_t length;    register TkTextSegment *eiPtr;    if (argc < 3) {	Tcl_AppendResult(interp, "wrong # args: should be \"",		argv[0], " image option ?arg arg ...?\"", (char *) NULL);	return TCL_ERROR;    }    length = strlen(argv[2]);    if ((strncmp(argv[2], "cget", length) == 0) && (length >= 2)) {	TkTextIndex index;	TkTextSegment *eiPtr;	if (argc != 5) {	    Tcl_AppendResult(interp, "wrong # args: should be \"",		    argv[0], " image cget index option\"",		    (char *) NULL);	    return TCL_ERROR;	}	if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {	    return TCL_ERROR;	}	eiPtr = TkTextIndexToSeg(&index, (int *) NULL);	if (eiPtr->typePtr != &tkTextEmbImageType) {	    Tcl_AppendResult(interp, "no embedded image at index \"",		    argv[3], "\"", (char *) NULL);	    return TCL_ERROR;	}	return Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs,		(char *) &eiPtr->body.ei, argv[4], 0);    } else if ((strncmp(argv[2], "configure", length) == 0) && (length >= 2)) {	TkTextIndex index;	TkTextSegment *eiPtr;	if (argc < 4) {	    Tcl_AppendResult(interp, "wrong # args: should be \"",		    argv[0], " image configure index ?option value ...?\"",		    (char *) NULL);	    return TCL_ERROR;	}	if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {	    return TCL_ERROR;	}	eiPtr = TkTextIndexToSeg(&index, (int *) NULL);	if (eiPtr->typePtr != &tkTextEmbImageType) {	    Tcl_AppendResult(interp, "no embedded image at index \"",		    argv[3], "\"", (char *) NULL);	    return TCL_ERROR;	}	if (argc == 4) {	    return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,		    (char *) &eiPtr->body.ei, (char *) NULL, 0);	} else if (argc == 5) {	    return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,		    (char *) &eiPtr->body.ei, argv[4], 0);	} else {	    TkTextChanged(textPtr, &index, &index);	    return EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4);	}    } else if ((strncmp(argv[2], "create", length) == 0) && (length >= 2)) {	TkTextIndex index;	int lineIndex;	/*	 * Add a new image.  Find where to put the new image, and	 * mark that position for redisplay.	 */	if (argc < 4) {	    Tcl_AppendResult(interp, "wrong # args: should be \"",		    argv[0], " image create index ?option value ...?\"",		    (char *) NULL);	    return TCL_ERROR;	}	if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {	    return TCL_ERROR;	}	/*	 * Don't allow insertions on the last (dummy) line of the text.	 */    	lineIndex = TkBTreeLineIndex(index.linePtr);	if (lineIndex == TkBTreeNumLines(textPtr->tree)) {	    lineIndex--;	    TkTextMakeIndex(textPtr->tree, lineIndex, 1000000, &index);	}	/*	 * Create the new image segment and initialize it.	 */	eiPtr = (TkTextSegment *) ckalloc(EI_SEG_SIZE);	eiPtr->typePtr = &tkTextEmbImageType;	eiPtr->size = 1;	eiPtr->body.ei.textPtr = textPtr;	eiPtr->body.ei.linePtr = NULL;	eiPtr->body.ei.imageName = NULL;	eiPtr->body.ei.imageString = NULL;	eiPtr->body.ei.name = NULL;	eiPtr->body.ei.image = NULL;	eiPtr->body.ei.align = ALIGN_CENTER;	eiPtr->body.ei.padX = eiPtr->body.ei.padY = 0;	eiPtr->body.ei.chunkCount = 0;	/*	 * Link the segment into the text widget, then configure it (delete	 * it again if the configuration fails).	 */	TkTextChanged(textPtr, &index, &index);	TkBTreeLinkSegment(eiPtr, &index);	if (EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4) != TCL_OK) {	    TkTextIndex index2;	    TkTextIndexForwChars(&index, 1, &index2);	    TkBTreeDeleteChars(&index, &index2);	    return TCL_ERROR;	}    } else if (strncmp(argv[2], "names", length) == 0) {	Tcl_HashSearch search;	Tcl_HashEntry *hPtr;	if (argc != 3) {	    Tcl_AppendResult(interp, "wrong # args: should be \"",		    argv[0], " image names\"", (char *) NULL);	    return TCL_ERROR;	}	for (hPtr = Tcl_FirstHashEntry(&textPtr->imageTable, &search);		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {	    Tcl_AppendElement(interp,		    Tcl_GetHashKey(&textPtr->markTable, hPtr));	}    } else {	Tcl_AppendResult(interp, "bad image option \"", argv[2],		"\": must be cget, configure, create, or names",		(char *) NULL);	return TCL_ERROR;    }    return TCL_OK;}/* *-------------------------------------------------------------- * * EmbImageConfigure -- * *	This procedure is called to handle configuration options *	for an embedded image, using an argc/argv list. * * Results: *	The return value is a standard Tcl result.  If TCL_ERROR is *	returned, then interp->result contains an error message.. * * Side effects: *	Configuration information for the embedded image changes, *	such as alignment, or name of the image. * *-------------------------------------------------------------- */static intEmbImageConfigure(textPtr, eiPtr, argc, argv)    TkText *textPtr;		/* Information about text widget that				 * contains embedded image. */    TkTextSegment *eiPtr;	/* Embedded image to be configured. */    int argc;			/* Number of strings in argv. */    char **argv;		/* Array of strings describing configuration				 * options. */{    Tk_Image image;    Tcl_DString newName;    Tcl_HashEntry *hPtr;    Tcl_HashSearch search;    int new;    char *name;    int count = 0;		/* The counter for picking a unique name */    int conflict = 0;		/* True if we have a name conflict */    unsigned int len;		/* length of image name */    if (Tk_ConfigureWidget(textPtr->interp, textPtr->tkwin, configSpecs,	    argc, argv, (char *) &eiPtr->body.ei,TK_CONFIG_ARGV_ONLY)	    != TCL_OK) {	return TCL_ERROR;    }    /*     * Create the image.  Save the old image around and don't free it     * until after the new one is allocated.  This keeps the reference     * count from going to zero so the image doesn't have to be recreated     * if it hasn't changed.     */    if (eiPtr->body.ei.imageString != NULL) {	image = Tk_GetImage(textPtr->interp, textPtr->tkwin, eiPtr->body.ei.imageString,		EmbImageProc, (ClientData) eiPtr);	if (image == NULL) {	    return TCL_ERROR;	}    } else {	image = NULL;    }    if (eiPtr->body.ei.image != NULL) {	Tk_FreeImage(eiPtr->body.ei.image);    }    eiPtr->body.ei.image = image;    if (eiPtr->body.ei.name != NULL) {    	return TCL_OK;    }    /*      * Find a unique name for this image.  Use imageName (or imageString)     * if available, otherwise tack on a #nn and use it.  If a name is already     * associated with this image, delete the name.     */    name = eiPtr->body.ei.imageName;    if (name == NULL) {    	name = eiPtr->body.ei.imageString;    }    if (name == NULL) {        Tcl_AppendResult(textPtr->interp,"Either a \"-name\" ",		"or a \"-image\" argument must be provided ",		"to the \"image create\" subcommand.",		(char *) NULL);	return TCL_ERROR;    }    len = strlen(name);    for (hPtr = Tcl_FirstHashEntry(&textPtr->imageTable, &search);	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {	char *haveName = Tcl_GetHashKey(&textPtr->imageTable, hPtr);	if (strncmp(name, haveName, len) == 0) {	    new = 0;	    sscanf(haveName+len,"#%d",&new);	    if (new > count) {		count = new;	    }	    if (len == (int) strlen(haveName)) {	    	conflict = 1;	    }	}    }    Tcl_DStringInit(&newName);    Tcl_DStringAppend(&newName,name, -1);    if (conflict) {    	char buf[10];	sprintf(buf, "#%d",count+1);	Tcl_DStringAppend(&newName,buf, -1);    }    name = Tcl_DStringValue(&newName);    hPtr = Tcl_CreateHashEntry(&textPtr->imageTable, name, &new);    Tcl_SetHashValue(hPtr, eiPtr);    Tcl_AppendResult(textPtr->interp, name , (char *) NULL);    eiPtr->body.ei.name = ckalloc((unsigned) Tcl_DStringLength(&newName)+1);    strcpy(eiPtr->body.ei.name,name);    Tcl_DStringFree(&newName);    return TCL_OK;}/* *-------------------------------------------------------------- * * AlignParseProc -- * *	This procedure is invoked by Tk_ConfigureWidget during *	option processing to handle "-align" options for embedded *	images. * * Results: *	A standard Tcl return value. * * Side effects: *	The alignment for the embedded image may change. * *-------------------------------------------------------------- */	/* ARGSUSED */static intAlignParseProc(clientData, interp, tkwin, value, widgRec, offset)    ClientData clientData;		/* Not used.*/    Tcl_Interp *interp;			/* Used for reporting errors. */    Tk_Window tkwin;			/* Window for text widget. */    char *value;			/* Value of option. */    char *widgRec;			/* Pointer to TkTextEmbWindow					 * structure. */    int offset;				/* Offset into item (ignored). */{    register TkTextEmbImage *embPtr = (TkTextEmbImage *) widgRec;    if (strcmp(value, "baseline") == 0) {	embPtr->align = ALIGN_BASELINE;    } else if (strcmp(value, "bottom") == 0) {	embPtr->align = ALIGN_BOTTOM;    } else if (strcmp(value, "center") == 0) {	embPtr->align = ALIGN_CENTER;    } else if (strcmp(value, "top") == 0) {	embPtr->align = ALIGN_TOP;    } else {	Tcl_AppendResult(interp, "bad alignment \"", value,		"\": must be baseline, bottom, center, or top",		(char *) NULL);	return TCL_ERROR;    }    return TCL_OK;}/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -