Ejemplo n.º 1
0
/*
** Increase the headroom to create a paragraph break at the current token
*/
static void Paragraph(
  HtmlLayoutContext *pLC,
  HtmlElement *p
){
  int headroom;

  if( p==0 ){ TestPoint(0); return; }
  if( p->base.type==Html_Text ){
    headroom = p->text.ascent + p->text.descent;
    TestPoint(0);
  }else if( p->pNext && p->pNext->base.type==Html_Text ){
    headroom = p->pNext->text.ascent + p->pNext->text.descent;
    TestPoint(0);
  }else{
    Tk_FontMetrics fontMetrics;
    Tk_Font font;
    font = HtmlGetFont(pLC->htmlPtr, p->base.style.font);
    if( font==0 ) return;   
    Tk_GetFontMetrics(font, &fontMetrics);
    headroom = fontMetrics.descent + fontMetrics.ascent;
    TestPoint(0);
  }
  if( pLC->headRoom < headroom && pLC->bottom > pLC->top ){
    pLC->headRoom = headroom;
  }
}
Ejemplo n.º 2
0
static void
DisplayHorizontalValue(
    register TkScale *scalePtr,	/* Information about widget in which to
				 * display value. */
    Drawable drawable,		/* Pixmap or window in which to draw the
				 * value. */
    double value,		/* X-coordinate of number to display,
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int top)			/* Y-coordinate of top edge of text, specified
				 * in pixels. */
{
    register Tk_Window tkwin = scalePtr->tkwin;
    int x, y, length, width;
    char valueString[PRINT_CHARS];
    Tk_FontMetrics fm;

    x = TkScaleValueToPixel(scalePtr, value);
    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = top + fm.ascent;
    sprintf(valueString, scalePtr->format, value);
    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the x-coordinate if necessary to keep the text entirely inside
     * the window.
     */

    x -= (width)/2;
    if (x < (scalePtr->inset + SPACING)) {
	x = scalePtr->inset + SPACING;
    }

    /*
     * Check the right border so use starting point +text width for the check.
     */

    if (x + width >= (Tk_Width(tkwin) - scalePtr->inset)) {
	x = Tk_Width(tkwin) - scalePtr->inset - SPACING - width;
    }
    Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
	    scalePtr->tkfont, valueString, length, x, y);
}
Ejemplo n.º 3
0
static void
DisplayVerticalValue(
    register TkScale *scalePtr,	/* Information about widget in which to
				 * display value. */
    Drawable drawable,		/* Pixmap or window in which to draw the
				 * value. */
    double value,		/* Y-coordinate of number to display,
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int rightEdge)		/* X-coordinate of right edge of text,
				 * specified in pixels. */
{
    register Tk_Window tkwin = scalePtr->tkwin;
    int y, width, length;
    char valueString[PRINT_CHARS];
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = TkScaleValueToPixel(scalePtr, value) + fm.ascent/2;
    sprintf(valueString, scalePtr->format, value);
    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the y-coordinate if necessary to keep the text entirely inside
     * the window.
     */

    if ((y - fm.ascent) < (scalePtr->inset + SPACING)) {
	y = scalePtr->inset + SPACING + fm.ascent;
    }
    if ((y + fm.descent) > (Tk_Height(tkwin) - scalePtr->inset - SPACING)) {
	y = Tk_Height(tkwin) - scalePtr->inset - SPACING - fm.descent;
    }
    Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
	    scalePtr->tkfont, valueString, length, rightEdge - width, y);
}
Ejemplo n.º 4
0
void
TkpComputeButtonGeometry(
    register TkButton *butPtr)	/* Button whose geometry may have changed. */
{
    int width, height, avgWidth, txtWidth, txtHeight;
    int haveImage = 0, haveText = 0;
    Tk_FontMetrics fm;

    butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;

    /*
     * Leave room for the default ring if needed.
     */

    if (butPtr->defaultState != DEFAULT_DISABLED) {
	butPtr->inset += 5;
    }
    butPtr->indicatorSpace = 0;

    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;

    if (butPtr->image != NULL) {
	Tk_SizeOfImage(butPtr->image, &width, &height);
	haveImage = 1;
    } else if (butPtr->bitmap != None) {
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);

	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight;
	avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

    /*
     * If the button is compound (i.e., it shows both an image and text), the
     * new geometry is a combination of the image and text geometry. We only
     * honor the compound bit if the button has both text and an image,
     * because otherwise it is not really a compound button.
     */

    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
	switch ((enum compound) butPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM:
	    /*
	     * Image is above or below text.
	     */

	    height += txtHeight + butPtr->padY;
	    width = (width > txtWidth ? width : txtWidth);
	    break;
	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text.
	     */

	    width += txtWidth + butPtr->padX;
	    height = (height > txtHeight ? height : txtHeight);
	    break;
	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed.
	     */

	    width = (width > txtWidth ? width : txtWidth);
	    height = (height > txtHeight ? height : txtHeight);
	    break;
	case COMPOUND_NONE:
	    break;
	}
	if (butPtr->width > 0) {
	    width = butPtr->width;
	}
	if (butPtr->height > 0) {
	    height = butPtr->height;
	}

	if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
	    butPtr->indicatorSpace = height;
	    if (butPtr->type == TYPE_CHECK_BUTTON) {
		butPtr->indicatorDiameter = (65*height)/100;
	    } else {
		butPtr->indicatorDiameter = (75*height)/100;
	    }
	}

	width += 2*butPtr->padX;
	height += 2*butPtr->padY;
    } else {
	if (haveImage) {
	    if (butPtr->width > 0) {
		width = butPtr->width;
	    }
	    if (butPtr->height > 0) {
		height = butPtr->height;
	    }

	    if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
		butPtr->indicatorSpace = height;
		if (butPtr->type == TYPE_CHECK_BUTTON) {
		    butPtr->indicatorDiameter = (65*height)/100;
		} else {
		    butPtr->indicatorDiameter = (75*height)/100;
		}
	    }
	} else {
	    width = txtWidth;
	    height = txtHeight;

	    if (butPtr->width > 0) {
		width = butPtr->width * avgWidth;
	    }
	    if (butPtr->height > 0) {
		height = butPtr->height * fm.linespace;
	    }
	    if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
		butPtr->indicatorDiameter = fm.linespace;
		if (butPtr->type == TYPE_CHECK_BUTTON) {
		    butPtr->indicatorDiameter =
			(80*butPtr->indicatorDiameter)/100;
		}
		butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
	    }
	}
    }

    /*
     * When issuing the geometry request, add extra space for the indicator,
     * if any, and for the border and padding, plus two extra pixels so the
     * display can be offset by 1 pixel in either direction for the raised or
     * lowered effect.
     */

    if ((butPtr->image == NULL) && (butPtr->bitmap == None)) {
	width += 2*butPtr->padX;
	height += 2*butPtr->padY;
    }
    if ((butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin)) {
	width += 2;
	height += 2;
    }
    Tk_GeometryRequest(butPtr->tkwin, (int) (width + butPtr->indicatorSpace
	    + 2*butPtr->inset), (int) (height + 2*butPtr->inset));
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}
Ejemplo n.º 5
0
static void
DisplayVerticalScale(
    TkScale *scalePtr,		/* Widget record for scale. */
    Drawable drawable,		/* Where to display scale (window or
				 * pixmap). */
    XRectangle *drawnAreaPtr)	/* Initally contains area of window; if only a
				 * part of the scale is redrawn, gets modified
				 * to reflect the part of the window that was
				 * redrawn. */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int x, y, width, height, shadowWidth;
    double tickValue, tickInterval = scalePtr->tickInterval;
    Tk_3DBorder sliderBorder;

    /*
     * Display the information from left to right across the window.
     */

    if (!(scalePtr->flags & REDRAW_OTHER)) {
	drawnAreaPtr->x = scalePtr->vertTickRightX;
	drawnAreaPtr->y = scalePtr->inset;
	drawnAreaPtr->width = scalePtr->vertTroughX + scalePtr->width
		+ 2*scalePtr->borderWidth - scalePtr->vertTickRightX;
	drawnAreaPtr->height -= 2*scalePtr->inset;
    }
    Tk_Fill3DRectangle(tkwin, drawable, scalePtr->bgBorder,
	    drawnAreaPtr->x, drawnAreaPtr->y, drawnAreaPtr->width,
	    drawnAreaPtr->height, 0, TK_RELIEF_FLAT);
    if (scalePtr->flags & REDRAW_OTHER) {
	/*
	 * Display the tick marks.
	 */

	if (tickInterval != 0) {
	    double ticks, maxTicks;

	    /*
	     * Ensure that we will only draw enough of the tick values such
	     * that they don't overlap
	     */

	    ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
		    / tickInterval);
	    maxTicks = (double) Tk_Height(tkwin)
		    / (double) scalePtr->fontHeight;
	    if (ticks > maxTicks) {
		tickInterval *= (ticks / maxTicks);
	    }
	    for (tickValue = scalePtr->fromValue; ;
		    tickValue += tickInterval) {
		/*
		 * The TkRoundToResolution call gets rid of accumulated
		 * round-off errors, if any.
		 */

		tickValue = TkRoundToResolution(scalePtr, tickValue);
		if (scalePtr->toValue >= scalePtr->fromValue) {
		    if (tickValue > scalePtr->toValue) {
			break;
		    }
		} else {
		    if (tickValue < scalePtr->toValue) {
			break;
		    }
		}
		DisplayVerticalValue(scalePtr, drawable, tickValue,
			scalePtr->vertTickRightX);
	    }
	}
    }

    /*
     * Display the value, if it is desired.
     */

    if (scalePtr->showValue) {
	DisplayVerticalValue(scalePtr, drawable, scalePtr->value,
		scalePtr->vertValueRightX);
    }

    /*
     * Display the trough and the slider.
     */

    Tk_Draw3DRectangle(tkwin, drawable,
	    scalePtr->bgBorder, scalePtr->vertTroughX, scalePtr->inset,
	    scalePtr->width + 2*scalePtr->borderWidth,
	    Tk_Height(tkwin) - 2*scalePtr->inset, scalePtr->borderWidth,
	    TK_RELIEF_SUNKEN);
    XFillRectangle(scalePtr->display, drawable, scalePtr->troughGC,
	    scalePtr->vertTroughX + scalePtr->borderWidth,
	    scalePtr->inset + scalePtr->borderWidth,
	    (unsigned) scalePtr->width,
	    (unsigned) (Tk_Height(tkwin) - 2*scalePtr->inset
		- 2*scalePtr->borderWidth));
    if (scalePtr->state == STATE_ACTIVE) {
	sliderBorder = scalePtr->activeBorder;
    } else {
	sliderBorder = scalePtr->bgBorder;
    }
    width = scalePtr->width;
    height = scalePtr->sliderLength/2;
    x = scalePtr->vertTroughX + scalePtr->borderWidth;
    y = TkScaleValueToPixel(scalePtr, scalePtr->value) - height;
    shadowWidth = scalePtr->borderWidth/2;
    if (shadowWidth == 0) {
	shadowWidth = 1;
    }
    Tk_Draw3DRectangle(tkwin, drawable, sliderBorder, x, y, width,
	    2*height, shadowWidth, scalePtr->sliderRelief);
    x += shadowWidth;
    y += shadowWidth;
    width -= 2*shadowWidth;
    height -= shadowWidth;
    Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y, width,
	    height, shadowWidth, scalePtr->sliderRelief);
    Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y+height,
	    width, height, shadowWidth, scalePtr->sliderRelief);

    /*
     * Draw the label to the right of the scale.
     */

    if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
	Tk_FontMetrics fm;

	Tk_GetFontMetrics(scalePtr->tkfont, &fm);
	Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
		scalePtr->tkfont, scalePtr->label,
                scalePtr->labelLength, scalePtr->vertLabelX,
                scalePtr->inset + (3*fm.ascent)/2);
    }
}
Ejemplo n.º 6
0
static void
DisplayHorizontalScale(
    TkScale *scalePtr,		/* Widget record for scale. */
    Drawable drawable,		/* Where to display scale (window or
				 * pixmap). */
    XRectangle *drawnAreaPtr)	/* Initally contains area of window; if only a
				 * part of the scale is redrawn, gets modified
				 * to reflect the part of the window that was
				 * redrawn. */
{
    register Tk_Window tkwin = scalePtr->tkwin;
    int x, y, width, height, shadowWidth;
    double tickValue, tickInterval = scalePtr->tickInterval;
    Tk_3DBorder sliderBorder;

    /*
     * Display the information from bottom to top across the window.
     */

    if (!(scalePtr->flags & REDRAW_OTHER)) {
	drawnAreaPtr->x = scalePtr->inset;
	drawnAreaPtr->y = scalePtr->horizValueY;
	drawnAreaPtr->width -= 2*scalePtr->inset;
	drawnAreaPtr->height = scalePtr->horizTroughY + scalePtr->width
		+ 2*scalePtr->borderWidth - scalePtr->horizValueY;
    }
    Tk_Fill3DRectangle(tkwin, drawable, scalePtr->bgBorder,
	    drawnAreaPtr->x, drawnAreaPtr->y, drawnAreaPtr->width,
	    drawnAreaPtr->height, 0, TK_RELIEF_FLAT);
    if (scalePtr->flags & REDRAW_OTHER) {
	/*
	 * Display the tick marks.
	 */

	if (tickInterval != 0) {
	    char valueString[PRINT_CHARS];
	    double ticks, maxTicks;

	    /*
	     * Ensure that we will only draw enough of the tick values such
	     * that they don't overlap. We base this off the width that
	     * fromValue would take. Not exact, but better than no constraint.
	     */

	    ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
		    / tickInterval);
	    sprintf(valueString, scalePtr->format, scalePtr->fromValue);
	    maxTicks = (double) Tk_Width(tkwin)
		    / (double) Tk_TextWidth(scalePtr->tkfont, valueString, -1);
	    if (ticks > maxTicks) {
		tickInterval *= (ticks / maxTicks);
	    }
	    for (tickValue = scalePtr->fromValue; ;
		 tickValue += tickInterval) {
		/*
		 * The TkRoundToResolution call gets rid of accumulated
		 * round-off errors, if any.
		 */

		tickValue = TkRoundToResolution(scalePtr, tickValue);
		if (scalePtr->toValue >= scalePtr->fromValue) {
		    if (tickValue > scalePtr->toValue) {
			break;
		    }
		} else {
		    if (tickValue < scalePtr->toValue) {
			break;
		    }
		}
		DisplayHorizontalValue(scalePtr, drawable, tickValue,
			scalePtr->horizTickY);
	    }
	}
    }

    /*
     * Display the value, if it is desired.
     */

    if (scalePtr->showValue) {
	DisplayHorizontalValue(scalePtr, drawable, scalePtr->value,
		scalePtr->horizValueY);
    }

    /*
     * Display the trough and the slider.
     */

    y = scalePtr->horizTroughY;
    Tk_Draw3DRectangle(tkwin, drawable,
	    scalePtr->bgBorder, scalePtr->inset, y,
	    Tk_Width(tkwin) - 2*scalePtr->inset,
	    scalePtr->width + 2*scalePtr->borderWidth,
	    scalePtr->borderWidth, TK_RELIEF_SUNKEN);
    XFillRectangle(scalePtr->display, drawable, scalePtr->troughGC,
	    scalePtr->inset + scalePtr->borderWidth,
	    y + scalePtr->borderWidth,
	    (unsigned) (Tk_Width(tkwin) - 2*scalePtr->inset
		- 2*scalePtr->borderWidth),
	    (unsigned) scalePtr->width);
    if (scalePtr->state == STATE_ACTIVE) {
	sliderBorder = scalePtr->activeBorder;
    } else {
	sliderBorder = scalePtr->bgBorder;
    }
    width = scalePtr->sliderLength/2;
    height = scalePtr->width;
    x = TkScaleValueToPixel(scalePtr, scalePtr->value) - width;
    y += scalePtr->borderWidth;
    shadowWidth = scalePtr->borderWidth/2;
    if (shadowWidth == 0) {
	shadowWidth = 1;
    }
    Tk_Draw3DRectangle(tkwin, drawable, sliderBorder,
	    x, y, 2*width, height, shadowWidth, scalePtr->sliderRelief);
    x += shadowWidth;
    y += shadowWidth;
    width -= shadowWidth;
    height -= 2*shadowWidth;
    Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y, width, height,
	    shadowWidth, scalePtr->sliderRelief);
    Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x+width, y,
	    width, height, shadowWidth, scalePtr->sliderRelief);

    /*
     * Draw the label at the top of the scale.
     */

    if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
	Tk_FontMetrics fm;

	Tk_GetFontMetrics(scalePtr->tkfont, &fm);
	Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
		scalePtr->tkfont, scalePtr->label,
                scalePtr->labelLength, scalePtr->inset + fm.ascent/2,
                scalePtr->horizLabelY + fm.ascent);
    }
}
Ejemplo n.º 7
0
void
TkpComputeMenubarGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int width, height, i, j, x, y, currentRowHeight, maxWidth;
    int maxWindowWidth, lastRowBreak, lastEntry;
    int borderWidth, activeBorderWidth, helpMenuIndex = -1;
    TkMenuEntry *mePtr;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    maxWidth = 0;
    if (menuPtr->numEntries == 0) {
	height = 0;
    } else {
	int borderWidth;

	maxWindowWidth = Tk_Width(menuPtr->tkwin);
	if (maxWindowWidth == 1) {
	    maxWindowWidth = 0x7ffffff;
	}
	currentRowHeight = 0;
	Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
		&borderWidth);
	x = y = borderWidth;
	lastRowBreak = 0;

	/*
	 * On the Mac especially, getting font metrics can be quite slow, so
	 * we want to do it intelligently. We are going to precalculate them
	 * and pass them down to all of the measureing and drawing routines.
	 * We will measure the font metrics of the menu once, and if an entry
	 * has a font set, we will measure it as we come to it, and then we
	 * decide which set to give the geometry routines.
	 */

	menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
	Tk_GetFontMetrics(menuFont, &menuMetrics);

	for (i = 0; i < menuPtr->numEntries; i++) {
	    mePtr = menuPtr->entries[i];
	    mePtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    if (mePtr->fontPtr != NULL) {
		tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
		Tk_GetFontMetrics(tkfont, &entryMetrics);
		fmPtr = &entryMetrics;
	    } else {
		tkfont = menuFont;
		fmPtr = &menuMetrics;
	    }

	    /*
	     * For every entry, we need to check to see whether or not we
	     * wrap. If we do wrap, then we have to adjust all of the previous
	     * entries' height and y position, because when we see them the
	     * first time, we don't know how big its neighbor might be.
	     */

	    if ((mePtr->type == SEPARATOR_ENTRY)
		    || (mePtr->type == TEAROFF_ENTRY)) {
		mePtr->height = mePtr->width = 0;
	    } else {
		GetMenuLabelGeometry(mePtr, tkfont, fmPtr, &width, &height);
		mePtr->height = height + 2 * activeBorderWidth + 10;
		mePtr->width = width;

		GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont, fmPtr,
			&width, &height);
		mePtr->indicatorSpace = width;
		if (width > 0) {
		    mePtr->width += width;
		}
		mePtr->width += 2 * activeBorderWidth + 10;
	    }
	    if (mePtr->entryFlags & ENTRY_HELP_MENU) {
		helpMenuIndex = i;
	    } else if (x + mePtr->width + borderWidth > maxWindowWidth) {
		if (i == lastRowBreak) {
		    mePtr->y = y;
		    mePtr->x = x;
		    lastRowBreak++;
		    y += mePtr->height;
		    currentRowHeight = 0;
		} else {
		    x = borderWidth;
		    for (j = lastRowBreak; j < i; j++) {
			menuPtr->entries[j]->y = y + currentRowHeight
				- menuPtr->entries[j]->height;
			menuPtr->entries[j]->x = x;
			x += menuPtr->entries[j]->width;
		    }
		    lastRowBreak = i;
		    y += currentRowHeight;
		    currentRowHeight = mePtr->height;
		}
		if (x > maxWidth) {
		    maxWidth = x;
		}
		x = borderWidth;
	    } else {
		x += mePtr->width;
		if (mePtr->height > currentRowHeight) {
		    currentRowHeight = mePtr->height;
		}
	    }
	}

	lastEntry = menuPtr->numEntries - 1;
	if (helpMenuIndex == lastEntry) {
	    lastEntry--;
	}
	if ((lastEntry >= 0) && (x + menuPtr->entries[lastEntry]->width
		+ borderWidth > maxWidth)) {
	    maxWidth = x + menuPtr->entries[lastEntry]->width + borderWidth;
	}
	x = borderWidth;
	for (j = lastRowBreak; j < menuPtr->numEntries; j++) {
	    if (j == helpMenuIndex) {
		continue;
	    }
	    menuPtr->entries[j]->y = y + currentRowHeight
		    - menuPtr->entries[j]->height;
	    menuPtr->entries[j]->x = x;
	    x += menuPtr->entries[j]->width;
	}


	if (helpMenuIndex != -1) {
	    mePtr = menuPtr->entries[helpMenuIndex];
	    if (x + mePtr->width + borderWidth > maxWindowWidth) {
		y += currentRowHeight;
		currentRowHeight = mePtr->height;
		x = borderWidth;
	    } else if (mePtr->height > currentRowHeight) {
		currentRowHeight = mePtr->height;
	    }
	    mePtr->x = maxWindowWidth - borderWidth - mePtr->width;
	    mePtr->y = y + currentRowHeight - mePtr->height;
	}
	height = y + currentRowHeight + borderWidth;
    }
    width = Tk_Width(menuPtr->tkwin);

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */

    if (width <= 0) {
	width = 1;
    }
    if (height <= 0) {
	height = 1;
    }
    menuPtr->totalWidth = maxWidth;
    menuPtr->totalHeight = height;
}
Ejemplo n.º 8
0
void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int x, y, height, width, indicatorSpace, labelWidth, accelWidth;
    int windowWidth, windowHeight, accelSpace, i, j, lastColumnBreak = 0;
    TkMenuEntry *mePtr;
    int borderWidth, activeBorderWidth;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    x = y = borderWidth;
    indicatorSpace = labelWidth = accelWidth = 0;
    windowHeight = windowWidth = 0;

    /*
     * On the Mac especially, getting font metrics can be quite slow, so we
     * want to do it intelligently. We are going to precalculate them and pass
     * them down to all of the measuring and drawing routines. We will measure
     * the font metrics of the menu once. If an entry does not have its own
     * font set, then we give the geometry/drawing routines the menu's font
     * and metrics. If an entry has its own font, we will measure that font
     * and give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    accelSpace = Tk_TextWidth(menuFont, "M", 1);

    for (i = 0; i < menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);
	    fmPtr = &entryMetrics;
	}

	if ((i > 0) && mePtr->columnBreak) {
	    if (accelWidth != 0) {
		labelWidth += accelSpace;
	    }
	    for (j = lastColumnBreak; j < i; j++) {
		menuPtr->entries[j]->indicatorSpace = indicatorSpace;
		menuPtr->entries[j]->labelWidth = labelWidth;
		menuPtr->entries[j]->width = indicatorSpace + labelWidth
			+ accelWidth + 2 * activeBorderWidth;
		menuPtr->entries[j]->x = x;
		menuPtr->entries[j]->entryFlags &= ~ENTRY_LAST_COLUMN;
	    }
	    x += indicatorSpace + labelWidth + accelWidth
		    + 2 * activeBorderWidth;
	    windowWidth = x;
	    indicatorSpace = labelWidth = accelWidth = 0;
	    lastColumnBreak = i;
	    y = borderWidth;
	}

	if (mePtr->type == SEPARATOR_ENTRY) {
	    GetMenuSeparatorGeometry(menuPtr, mePtr, tkfont, fmPtr,
		    &width, &height);
	    mePtr->height = height;
	} else if (mePtr->type == TEAROFF_ENTRY) {
	    GetTearoffEntryGeometry(menuPtr, mePtr, tkfont, fmPtr,
		    &width, &height);
	    mePtr->height = height;
	    labelWidth = width;
	} else {
	    /*
	     * For each entry, compute the height required by that particular
	     * entry, plus three widths: the width of the label, the width to
	     * allow for an indicator to be displayed to the left of the label
	     * (if any), and the width of the accelerator to be displayed to
	     * the right of the label (if any). These sizes depend, of course,
	     * on the type of the entry.
	     */

	    GetMenuLabelGeometry(mePtr, tkfont, fmPtr, &width, &height);
	    mePtr->height = height;
	    if (!mePtr->hideMargin) {
		width += MENU_MARGIN_WIDTH;
	    }
	    if (width > labelWidth) {
	    	labelWidth = width;
	    }

	    GetMenuAccelGeometry(menuPtr, mePtr, tkfont,
		    fmPtr, &width, &height);
	    if (height > mePtr->height) {
	    	mePtr->height = height;
	    }
	    if (!mePtr->hideMargin) {
		width += MENU_MARGIN_WIDTH;
	    }
	    if (width > accelWidth) {
	    	accelWidth = width;
	    }

	    GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont, fmPtr,
		    &width, &height);
	    if (height > mePtr->height) {
	    	mePtr->height = height;
	    }
	    if (!mePtr->hideMargin) {
		width += MENU_MARGIN_WIDTH;
	    }
	    if (width > indicatorSpace) {
	    	indicatorSpace = width;
	    }

	    mePtr->height += 2 * activeBorderWidth + MENU_DIVIDER_HEIGHT;
    	}
	mePtr->y = y;
	y += mePtr->height;
	if (y > windowHeight) {
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < menuPtr->numEntries; j++) {
	menuPtr->entries[j]->indicatorSpace = indicatorSpace;
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + indicatorSpace + labelWidth + accelWidth
	    + 2 * activeBorderWidth + 2 * borderWidth;

    windowHeight += borderWidth;

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */

    if (windowWidth <= 0) {
	windowWidth = 1;
    }
    if (windowHeight <= 0) {
	windowHeight = 1;
    }
    menuPtr->totalWidth = windowWidth;
    menuPtr->totalHeight = windowHeight;
}
Ejemplo n.º 9
0
void
TkpDrawMenuEntry(
    TkMenuEntry *mePtr,		/* The entry to draw */
    Drawable d,			/* What to draw into */
    Tk_Font tkfont,		/* Precalculated font for menu */
    const Tk_FontMetrics *menuMetricsPtr,
				/* Precalculated metrics for menu */
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawArrow)		/* Whether or not to draw the cascade arrow
				 * for cascade items. Only applies to
				 * Windows. */
{
    GC gc, indicatorGC;
    XColor *indicatorColor, *disableColor = NULL;
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_3DBorder bgBorder, activeBorder;
    const Tk_FontMetrics *fmPtr;
    Tk_FontMetrics entryMetrics;
    int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
    int adjustedY = y + padY;
    int adjustedHeight = height - 2 * padY;

    /*
     * Choose the gc for drawing the foreground part of the entry.
     */

    if ((mePtr->state == ENTRY_ACTIVE) && !strictMotif) {
	gc = mePtr->activeGC;
	if (gc == NULL) {
	    gc = menuPtr->activeGC;
	}
    } else {
    	TkMenuEntry *cascadeEntryPtr;
    	int parentDisabled = 0;

    	for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
    		cascadeEntryPtr != NULL;
    		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	    if (cascadeEntryPtr->namePtr != NULL) {
		const char *name = Tcl_GetString(cascadeEntryPtr->namePtr);

		if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
		    if (cascadeEntryPtr->state == ENTRY_DISABLED) {
			parentDisabled = 1;
		    }
		    break;
    	    	}
    	    }
    	}

	if (((parentDisabled || (mePtr->state == ENTRY_DISABLED)))
		&& (menuPtr->disabledFgPtr != NULL)) {
	    gc = mePtr->disabledGC;
	    if (gc == NULL) {
		gc = menuPtr->disabledGC;
	    }
	} else {
	    gc = mePtr->textGC;
	    if (gc == NULL) {
		gc = menuPtr->textGC;
	    }
	}
    }
    indicatorGC = mePtr->indicatorGC;
    if (indicatorGC == NULL) {
	indicatorGC = menuPtr->indicatorGC;
    }
    if (mePtr->indicatorFgPtr) {
	indicatorColor = Tk_GetColorFromObj(menuPtr->tkwin,
		mePtr->indicatorFgPtr);
    } else {
	indicatorColor = Tk_GetColorFromObj(menuPtr->tkwin,
		menuPtr->indicatorFgPtr);
    }

    if (menuPtr->disabledFgPtr != NULL) {
	disableColor = Tk_GetColorFromObj(menuPtr->tkwin,
		menuPtr->disabledFgPtr);
    }

    bgBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
	    (mePtr->borderPtr == NULL)
	    ? menuPtr->borderPtr : mePtr->borderPtr);
    if (strictMotif) {
	activeBorder = bgBorder;
    } else {
	activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
	    (mePtr->activeBorderPtr == NULL)
	    ? menuPtr->activeBorderPtr : mePtr->activeBorderPtr);
    }

    if (mePtr->fontPtr == NULL) {
	fmPtr = menuMetricsPtr;
    } else {
	tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	Tk_GetFontMetrics(tkfont, &entryMetrics);
	fmPtr = &entryMetrics;
    }

    /*
     * Need to draw the entire background, including padding. On Unix, for
     * menubars, we have to draw the rest of the entry taking into account the
     * padding.
     */

    DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder,
	    bgBorder, x, y, width, height);

    if (mePtr->type == SEPARATOR_ENTRY) {
	DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont,
		fmPtr, x, adjustedY, width, adjustedHeight);
    } else if (mePtr->type == TEAROFF_ENTRY) {
	DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
    } else {
	DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
	DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
		activeBorder, x, adjustedY, width, adjustedHeight, drawArrow);
	if (!mePtr->hideMargin) {
	    if (mePtr->state == ENTRY_ACTIVE) {
		bgBorder = activeBorder;
	    }
	    DrawMenuEntryIndicator(menuPtr, mePtr, d, bgBorder, indicatorColor,
		    disableColor, tkfont, fmPtr, x, adjustedY, width,
		    adjustedHeight);
	}
    }
}
Ejemplo n.º 10
0
/*
** Compute the size of all elements in the widget.  Assume that a
** style has already been assigned to all elements.
**
** Some of the elements might have already been sized.  Refer to the
** htmlPtr->lastSized and only compute sizes for elements that follow
** this one.  If htmlPtr->lastSized==0, then size everything.
**
** This routine only computes the sizes of individual elements.  The
** size of aggregate elements (like tables) are computed separately.
**
** The HTML_Visible flag is also set on every element that results
** in ink on the page.
**
** This routine may invoke a callback procedure which could delete
** the HTML widget.
*/
void HtmlSizer(HtmlWidget *htmlPtr){
  HtmlElement *p;
  int iFont = -1;
  Tk_Font font;
  int spaceWidth = 0;
  Tk_FontMetrics fontMetrics;
  char *z;
  int stop = 0;

  if( htmlPtr->pFirst==0 ){ TestPoint(0); return; }
  if( htmlPtr->lastSized==0 ){
    p = htmlPtr->pFirst;
    TestPoint(0);
  }else{
    p = htmlPtr->lastSized->pNext;
    TestPoint(0);
  }
  for(; !stop && p; p=p->pNext){
    if( p->base.style.flags & STY_Invisible ){
      p->base.flags &= ~HTML_Visible;
      TestPoint(0);
      continue;
    }
    if( iFont != p->base.style.font ){
      iFont = p->base.style.font;
      HtmlLock(htmlPtr);
      font = HtmlGetFont(htmlPtr, iFont);
      if( HtmlUnlock(htmlPtr) ) break;
      Tk_GetFontMetrics(font, &fontMetrics);
      spaceWidth = 0;
    }
    switch( p->base.type ){
      case Html_Text:
        p->text.w = Tk_TextWidth(font, p->text.zText, p->base.count);
        p->base.flags |= HTML_Visible;
        p->text.descent = fontMetrics.descent;
        p->text.ascent = fontMetrics.ascent;
        if( spaceWidth==0 ){
          spaceWidth = Tk_TextWidth(font, " ", 1);
          TestPoint(0);
        }else{
          TestPoint(0);
        }
        p->text.spaceWidth = spaceWidth;
        break;
      case Html_Space:
        if( spaceWidth==0 ){
          spaceWidth = Tk_TextWidth(font, " ", 1);
        }
        p->space.w = spaceWidth;
        p->space.descent = fontMetrics.descent;
        p->space.ascent = fontMetrics.ascent;
        p->base.flags &= ~HTML_Visible;
        break;
      case Html_TD:
      case Html_TH:
        z = HtmlMarkupArg(p, "rowspan","1");
        p->cell.rowspan = atoi(z);
        z = HtmlMarkupArg(p, "colspan","1");
        p->cell.colspan = atoi(z);
        p->base.flags |= HTML_Visible;
        TestPoint(0);
        break;
      case Html_LI:
        p->li.descent = fontMetrics.descent;
        p->li.ascent = fontMetrics.ascent;
        p->base.flags |= HTML_Visible;
        TestPoint(0);
        break;
      case Html_IMG:
        p->base.flags |= HTML_Visible;
        p->image.redrawNeeded = 0;
        p->image.textAscent = fontMetrics.ascent;
        p->image.textDescent = fontMetrics.descent;
        p->image.align = HtmlGetImageAlignment(p);
        if( p->image.pImage==0 ){
          p->image.ascent = fontMetrics.ascent;
          p->image.descent = fontMetrics.descent;
          p->image.zAlt = HtmlMarkupArg(p, "alt", "<image>");
          p->image.w = Tk_TextWidth(font, p->image.zAlt, strlen(p->image.zAlt));
        }else{
          int w, h;
          p->image.pNext = p->image.pImage->pList;
          p->image.pImage->pList = p;
          Tk_SizeOfImage(p->image.pImage->image, &w, &h);
          p->image.h = h;
          p->image.w = w;
          p->image.ascent = h/2;
          p->image.descent = h - p->image.ascent;
        }
        if( (z = HtmlMarkupArg(p, "width", 0))!=0 ){
          int w = atoi(z);
          if( w>0 ) p->image.w = w;
        }
        if( (z = HtmlMarkupArg(p, "height", 0))!=0 ){
          int h = atoi(z);
          if( h>0 ) p->image.h = h;
        }
        break;
      case Html_HR:
      case Html_TABLE:
        p->base.flags |= HTML_Visible;
        TestPoint(0);
        break;
      case Html_APPLET:
      case Html_EMBED:
      case Html_INPUT:
        p->input.textAscent = fontMetrics.ascent;
        p->input.textDescent = fontMetrics.descent;
        stop = HtmlControlSize(htmlPtr, p);
        break;
      case Html_SELECT:
      case Html_TEXTAREA:
        p->input.textAscent = fontMetrics.ascent;
        p->input.textDescent = fontMetrics.descent;
        break;
      case Html_EndSELECT:
      case Html_EndTEXTAREA:
        if( p->ref.pOther ){
          p->ref.pOther->input.pEnd = p;
          stop = HtmlControlSize(htmlPtr, p->ref.pOther);
        }
        break;
      default:
        p->base.flags &= ~HTML_Visible;
        break;
    }
  }
  if( p ){
    htmlPtr->lastSized = p;
  }else{
    htmlPtr->lastSized = htmlPtr->pLast;
  }
}
Ejemplo n.º 11
0
void
TkpComputeMenuButtonGeometry(
    TkMenuButton *mbPtr)	/* Widget record for menu button. */
{
    int width, height, mm, pixels;
    int	 avgWidth, txtWidth, txtHeight;
    int haveImage = 0, haveText = 0;
    Tk_FontMetrics fm;

    mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth;

    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;

    if (mbPtr->image != None) {
	Tk_SizeOfImage(mbPtr->image, &width, &height);
	haveImage = 1;
    } else if (mbPtr->bitmap != None) {
	Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || mbPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(mbPtr->textLayout);

	mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text,
		-1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth,
		&mbPtr->textHeight);
	txtWidth = mbPtr->textWidth;
	txtHeight = mbPtr->textHeight;
	avgWidth = Tk_TextWidth(mbPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(mbPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

    /*
     * If the menubutton is compound (ie, it shows both an image and text),
     * the new geometry is a combination of the image and text geometry. We
     * only honor the compound bit if the menubutton has both text and an
     * image, because otherwise it is not really a compound menubutton.
     */

    if (mbPtr->compound != COMPOUND_NONE && haveImage && haveText) {
	switch ((enum compound) mbPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM:
	    /*
	     * Image is above or below text.
	     */

	    height += txtHeight + mbPtr->padY;
	    width = (width > txtWidth ? width : txtWidth);
	    break;
	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text.
	     */

	    width += txtWidth + mbPtr->padX;
	    height = (height > txtHeight ? height : txtHeight);
	    break;
	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed.
	     */

	    width = (width > txtWidth ? width : txtWidth);
	    height = (height > txtHeight ? height : txtHeight);
	    break;
	case COMPOUND_NONE:
	    break;
	}
	if (mbPtr->width > 0) {
	    width = mbPtr->width;
	}
	if (mbPtr->height > 0) {
	    height = mbPtr->height;
	}
	width += 2*mbPtr->padX;
	height += 2*mbPtr->padY;
    } else {
	if (haveImage) {
	    if (mbPtr->width > 0) {
		width = mbPtr->width;
	    }
	    if (mbPtr->height > 0) {
		height = mbPtr->height;
	    }
	} else {
	    width = txtWidth;
	    height = txtHeight;
	    if (mbPtr->width > 0) {
		width = mbPtr->width * avgWidth;
	    }
	    if (mbPtr->height > 0) {
		height = mbPtr->height * fm.linespace;
	    }
	}
    }

    if (! haveImage) {
	width += 2*mbPtr->padX;
	height += 2*mbPtr->padY;
    }

    if (mbPtr->indicatorOn) {
	mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin));
	pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin));
	mbPtr->indicatorHeight= (INDICATOR_HEIGHT * pixels)/(10*mm);
	mbPtr->indicatorWidth = (INDICATOR_WIDTH * pixels)/(10*mm)
		+ 2*mbPtr->indicatorHeight;
	width += mbPtr->indicatorWidth;
    } else {
	mbPtr->indicatorHeight = 0;
	mbPtr->indicatorWidth = 0;
    }

    Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset),
	    (int) (height + 2*mbPtr->inset));
    Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset);
}
Ejemplo n.º 12
0
static void
ComputeScaleGeometry(
    register TkScale *scalePtr)	/* Information about widget. */
{
    char valueString[PRINT_CHARS];
    int tmp, valuePixels, x, y, extraSpace;
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    scalePtr->fontHeight = fm.linespace + SPACING;

    /*
     * Horizontal scales are simpler than vertical ones because all sizes are
     * the same (the height of a line of text); handle them first and then
     * quit.
     */

    if (scalePtr->orient == ORIENT_HORIZONTAL) {
        y = scalePtr->inset;
        extraSpace = 0;
        if (scalePtr->labelLength != 0) {
            scalePtr->horizLabelY = y + SPACING;
            y += scalePtr->fontHeight;
            extraSpace = SPACING;
        }
        if (scalePtr->showValue) {
            scalePtr->horizValueY = y + SPACING;
            y += scalePtr->fontHeight;
            extraSpace = SPACING;
        } else {
            scalePtr->horizValueY = y;
        }
        y += extraSpace;
        scalePtr->horizTroughY = y;
        y += scalePtr->width + 2*scalePtr->borderWidth;
        if (scalePtr->tickInterval != 0) {
            scalePtr->horizTickY = y + SPACING;
            y += scalePtr->fontHeight + SPACING;
        }
        Tk_GeometryRequest(scalePtr->tkwin,
                           scalePtr->length + 2*scalePtr->inset, y + scalePtr->inset);
        Tk_SetInternalBorder(scalePtr->tkwin, scalePtr->inset);
        return;
    }

    /*
     * Vertical scale: compute the amount of space needed to display the
     * scales value by formatting strings for the two end points; use
     * whichever length is longer.
     */

    sprintf(valueString, scalePtr->format, scalePtr->fromValue);
    valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);

    sprintf(valueString, scalePtr->format, scalePtr->toValue);
    tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
    if (valuePixels < tmp) {
        valuePixels = tmp;
    }

    /*
     * Assign x-locations to the elements of the scale, working from left to
     * right.
     */

    x = scalePtr->inset;
    if ((scalePtr->tickInterval != 0) && (scalePtr->showValue)) {
        scalePtr->vertTickRightX = x + SPACING + valuePixels;
        scalePtr->vertValueRightX = scalePtr->vertTickRightX + valuePixels
                                    + fm.ascent/2;
        x = scalePtr->vertValueRightX + SPACING;
    } else if (scalePtr->tickInterval != 0) {
        scalePtr->vertTickRightX = x + SPACING + valuePixels;
        scalePtr->vertValueRightX = scalePtr->vertTickRightX;
        x = scalePtr->vertTickRightX + SPACING;
    } else if (scalePtr->showValue) {
        scalePtr->vertTickRightX = x;
        scalePtr->vertValueRightX = x + SPACING + valuePixels;
        x = scalePtr->vertValueRightX + SPACING;
    } else {
        scalePtr->vertTickRightX = x;
        scalePtr->vertValueRightX = x;
    }
    scalePtr->vertTroughX = x;
    x += 2*scalePtr->borderWidth + scalePtr->width;
    if (scalePtr->labelLength == 0) {
        scalePtr->vertLabelX = 0;
    } else {
        scalePtr->vertLabelX = x + fm.ascent/2;
        x = scalePtr->vertLabelX + fm.ascent/2
            + Tk_TextWidth(scalePtr->tkfont, scalePtr->label,
                           scalePtr->labelLength);
    }
    Tk_GeometryRequest(scalePtr->tkwin, x + scalePtr->inset,
                       scalePtr->length + 2*scalePtr->inset);
    Tk_SetInternalBorder(scalePtr->tkwin, scalePtr->inset);
}
Ejemplo n.º 13
0
static int
TextToPostscript(
    Tcl_Interp *interp,		/* Leave Postscript or error message here. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    int prepass)		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    double x, y;
    Tk_FontMetrics fm;
    const char *justify;
    XColor *color;
    Pixmap stipple;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    color = textPtr->color;
    stipple = textPtr->stipple;
    if (state == TK_STATE_HIDDEN || textPtr->color == NULL ||
	    textPtr->text == NULL || *textPtr->text == 0) {
	return TCL_OK;
    } else if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeColor != NULL) {
	    color = textPtr->activeColor;
	}
	if (textPtr->activeStipple != None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (textPtr->disabledColor != NULL) {
	    color = textPtr->disabledColor;
	}
	if (textPtr->disabledStipple != None) {
	    stipple = textPtr->disabledStipple;
	}
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * Generate postscript.
     */

    Tcl_ResetResult(interp);
    if (Tk_CanvasPsFont(interp, canvas, textPtr->tkfont) != TCL_OK) {
	goto error;
    }
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (prepass != 0) {
	goto done;
    }

    Tcl_ResetResult(interp);
    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	goto error;
    }
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (stipple != None) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendPrintfToObj(psObj, "/StippleText {\n    %s} bind def\n",
		Tcl_GetString(Tcl_GetObjResult(interp)));
    }

    x = 0;  y = 0;  justify = NULL;	/* lint. */
    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:	   x = 0; y = 0; break;
    case TK_ANCHOR_N:	   x = 1; y = 0; break;
    case TK_ANCHOR_NE:	   x = 2; y = 0; break;
    case TK_ANCHOR_E:	   x = 2; y = 1; break;
    case TK_ANCHOR_SE:	   x = 2; y = 2; break;
    case TK_ANCHOR_S:	   x = 1; y = 2; break;
    case TK_ANCHOR_SW:	   x = 0; y = 2; break;
    case TK_ANCHOR_W:	   x = 0; y = 1; break;
    case TK_ANCHOR_CENTER: x = 1; y = 1; break;
    }
    switch (textPtr->justify) {
    case TK_JUSTIFY_LEFT:   justify = "0";   break;
    case TK_JUSTIFY_CENTER: justify = "0.5"; break;
    case TK_JUSTIFY_RIGHT:  justify = "1";   break;
    }

    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g %.15g [\n",
	    textPtr->angle, textPtr->x, Tk_CanvasPsY(canvas, textPtr->y));
    Tcl_ResetResult(interp);
    Tk_TextLayoutToPostscript(interp, textPtr->textLayout);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    Tcl_AppendPrintfToObj(psObj,
	    "] %d %g %g %s %s DrawText\n",
	    fm.linespace, x / -2.0, y / 2.0, justify,
	    ((stipple == None) ? "false" : "true"));

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}
Ejemplo n.º 14
0
void
TkpComputeButtonGeometry(
    TkButton *butPtr)		/* Button whose geometry may have changed. */
{
    int width = 0, height = 0, charWidth = 1, haveImage = 0, haveText = 0;
    int txtWidth = 0, txtHeight = 0;
    MacButton *mbPtr = (MacButton*)butPtr;
    Tk_FontMetrics fm;
    DrawParams drawParams;

    /*
     * First figure out the size of the contents of the button.
     */

    TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    /*
     * If the indicator is on, get its size.
     */

    if ( butPtr->indicatorOn ) {
      switch (butPtr->type) {
      case TYPE_RADIO_BUTTON:
	GetThemeMetric(kThemeMetricRadioButtonWidth, &butPtr->indicatorDiameter);
	  break;
      case TYPE_CHECK_BUTTON:
	GetThemeMetric(kThemeMetricCheckBoxWidth, &butPtr->indicatorDiameter);
	  break;
      default:
	break;
      }
      /* Allow 2px extra space next to the indicator. */
      butPtr->indicatorSpace = butPtr->indicatorDiameter + 2;
    } else {
      butPtr->indicatorSpace = 0;
      butPtr->indicatorDiameter = 0;
    }

    if (butPtr->image != NULL) {
	Tk_SizeOfImage(butPtr->image, &width, &height);
	haveImage = 1;
    } else if (butPtr->bitmap != None) {
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight;
	charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

    if (haveImage && haveText) { /* Image and Text */
	switch ((enum compound) butPtr->compound) {
	    case COMPOUND_TOP:
	    case COMPOUND_BOTTOM:
		/*
		 * Image is above or below text.
		 */

		height += txtHeight + butPtr->padY;
		width = (width > txtWidth ? width : txtWidth);
		break;
	    case COMPOUND_LEFT:
	    case COMPOUND_RIGHT:
		/*
		 * Image is left or right of text.
		 */

		width += txtWidth + butPtr->padX;
		height = (height > txtHeight ? height : txtHeight);
		break;
	    case COMPOUND_CENTER:
		/*
		 * Image and text are superimposed.
		 */

		width = (width > txtWidth ? width : txtWidth);
		height = (height > txtHeight ? height : txtHeight);
		break;
	    default:
		break;
	}
	width += butPtr->indicatorSpace;

    } else if (haveImage) { /* Image only */
      width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
      height = butPtr->height > 0 ? butPtr->height : height;

    } else { /* Text only */
        width = txtWidth + butPtr->indicatorSpace;
	height = txtHeight;
	if (butPtr->width > 0) {
	   width = butPtr->width * charWidth;
	}
	if (butPtr->height > 0) {
	  height = butPtr->height * fm.linespace;
	}
    }

    /* Add padding */
    width  += 2 * butPtr->padX;
    height += 2 * butPtr->padY;

    /*
     * Now figure out the size of the border decorations for the button.
     */

    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }

    butPtr->inset = 0;
    butPtr->inset += butPtr->highlightWidth;
    
    if (TkMacOSXComputeButtonDrawParams(butPtr,&drawParams)) {
        HIRect tmpRect;
    	HIRect contBounds;
        int paddingx = 0;
        int paddingy = 0;

    	tmpRect = CGRectMake(0, 0, width, height);

        HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
        /* If the content region has a minimum height, match it. */
        if (height < contBounds.size.height) {
    	  height = contBounds.size.height;
        }

        /* If the content region has a minimum width, match it. */
        if (width < contBounds.size.width) {
    	  width = contBounds.size.width;
        }

        /* Pad to fill difference between content bounds and button bounds. */
    	paddingx = contBounds.origin.x;
    	paddingy = contBounds.origin.y;

        if (height < paddingx - 4) {
            /* can't have buttons much shorter than button side diameter. */
            height = paddingx - 4;
    	}

    } else {
        height += butPtr->borderWidth*2;
        width += butPtr->borderWidth*2;
    }

    width += butPtr->inset*2;
    height += butPtr->inset*2;

    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}
