📄 tkfont.c
字号:
intTk_PointToChar(layout, x, y) Tk_TextLayout layout; /* Layout information, from a previous call * to Tk_ComputeTextLayout(). */ int x, y; /* Coordinates of point to check, with * respect to the upper-left corner of the * text layout. */{ TextLayout *layoutPtr; LayoutChunk *chunkPtr, *lastPtr; TkFont *fontPtr; int i, n, dummy, baseline, pos; if (y < 0) { /* * Point lies above any line in this layout. Return the index of * the first char. */ return 0; } /* * Find which line contains the point. */ layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; lastPtr = chunkPtr = layoutPtr->chunks; for (i = 0; i < layoutPtr->numChunks; i++) { baseline = chunkPtr->y; if (y < baseline + fontPtr->fm.descent) { if (x < chunkPtr->x) { /* * Point is to the left of all chunks on this line. Return * the index of the first character on this line. */ return chunkPtr->start - layoutPtr->string; } if (x >= layoutPtr->width) { /* * If point lies off right side of the text layout, return * the last char in the last chunk on this line. Without * this, it might return the index of the first char that * was located outside of the text layout. */ x = INT_MAX; } /* * Examine all chunks on this line to see which one contains * the specified point. */ lastPtr = chunkPtr; while ((i < layoutPtr->numChunks) && (chunkPtr->y == baseline)) { if (x < chunkPtr->x + chunkPtr->totalWidth) { /* * Point falls on one of the characters in this chunk. */ if (chunkPtr->numDisplayChars < 0) { /* * This is a special chunk that encapsulates a single * tab or newline char. */ return chunkPtr->start - layoutPtr->string; } n = Tk_MeasureChars((Tk_Font) fontPtr, chunkPtr->start, chunkPtr->numChars, x + 1 - chunkPtr->x, TK_PARTIAL_OK, &dummy); return (chunkPtr->start + n - 1) - layoutPtr->string; } lastPtr = chunkPtr; chunkPtr++; i++; } /* * Point is to the right of all chars in all the chunks on this * line. Return the index just past the last char in the last * chunk on this line. */ pos = (lastPtr->start + lastPtr->numChars) - layoutPtr->string; if (i < layoutPtr->numChunks) { pos--; } return pos; } lastPtr = chunkPtr; chunkPtr++; } /* * Point lies below any line in this text layout. Return the index * just past the last char. */ return (lastPtr->start + lastPtr->numChars) - layoutPtr->string;}/* *--------------------------------------------------------------------------- * * Tk_CharBbox -- * * Use the information in the Tk_TextLayout token to return the * bounding box for the character specified by index. * * The width of the bounding box is the advance width of the * character, and does not include and left- or right-bearing. * Any character that extends partially outside of the * text layout is considered to be truncated at the edge. Any * character which is located completely outside of the text * layout is considered to be zero-width and pegged against * the edge. * * The height of the bounding box is the line height for this font, * extending from the top of the ascent to the bottom of the * descent. Information about the actual height of the individual * letter is not available. * * A text layout that contains no characters is considered to * contain a single zero-width placeholder character. * * Results: * The return value is 0 if the index did not specify a character * in the text layout, or non-zero otherwise. In that case, * *bbox is filled with the bounding box of the character. * * Side effects: * None. * *--------------------------------------------------------------------------- */intTk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) Tk_TextLayout layout; /* Layout information, from a previous call to * Tk_ComputeTextLayout(). */ int index; /* The index of the character whose bbox is * desired. */ int *xPtr, *yPtr; /* Filled with the upper-left hand corner, in * pixels, of the bounding box for the character * specified by index, if non-NULL. */ int *widthPtr, *heightPtr; /* Filled with the width and height of the * bounding box for the character specified by * index, if non-NULL. */{ TextLayout *layoutPtr; LayoutChunk *chunkPtr; int i, x, w; Tk_Font tkfont; TkFont *fontPtr; if (index < 0) { return 0; } layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; tkfont = layoutPtr->tkfont; fontPtr = (TkFont *) tkfont; for (i = 0; i < layoutPtr->numChunks; i++) { if (chunkPtr->numDisplayChars < 0) { if (index == 0) { x = chunkPtr->x; w = chunkPtr->totalWidth; goto check; } } else if (index < chunkPtr->numChars) { if (xPtr != NULL) { Tk_MeasureChars(tkfont, chunkPtr->start, index, 0, 0, &x); x += chunkPtr->x; } if (widthPtr != NULL) { Tk_MeasureChars(tkfont, chunkPtr->start + index, 1, 0, 0, &w); } goto check; } index -= chunkPtr->numChars; chunkPtr++; } if (index == 0) { /* * Special case to get location just past last char in layout. */ chunkPtr--; x = chunkPtr->x + chunkPtr->totalWidth; w = 0; } else { return 0; } /* * Ensure that the bbox lies within the text layout. This forces all * chars that extend off the right edge of the text layout to have * truncated widths, and all chars that are completely off the right * edge of the text layout to peg to the edge and have 0 width. */ check: if (yPtr != NULL) { *yPtr = chunkPtr->y - fontPtr->fm.ascent; } if (heightPtr != NULL) { *heightPtr = fontPtr->fm.ascent + fontPtr->fm.descent; } if (x > layoutPtr->width) { x = layoutPtr->width; } if (xPtr != NULL) { *xPtr = x; } if (widthPtr != NULL) { if (x + w > layoutPtr->width) { w = layoutPtr->width - x; } *widthPtr = w; } return 1;}/* *--------------------------------------------------------------------------- * * Tk_DistanceToTextLayout -- * * Computes the distance in pixels from the given point to the * given text layout. Non-displaying space characters that occur * at the end of individual lines in the text layout are ignored * for hit detection purposes. * * Results: * The return value is 0 if the point (x, y) is inside the text * layout. If the point isn't inside the text layout then the * return value is the distance in pixels from the point to the * text item. * * Side effects: * None. * *--------------------------------------------------------------------------- */intTk_DistanceToTextLayout(layout, x, y) Tk_TextLayout layout; /* Layout information, from a previous call * to Tk_ComputeTextLayout(). */ int x, y; /* Coordinates of point to check, with * respect to the upper-left corner of the * text layout (in pixels). */{ int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent; LayoutChunk *chunkPtr; TextLayout *layoutPtr; TkFont *fontPtr; layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; ascent = fontPtr->fm.ascent; descent = fontPtr->fm.descent; minDist = 0; chunkPtr = layoutPtr->chunks; for (i = 0; i < layoutPtr->numChunks; i++) { if (chunkPtr->start[0] == '\n') { /* * Newline characters are not counted when computing distance * (but tab characters would still be considered). */ chunkPtr++; continue; } x1 = chunkPtr->x; y1 = chunkPtr->y - ascent; x2 = chunkPtr->x + chunkPtr->displayWidth; y2 = chunkPtr->y + descent; if (x < x1) { xDiff = x1 - x; } else if (x >= x2) { xDiff = x - x2 + 1; } else { xDiff = 0; } if (y < y1) { yDiff = y1 - y; } else if (y >= y2) { yDiff = y - y2 + 1; } else { yDiff = 0; } if ((xDiff == 0) && (yDiff == 0)) { return 0; } dist = (int) hypot((double) xDiff, (double) yDiff); if ((dist < minDist) || (minDist == 0)) { minDist = dist; } chunkPtr++; } return minDist;}/* *--------------------------------------------------------------------------- * * Tk_IntersectTextLayout -- * * Determines whether a text layout lies entirely inside, * entirely outside, or overlaps a given rectangle. Non-displaying * space characters that occur at the end of individual lines in * the text layout are ignored for intersection calculations. * * Results: * The return value is -1 if the text layout is entirely outside of * the rectangle, 0 if it overlaps, and 1 if it is entirely inside * of the rectangle. * * Side effects: * None. * *--------------------------------------------------------------------------- */intTk_IntersectTextLayout(layout, x, y, width, height) Tk_TextLayout layout; /* Layout information, from a previous call * to Tk_ComputeTextLayout(). */ int x, y; /* Upper-left hand corner, in pixels, of * rectangular area to compare with text * layout. Coordinates are with respect to * the upper-left hand corner of the text * layout itself. */ int width, height; /* The width and height of the above * rectangular area, in pixels. */{ int result, i, x1, y1, x2, y2; TextLayout *layoutPtr; LayoutChunk *chunkPtr; TkFont *fontPtr; int left, top, right, bottom; /* * Scan the chunks one at a time, seeing whether each is entirely in, * entirely out, or overlapping the rectangle. If an overlap is * detected, return immediately; otherwise wait until all chunks have * been processed and see if they were all inside or all outside. */ layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; fontPtr = (TkFont *) layoutPtr->tkfont; left = x; top = y; right = x + width; bottom = y + height; result = 0; for (i = 0; i < layoutPtr->numChunks; i++) { if (chunkPtr->start[0] == '\n') { /* * Newline characters are not counted when computing area * intersection (but tab characters would still be considered). */ chunkPtr++; continue; } x1 = chunkPtr->x; y1 = chunkPtr->y - fontPtr->fm.ascent; x2 = chunkPtr->x + chunkPtr->displayWidth; y2 = chunkPtr->y + fontPtr->fm.descent; if ((right < x1) || (left >= x2) || (bottom < y1) || (top >= y2)) { if (result == 1) { return 0; } result = -1; } else if ((x1 < left) || (x2 >= right) || (y1 < top) || (y2 >= bottom)) { return 0; } else if (result == -1) { return 0; } else { result = 1; } chunkPtr++; } return result;}/* *--------------------------------------------------------------------------- * * Tk_TextLayoutToPostscript -- * * Outputs the contents of a text layout in Postscript format. * The set of lines in the text layout will be rendered by the user * supplied Postscript function. The function should be of the form: * * justify x y string function -- * * Justify is -1, 0, or 1, depending on whether the following string * should be left, center, or right justified, x and y is the * location for the origin of the string, string is the sequence * of characters to be printed, and function is the name of the * caller-provided function; the function should leave nothing * on the stack. * * The meaning of the origin of the string (x and y) depends on * the justification. For left justification, x is where the * left edge of the string should appear. For center justification, * x is where the center of the string should appear. And for right * justification, x is where the right edge of the string should * appear. This behavior is necessary because, for example, right * justified text on the screen is justified with screen metrics. * The same string needs to be justified with printer metrics on * the printer to appear in the correct place with respect to other * similarly justified strings. In all circumstances, y is the * location of the baseline for the string. * * Results: * Interp->result is modified to hold the Postscript code that * will render the text layout. * * Side effects: * None. * *--------------------------------------------------------------------------- */voidTk_TextLayoutToPostscript(interp, layout) Tcl_Interp *interp; /* Filled with Postscript code. */ Tk_TextLayout layout; /* The layout to be rendered. */{#define MAXUSE 128 char buf[MAXUSE+10]; LayoutChunk *chunkPtr; int i, j, used, c, baseline; TextLayout *layoutPtr; layoutPtr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -