4 * This file contains code that allows images to be
5 * nested inside text widgets. It also implements the "image"
6 * widget command for texts.
8 * Copyright (c) 1996 Sun Microsystems, Inc.
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
21 * Definitions for alignment values:
24 #define ALIGN_BOTTOM 0
25 #define ALIGN_CENTER 1
27 #define ALIGN_BASELINE 3
30 * Macro that determines the size of an embedded image segment:
33 #define EI_SEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
34 + sizeof(TkTextEmbImage)))
37 * Prototypes for procedures defined in this file:
40 static int AlignParseProc _ANSI_ARGS_((ClientData clientData,
41 Tcl_Interp *interp, Tk_Window tkwin, char *value,
42 char *widgRec, int offset));
43 static char * AlignPrintProc _ANSI_ARGS_((ClientData clientData,
44 Tk_Window tkwin, char *widgRec, int offset,
45 Tcl_FreeProc **freeProcPtr));
46 static TkTextSegment * EmbImageCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,
47 TkTextLine *linePtr));
48 static void EmbImageCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
49 TkTextLine *linePtr));
50 static void EmbImageBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
51 int index, int y, int lineHeight, int baseline,
52 int *xPtr, int *yPtr, int *widthPtr,
54 static int EmbImageConfigure _ANSI_ARGS_((TkText *textPtr,
55 TkTextSegment *eiPtr, int argc, char **argv));
56 static int EmbImageDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,
57 TkTextLine *linePtr, int treeGone));
58 static void EmbImageDisplayProc _ANSI_ARGS_((
59 TkTextDispChunk *chunkPtr, int x, int y,
60 int lineHeight, int baseline, Display *display,
61 Drawable dst, int screenY));
62 static int EmbImageLayoutProc _ANSI_ARGS_((TkText *textPtr,
63 TkTextIndex *indexPtr, TkTextSegment *segPtr,
64 int offset, int maxX, int maxChars,
65 int noCharsYet, Tk_Uid wrapMode,
66 TkTextDispChunk *chunkPtr));
67 static void EmbImageProc _ANSI_ARGS_((ClientData clientData,
68 int x, int y, int width, int height,
69 int imageWidth, int imageHeight));
72 * The following structure declares the "embedded image" segment type.
75 static Tk_SegType tkTextEmbImageType = {
78 (Tk_SegSplitProc *) NULL, /* splitProc */
79 EmbImageDeleteProc, /* deleteProc */
80 EmbImageCleanupProc, /* cleanupProc */
81 (Tk_SegLineChangeProc *) NULL, /* lineChangeProc */
82 EmbImageLayoutProc, /* layoutProc */
83 EmbImageCheckProc /* checkProc */
87 * Information used for parsing image configuration options:
90 static Tk_CustomOption alignOption = {AlignParseProc, AlignPrintProc,
93 static Tk_ConfigSpec configSpecs[] = {
94 {TK_CONFIG_CUSTOM, "-align", (char *) NULL, (char *) NULL,
95 "center", 0, TK_CONFIG_DONT_SET_DEFAULT, &alignOption},
96 {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,
97 "0", Tk_Offset(TkTextEmbImage, padX),
98 TK_CONFIG_DONT_SET_DEFAULT},
99 {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,
100 "0", Tk_Offset(TkTextEmbImage, padY),
101 TK_CONFIG_DONT_SET_DEFAULT},
102 {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL,
103 (char *) NULL, Tk_Offset(TkTextEmbImage, imageString),
104 TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
105 {TK_CONFIG_STRING, "-name", (char *) NULL, (char *) NULL,
106 (char *) NULL, Tk_Offset(TkTextEmbImage, imageName),
107 TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
108 {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
113 *--------------------------------------------------------------
117 * This procedure implements the "image" widget command
118 * for text widgets. See the user documentation for details
122 * A standard Tcl result or error.
125 * See the user documentation.
127 *--------------------------------------------------------------
131 TkTextImageCmd(textPtr, interp, argc, argv)
132 register TkText *textPtr; /* Information about text widget. */
133 Tcl_Interp *interp; /* Current interpreter. */
134 int argc; /* Number of arguments. */
135 char **argv; /* Argument strings. Someone else has already
136 * parsed this command enough to know that
137 * argv[1] is "image". */
140 register TkTextSegment *eiPtr;
143 Tcl_AppendResult(interp, "wrong # args: should be \"",
144 argv[0], " image option ?arg arg ...?\"", (char *) NULL);
147 length = strlen(argv[2]);
148 if ((strncmp(argv[2], "cget", length) == 0) && (length >= 2)) {
150 TkTextSegment *eiPtr;
153 Tcl_AppendResult(interp, "wrong # args: should be \"",
154 argv[0], " image cget index option\"",
158 if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
161 eiPtr = TkTextIndexToSeg(&index, (int *) NULL);
162 if (eiPtr->typePtr != &tkTextEmbImageType) {
163 Tcl_AppendResult(interp, "no embedded image at index \"",
164 argv[3], "\"", (char *) NULL);
167 return Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs,
168 (char *) &eiPtr->body.ei, argv[4], 0);
169 } else if ((strncmp(argv[2], "configure", length) == 0) && (length >= 2)) {
171 TkTextSegment *eiPtr;
174 Tcl_AppendResult(interp, "wrong # args: should be \"",
175 argv[0], " image configure index ?option value ...?\"",
179 if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
182 eiPtr = TkTextIndexToSeg(&index, (int *) NULL);
183 if (eiPtr->typePtr != &tkTextEmbImageType) {
184 Tcl_AppendResult(interp, "no embedded image at index \"",
185 argv[3], "\"", (char *) NULL);
189 return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
190 (char *) &eiPtr->body.ei, (char *) NULL, 0);
191 } else if (argc == 5) {
192 return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
193 (char *) &eiPtr->body.ei, argv[4], 0);
195 TkTextChanged(textPtr, &index, &index);
196 return EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4);
198 } else if ((strncmp(argv[2], "create", length) == 0) && (length >= 2)) {
203 * Add a new image. Find where to put the new image, and
204 * mark that position for redisplay.
208 Tcl_AppendResult(interp, "wrong # args: should be \"",
209 argv[0], " image create index ?option value ...?\"",
213 if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
218 * Don't allow insertions on the last (dummy) line of the text.
221 lineIndex = TkBTreeLineIndex(index.linePtr);
222 if (lineIndex == TkBTreeNumLines(textPtr->tree)) {
224 TkTextMakeIndex(textPtr->tree, lineIndex, 1000000, &index);
228 * Create the new image segment and initialize it.
231 eiPtr = (TkTextSegment *) ckalloc(EI_SEG_SIZE);
232 eiPtr->typePtr = &tkTextEmbImageType;
234 eiPtr->body.ei.textPtr = textPtr;
235 eiPtr->body.ei.linePtr = NULL;
236 eiPtr->body.ei.imageName = NULL;
237 eiPtr->body.ei.imageString = NULL;
238 eiPtr->body.ei.name = NULL;
239 eiPtr->body.ei.image = NULL;
240 eiPtr->body.ei.align = ALIGN_CENTER;
241 eiPtr->body.ei.padX = eiPtr->body.ei.padY = 0;
242 eiPtr->body.ei.chunkCount = 0;
245 * Link the segment into the text widget, then configure it (delete
246 * it again if the configuration fails).
249 TkTextChanged(textPtr, &index, &index);
250 TkBTreeLinkSegment(eiPtr, &index);
251 if (EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4) != TCL_OK) {
254 TkTextIndexForwChars(&index, 1, &index2);
255 TkBTreeDeleteChars(&index, &index2);
258 } else if (strncmp(argv[2], "names", length) == 0) {
259 Tcl_HashSearch search;
263 Tcl_AppendResult(interp, "wrong # args: should be \"",
264 argv[0], " image names\"", (char *) NULL);
267 for (hPtr = Tcl_FirstHashEntry(&textPtr->imageTable, &search);
268 hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
269 Tcl_AppendElement(interp,
270 Tcl_GetHashKey(&textPtr->markTable, hPtr));
273 Tcl_AppendResult(interp, "bad image option \"", argv[2],
274 "\": must be cget, configure, create, or names",
282 *--------------------------------------------------------------
284 * EmbImageConfigure --
286 * This procedure is called to handle configuration options
287 * for an embedded image, using an argc/argv list.
290 * The return value is a standard Tcl result. If TCL_ERROR is
291 * returned, then interp->result contains an error message..
294 * Configuration information for the embedded image changes,
295 * such as alignment, or name of the image.
297 *--------------------------------------------------------------
301 EmbImageConfigure(textPtr, eiPtr, argc, argv)
302 TkText *textPtr; /* Information about text widget that
303 * contains embedded image. */
304 TkTextSegment *eiPtr; /* Embedded image to be configured. */
305 int argc; /* Number of strings in argv. */
306 char **argv; /* Array of strings describing configuration
312 Tcl_HashSearch search;
315 int count = 0; /* The counter for picking a unique name */
316 int conflict = 0; /* True if we have a name conflict */
317 unsigned int len; /* length of image name */
319 if (Tk_ConfigureWidget(textPtr->interp, textPtr->tkwin, configSpecs,
320 argc, argv, (char *) &eiPtr->body.ei,TK_CONFIG_ARGV_ONLY)
326 * Create the image. Save the old image around and don't free it
327 * until after the new one is allocated. This keeps the reference
328 * count from going to zero so the image doesn't have to be recreated
329 * if it hasn't changed.
332 if (eiPtr->body.ei.imageString != NULL) {
333 image = Tk_GetImage(textPtr->interp, textPtr->tkwin, eiPtr->body.ei.imageString,
334 EmbImageProc, (ClientData) eiPtr);
341 if (eiPtr->body.ei.image != NULL) {
342 Tk_FreeImage(eiPtr->body.ei.image);
344 eiPtr->body.ei.image = image;
346 if (eiPtr->body.ei.name != NULL) {
351 * Find a unique name for this image. Use imageName (or imageString)
352 * if available, otherwise tack on a #nn and use it. If a name is already
353 * associated with this image, delete the name.
356 name = eiPtr->body.ei.imageName;
358 name = eiPtr->body.ei.imageString;
361 Tcl_AppendResult(textPtr->interp,"Either a \"-name\" ",
362 "or a \"-image\" argument must be provided ",
363 "to the \"image create\" subcommand.",
368 for (hPtr = Tcl_FirstHashEntry(&textPtr->imageTable, &search);
369 hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
370 char *haveName = Tcl_GetHashKey(&textPtr->imageTable, hPtr);
371 if (strncmp(name, haveName, len) == 0) {
373 sscanf(haveName+len,"#%d",&new);
377 if (len == (int) strlen(haveName)) {
383 Tcl_DStringInit(&newName);
384 Tcl_DStringAppend(&newName,name, -1);
388 sprintf(buf, "#%d",count+1);
389 Tcl_DStringAppend(&newName,buf, -1);
391 name = Tcl_DStringValue(&newName);
392 hPtr = Tcl_CreateHashEntry(&textPtr->imageTable, name, &new);
393 Tcl_SetHashValue(hPtr, eiPtr);
394 Tcl_AppendResult(textPtr->interp, name , (char *) NULL);
395 eiPtr->body.ei.name = ckalloc((unsigned) Tcl_DStringLength(&newName)+1);
396 strcpy(eiPtr->body.ei.name,name);
397 Tcl_DStringFree(&newName);
403 *--------------------------------------------------------------
407 * This procedure is invoked by Tk_ConfigureWidget during
408 * option processing to handle "-align" options for embedded
412 * A standard Tcl return value.
415 * The alignment for the embedded image may change.
417 *--------------------------------------------------------------
422 AlignParseProc(clientData, interp, tkwin, value, widgRec, offset)
423 ClientData clientData; /* Not used.*/
424 Tcl_Interp *interp; /* Used for reporting errors. */
425 Tk_Window tkwin; /* Window for text widget. */
426 char *value; /* Value of option. */
427 char *widgRec; /* Pointer to TkTextEmbWindow
429 int offset; /* Offset into item (ignored). */
431 register TkTextEmbImage *embPtr = (TkTextEmbImage *) widgRec;
433 if (strcmp(value, "baseline") == 0) {
434 embPtr->align = ALIGN_BASELINE;
435 } else if (strcmp(value, "bottom") == 0) {
436 embPtr->align = ALIGN_BOTTOM;
437 } else if (strcmp(value, "center") == 0) {
438 embPtr->align = ALIGN_CENTER;
439 } else if (strcmp(value, "top") == 0) {
440 embPtr->align = ALIGN_TOP;
442 Tcl_AppendResult(interp, "bad alignment \"", value,
443 "\": must be baseline, bottom, center, or top",
451 *--------------------------------------------------------------
455 * This procedure is invoked by the Tk configuration code
456 * to produce a printable string for the "-align" configuration
457 * option for embedded images.
460 * The return value is a string describing the embedded
461 * images's current alignment.
466 *--------------------------------------------------------------
471 AlignPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
472 ClientData clientData; /* Ignored. */
473 Tk_Window tkwin; /* Window for text widget. */
474 char *widgRec; /* Pointer to TkTextEmbImage
476 int offset; /* Ignored. */
477 Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
478 * information about how to reclaim
479 * storage for return string. */
481 switch (((TkTextEmbImage *) widgRec)->align) {
496 *--------------------------------------------------------------
498 * EmbImageDeleteProc --
500 * This procedure is invoked by the text B-tree code whenever
501 * an embedded image lies in a range of characters being deleted.
504 * Returns 0 to indicate that the deletion has been accepted.
507 * The embedded image is deleted, if it exists, and any resources
508 * associated with it are released.
510 *--------------------------------------------------------------
515 EmbImageDeleteProc(eiPtr, linePtr, treeGone)
516 TkTextSegment *eiPtr; /* Segment being deleted. */
517 TkTextLine *linePtr; /* Line containing segment. */
518 int treeGone; /* Non-zero means the entire tree is
519 * being deleted, so everything must
524 if (eiPtr->body.ei.image != NULL) {
525 hPtr = Tcl_FindHashEntry(&eiPtr->body.ei.textPtr->imageTable,
526 eiPtr->body.ei.name);
529 * (It's possible for there to be no hash table entry for this
530 * image, if an error occurred while creating the image segment
531 * but before the image got added to the table)
534 Tcl_DeleteHashEntry(hPtr);
536 Tk_FreeImage(eiPtr->body.ei.image);
538 Tk_FreeOptions(configSpecs, (char *) &eiPtr->body.ei,
539 eiPtr->body.ei.textPtr->display, 0);
540 if (eiPtr->body.ei.name != NULL) {
541 ckfree(eiPtr->body.ei.name);
543 ckfree((char *) eiPtr);
548 *--------------------------------------------------------------
550 * EmbImageCleanupProc --
552 * This procedure is invoked by the B-tree code whenever a
553 * segment containing an embedded image is moved from one
560 * The linePtr field of the segment gets updated.
562 *--------------------------------------------------------------
565 static TkTextSegment *
566 EmbImageCleanupProc(eiPtr, linePtr)
567 TkTextSegment *eiPtr; /* Mark segment that's being moved. */
568 TkTextLine *linePtr; /* Line that now contains segment. */
570 eiPtr->body.ei.linePtr = linePtr;
575 *--------------------------------------------------------------
577 * EmbImageLayoutProc --
579 * This procedure is the "layoutProc" for embedded image
583 * 1 is returned to indicate that the segment should be
584 * displayed. The chunkPtr structure is filled in.
587 * None, except for filling in chunkPtr.
589 *--------------------------------------------------------------
594 EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars,
595 noCharsYet, wrapMode, chunkPtr)
596 TkText *textPtr; /* Text widget being layed out. */
597 TkTextIndex *indexPtr; /* Identifies first character in chunk. */
598 TkTextSegment *eiPtr; /* Segment corresponding to indexPtr. */
599 int offset; /* Offset within segPtr corresponding to
600 * indexPtr (always 0). */
601 int maxX; /* Chunk must not occupy pixels at this
602 * position or higher. */
603 int maxChars; /* Chunk must not include more than this
604 * many characters. */
605 int noCharsYet; /* Non-zero means no characters have been
606 * assigned to this line yet. */
607 Tk_Uid wrapMode; /* Wrap mode to use for line: tkTextCharUid,
608 * tkTextNoneUid, or tkTextWordUid. */
609 register TkTextDispChunk *chunkPtr;
610 /* Structure to fill in with information
611 * about this chunk. The x field has already
612 * been set by the caller. */
617 panic("Non-zero offset in EmbImageLayoutProc");
621 * See if there's room for this image on this line.
624 if (eiPtr->body.ei.image == NULL) {
628 Tk_SizeOfImage(eiPtr->body.ei.image, &width, &height);
629 width += 2*eiPtr->body.ei.padX;
630 height += 2*eiPtr->body.ei.padY;
632 if ((width > (maxX - chunkPtr->x))
633 && !noCharsYet && (textPtr->wrapMode != tkTextNoneUid)) {
638 * Fill in the chunk structure.
641 chunkPtr->displayProc = EmbImageDisplayProc;
642 chunkPtr->undisplayProc = (Tk_ChunkUndisplayProc *) NULL;
643 chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL;
644 chunkPtr->bboxProc = EmbImageBboxProc;
645 chunkPtr->numChars = 1;
646 if (eiPtr->body.ei.align == ALIGN_BASELINE) {
647 chunkPtr->minAscent = height - eiPtr->body.ei.padY;
648 chunkPtr->minDescent = eiPtr->body.ei.padY;
649 chunkPtr->minHeight = 0;
651 chunkPtr->minAscent = 0;
652 chunkPtr->minDescent = 0;
653 chunkPtr->minHeight = height;
655 chunkPtr->width = width;
656 chunkPtr->breakIndex = -1;
657 chunkPtr->breakIndex = 1;
658 chunkPtr->clientData = (ClientData) eiPtr;
659 eiPtr->body.ei.chunkCount += 1;
664 *--------------------------------------------------------------
666 * EmbImageCheckProc --
668 * This procedure is invoked by the B-tree code to perform
669 * consistency checks on embedded images.
675 * The procedure panics if it detects anything wrong with
676 * the embedded image.
678 *--------------------------------------------------------------
682 EmbImageCheckProc(eiPtr, linePtr)
683 TkTextSegment *eiPtr; /* Segment to check. */
684 TkTextLine *linePtr; /* Line containing segment. */
686 if (eiPtr->nextPtr == NULL) {
687 panic("EmbImageCheckProc: embedded image is last segment in line");
689 if (eiPtr->size != 1) {
690 panic("EmbImageCheckProc: embedded image has size %d", eiPtr->size);
695 *--------------------------------------------------------------
697 * EmbImageDisplayProc --
699 * This procedure is invoked by the text displaying code
700 * when it is time to actually draw an embedded image
701 * chunk on the screen.
707 * The embedded image gets moved to the correct location
708 * and drawn onto the display.
710 *--------------------------------------------------------------
714 EmbImageDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
715 TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */
716 int x; /* X-position in dst at which to
717 * draw this chunk (differs from
718 * the x-position in the chunk because
720 int y; /* Top of rectangular bounding box
721 * for line: tells where to draw this
722 * chunk in dst (x-position is in
723 * the chunk itself). */
724 int lineHeight; /* Total height of line. */
725 int baseline; /* Offset of baseline from y. */
726 Display *display; /* Display to use for drawing. */
727 Drawable dst; /* Pixmap or window in which to draw */
728 int screenY; /* Y-coordinate in text window that
729 * corresponds to y. */
731 TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData;
732 int lineX, imageX, imageY, width, height;
735 image = eiPtr->body.ei.image;
739 if ((x + chunkPtr->width) <= 0) {
744 * Compute the image's location and size in the text widget, taking
745 * into account the align value for the image.
748 EmbImageBboxProc(chunkPtr, 0, y, lineHeight, baseline, &lineX,
749 &imageY, &width, &height);
750 imageX = lineX - chunkPtr->x + x;
752 Tk_RedrawImage(image, 0, 0, width, height, dst,
757 *--------------------------------------------------------------
759 * EmbImageBboxProc --
761 * This procedure is called to compute the bounding box of
762 * the area occupied by an embedded image.
765 * There is no return value. *xPtr and *yPtr are filled in
766 * with the coordinates of the upper left corner of the
767 * image, and *widthPtr and *heightPtr are filled in with
768 * the dimensions of the image in pixels. Note: not all
769 * of the returned bbox is necessarily visible on the screen
770 * (the rightmost part might be off-screen to the right,
771 * and the bottommost part might be off-screen to the bottom).
776 *--------------------------------------------------------------
780 EmbImageBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
782 TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */
783 int index; /* Index of desired character within
785 int y; /* Topmost pixel in area allocated
787 int lineHeight; /* Total height of line. */
788 int baseline; /* Location of line's baseline, in
789 * pixels measured down from y. */
790 int *xPtr, *yPtr; /* Gets filled in with coords of
791 * character's upper-left pixel. */
792 int *widthPtr; /* Gets filled in with width of
793 * character, in pixels. */
794 int *heightPtr; /* Gets filled in with height of
795 * character, in pixels. */
797 TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData;
800 image = eiPtr->body.ei.image;
802 Tk_SizeOfImage(image, widthPtr, heightPtr);
807 *xPtr = chunkPtr->x + eiPtr->body.ei.padX;
808 switch (eiPtr->body.ei.align) {
810 *yPtr = y + (lineHeight - *heightPtr - eiPtr->body.ei.padY);
813 *yPtr = y + (lineHeight - *heightPtr)/2;
816 *yPtr = y + eiPtr->body.ei.padY;
819 *yPtr = y + (baseline - *heightPtr);
825 *--------------------------------------------------------------
827 * TkTextImageIndex --
829 * Given the name of an embedded image within a text widget,
830 * returns an index corresponding to the image's position
834 * The return value is 1 if there is an embedded image by
835 * the given name in the text widget, 0 otherwise. If the
836 * image exists, *indexPtr is filled in with its index.
841 *--------------------------------------------------------------
845 TkTextImageIndex(textPtr, name, indexPtr)
846 TkText *textPtr; /* Text widget containing image. */
847 char *name; /* Name of image. */
848 TkTextIndex *indexPtr; /* Index information gets stored here. */
851 TkTextSegment *eiPtr;
853 hPtr = Tcl_FindHashEntry(&textPtr->imageTable, name);
857 eiPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
858 indexPtr->tree = textPtr->tree;
859 indexPtr->linePtr = eiPtr->body.ei.linePtr;
860 indexPtr->charIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr);
865 *--------------------------------------------------------------
869 * This procedure is called by the image code whenever an
870 * image or its contents changes.
876 * The image will be redisplayed.
878 *--------------------------------------------------------------
882 EmbImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
883 ClientData clientData; /* Pointer to widget record. */
884 int x, y; /* Upper left pixel (within image)
885 * that must be redisplayed. */
886 int width, height; /* Dimensions of area to redisplay
888 int imgWidth, imgHeight; /* New dimensions of image. */
891 TkTextSegment *eiPtr = (TkTextSegment *) clientData;
894 index.tree = eiPtr->body.ei.textPtr->tree;
895 index.linePtr = eiPtr->body.ei.linePtr;
896 index.charIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr);
897 TkTextChanged(eiPtr->body.ei.textPtr, &index, &index);