Ejemplo n.º 15
0
void
TkpComputeButtonGeometry(
    TkButton *butPtr)		/* Button whose geometry may have changed. */
{
    int width, height, avgWidth, haveImage = 0, haveText = 0;
    int xInset, yInset, txtWidth, txtHeight;
    Tk_FontMetrics fm;
    DrawParams drawParams;

    /*
     * First figure out the size of the contents of the button.
     */

    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;

    butPtr->indicatorSpace = 0;
    if (butPtr->image != NULL) {
	Tk_SizeOfImage(butPtr->image, &width, &height);
	haveImage = 1;
    } else if (butPtr->bitmap != None) {
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight;
	avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

    /*
     * If the button is compound (ie, it shows both an image and text),
     * the new geometry is a combination of the image and text geometry.
     * We only honor the compound bit if the button has both text and an
     * image, because otherwise it is not really a compound button.
     */

    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
	switch ((enum compound) butPtr->compound) {
	    case COMPOUND_TOP:
	    case COMPOUND_BOTTOM:
		/*
		 * Image is above or below text.
		 */

		height += txtHeight + butPtr->padY;
		width = (width > txtWidth ? width : txtWidth);
		break;
	    case COMPOUND_LEFT:
	    case COMPOUND_RIGHT:
		/*
		 * Image is left or right of text.
		 */

		width += txtWidth + butPtr->padX;
		height = (height > txtHeight ? height : txtHeight);
		break;
	    case COMPOUND_CENTER:
		/*
		 * Image and text are superimposed.
		 */

		width = (width > txtWidth ? width : txtWidth);
		height = (height > txtHeight ? height : txtHeight);
		break;
	    case COMPOUND_NONE:
		break;
	}
	if (butPtr->width > 0) {
	    width = butPtr->width;
	}
	if (butPtr->height > 0) {
	    height = butPtr->height;
	}

	if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
	    butPtr->indicatorSpace = height;
	    if (butPtr->type == TYPE_CHECK_BUTTON) {
		butPtr->indicatorDiameter = (65 * height)/100;
	    } else {
		butPtr->indicatorDiameter = (75 * height)/100;
	    }
	}

	width += 2 * butPtr->padX;
	height += 2 * butPtr->padY;
    } else if (haveImage) {
	if (butPtr->width > 0) {
	    width = butPtr->width;
	}
	if (butPtr->height > 0) {
	    height = butPtr->height;
	}
	if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
	    butPtr->indicatorSpace = height;
	    if (butPtr->type == TYPE_CHECK_BUTTON) {
		butPtr->indicatorDiameter = (65 * height)/100;
	    } else {
		butPtr->indicatorDiameter = (75 * height)/100;
	    }
	}
    } else {
	width = txtWidth;
	height = txtHeight;
	if (butPtr->width > 0) {
	    width = butPtr->width * avgWidth;
	}
	if (butPtr->height > 0) {
	    height = butPtr->height * fm.linespace;
	}
	if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
	    butPtr->indicatorDiameter = fm.linespace;
	    if (butPtr->type == TYPE_CHECK_BUTTON) {
		butPtr->indicatorDiameter =
			(80 * butPtr->indicatorDiameter)/100;
	    }
	    butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
	}
    }

    /*
     * Now figure out the size of the border decorations for the button.
     */

    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }

    /*
     * The width and height calculation for Appearance buttons with images &
     * non-Appearance buttons with images is different. In the latter case,
     * we add the borderwidth to the inset, since we are going to stamp a
     * 3-D border over the image. In the former, we add it to the height,
     * directly, since Appearance will draw the border as part of our control.
     *
     * When issuing the geometry request, add extra space for the indicator,
     * if any, and for the border and padding, plus if this is an image two
     * extra pixels so the display can be offset by 1 pixel in either
     * direction for the raised or lowered effect.
     *
     * The highlight width corresponds to the default ring on the Macintosh.
     * As such, the highlight width is only added if the button is the default
     * button. The actual width of the default ring is one less than the
     * highlight width as there is also one pixel of spacing.
     * Appearance buttons with images do not have a highlight ring, because the
     * Bevel button type does not support one.
     */

    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
	width += 2*butPtr->padX;
	height += 2*butPtr->padY;
    }

    if ((butPtr->type == TYPE_BUTTON)) {
	if ((butPtr->image == None) && (butPtr->bitmap == None)) {
	    butPtr->inset = 0;
	    if (butPtr->defaultState != STATE_DISABLED) {
		butPtr->inset += butPtr->highlightWidth;
	    }
	} else {
	    butPtr->inset = 0;
	    width += (2 * butPtr->borderWidth + 4);
	    height += (2 * butPtr->borderWidth + 4);
	}
    } else if (butPtr->type == TYPE_LABEL) {
	butPtr->inset = butPtr->borderWidth;
    } else if (butPtr->indicatorOn) {
	butPtr->inset = 0;
    } else {
	/*
	 * Under Appearance, the Checkbutton or radiobutton with an image
	 * is represented by a BevelButton with the Sticky defProc...
	 * So we must set its height in the same way as the Button
	 * with an image or bitmap.
	 */

	if (butPtr->image != None || butPtr->bitmap != None) {
	    int border;

	    butPtr->inset = 0;
	    if (butPtr->borderWidth <= 2) {
		border = 6;
	    } else {
		border = 2 * butPtr->borderWidth + 2;
	    }
	    width += border;
	    height += border;
	} else {
	    butPtr->inset = butPtr->borderWidth;
	}
    }

    if (TkMacOSXComputeDrawParams(butPtr, &drawParams)) {
	xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT;
	yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM;
    } else {
	xInset = butPtr->indicatorSpace+butPtr->inset*2;
	yInset = butPtr->inset*2;
    }
    Tk_GeometryRequest(butPtr->tkwin, width + xInset, height + yInset);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}
Ejemplo n.º 16
0
bool callGraphDisplay::softScrollToEndOfPath(const whereNodePosRawPath &thePath) {
  const int overallWindowBorderPix = 0;
   whereNodeGraphicalPath<callGraphRootNode>
     scrollToPath(thePath, consts, rootPtr,
		  nominal_centerx,
		  // ignores scrollbar settings (an absolute coord),
		  overallWindowBorderPix
		  // absolute coord of root topy
		  );
   const int last_item_centerx = scrollToPath.get_endpath_centerx();
   const int last_item_topy    = scrollToPath.get_endpath_topy();
   // note: if the path ends in an lb item, these coords refer to the PARENT
   //       node, which is expanded.
   
   switch (scrollToPath.whatDoesPathEndIn()) {
      case whereNodeGraphicalPath<callGraphRootNode>::ExpandedNode: {
	const int last_item_middley =
	  last_item_topy +
	  scrollToPath.getLastPathNode(rootPtr)->getNodeData().getHeightAsRoot()/2;
	return set_scrollbars(last_item_centerx,
			      Tk_Width(consts.theTkWindow) / 2,
			      last_item_middley,
			      Tk_Height(consts.theTkWindow) / 2,
			      true);
      }
      case whereNodeGraphicalPath<callGraphRootNode>::ListboxItem: {
	// First, let's scroll within the listbox (no redrawing yet)
	where4tree<callGraphRootNode> *parent = 
	  scrollToPath.getParentOfLastPathNode(rootPtr);

         Tk_FontMetrics lbFontMetrics; // filled in by Tk_GetFontMetrics()
         Tk_GetFontMetrics(consts.listboxFontStruct, &lbFontMetrics);
         const unsigned itemHeight = consts.listboxVertPadAboveItem +
                                     lbFontMetrics.ascent +
   	                             consts.listboxVertPadAfterItemBaseline;
   
         int scrollToVertPix = 0; // relative to listbox top
         const unsigned childnum = scrollToPath.getPath().getLastItem();
         for (unsigned childlcv=0; childlcv < childnum; childlcv++)
            if (!parent->getChildIsExpandedFlag(childlcv))
               scrollToVertPix += itemHeight;

         int destItemRelToListboxTop = scrollToVertPix;   
         if (parent->getScrollbar().isValid()) {
            (void)parent->scroll_listbox(consts, scrollToVertPix -
					 parent->getScrollbar().getPixFirst());

            destItemRelToListboxTop -= parent->getScrollbar().getPixFirst();
         }

         if (destItemRelToListboxTop < 0) {
            cout << "note: softScrollToEndOfPath() failed to scroll properly to item w/in listbox" << endl;
         }

         return set_scrollbars(scrollToPath.get_endpath_centerx() -
			   parent->horiz_pix_everything_below_root(consts)/2 +
			       parent->getListboxPixWidth() / 2,
			       // listbox centerx
			       Tk_Width(consts.theTkWindow) / 2,
			       scrollToPath.get_endpath_topy() +
			       parent->getNodeData().getHeightAsRoot() +
			       consts.vertPixParent2ChildTop +
			       destItemRelToListboxTop + itemHeight / 2,
			       // should be the middley of the lb item
			       Tk_Height(consts.theTkWindow) / 2,
			       true);
      }
      default: assert(false);
   }

   assert(false);
   return false; // placate compiler
}