// Because rendering a text field is dependent on input
// parameters the other controls don't have, we render it directly
// rather than trying to overcomplicate draw() further.
void WebTestThemeControlWin::drawTextField(bool drawEdges, bool fillContentArea, SkColor color)
{
    SkPaint paint;

    if (fillContentArea) {
        paint.setColor(color);
        paint.setStyle(SkPaint::kFill_Style);
        m_canvas->drawIRect(m_irect, paint);
    }
    if (drawEdges) {
        paint.setColor(m_edgeColor);
        paint.setStyle(SkPaint::kStroke_Style);
        m_canvas->drawIRect(m_irect, paint);
    }

    markState();
}
void WebTestThemeControlWin::drawProgressBar(const SkIRect& fillRect)
{
    SkPaint paint;

    paint.setColor(m_bgColor);
    paint.setStyle(SkPaint::kFill_Style);
    m_canvas->drawIRect(m_irect, paint);

    // Emulate clipping
    SkIRect tofill;
    tofill.intersect(m_irect, fillRect);
    paint.setColor(m_fgColor);
    paint.setStyle(SkPaint::kFill_Style);
    m_canvas->drawIRect(tofill, paint);

    markState();
}
Example #3
0
void WebTestThemeEngineMock::paint(
    blink::WebCanvas* canvas,
    WebThemeEngine::Part part,
    WebThemeEngine::State state,
    const blink::WebRect& rect,
    const WebThemeEngine::ExtraParams* extraParams)
{
    SkIRect irect = webRectToSkIRect(rect);
    SkPaint paint;

    // Indent amounts for the check in a checkbox or radio button.
    const int checkIndent = 3;

    // Indent amounts for short and long sides of the scrollbar notches.
    const int notchLongOffset = 1;
    const int notchShortOffset = 4;
    const int noOffset = 0;

    // Indent amounts for the short and long sides of a scroll thumb box.
    const int thumbLongIndent = 0;
    const int thumbShortIndent = 2;

    // Indents for the crosshatch on a scroll grip.
    const int gripLongIndent = 3;
    const int gripShortIndent = 5;

    // Indents for the the slider track.
    const int sliderIndent = 2;

    int halfHeight = irect.height() / 2;
    int halfWidth = irect.width() / 2;
    int quarterHeight = irect.height() / 4;
    int quarterWidth = irect.width() / 4;
    int left = irect.fLeft;
    int right = irect.fRight;
    int top = irect.fTop;
    int bottom = irect.fBottom;

    switch (part) {
    case WebThemeEngine::PartScrollbarDownArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + quarterHeight,
            left  + halfWidth,    bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartScrollbarLeftArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            right - quarterWidth, top    + quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            left  + quarterWidth, top    + halfHeight,
            edgeColor);
        break;

    case WebThemeEngine::PartScrollbarRightArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + halfHeight,
            left  + quarterWidth, bottom - quarterHeight,
            edgeColor);
        break;

    case WebThemeEngine::PartScrollbarUpArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, bottom - quarterHeight,
            left  + halfWidth,    top    + quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartScrollbarHorizontalThumb: {
        // Draw a narrower box on top of the outside box.
        nestedBoxes(canvas, irect, thumbLongIndent, thumbShortIndent,
            thumbLongIndent, thumbShortIndent,
            bgColors[state], bgColors[state]);
        // Draw a horizontal crosshatch for the grip.
        int longOffset = halfWidth - gripLongIndent;
        line(canvas,
            left  + gripLongIndent, top    + halfHeight,
            right - gripLongIndent, top    + halfHeight,
            edgeColor);
        line(canvas,
            left  + longOffset,     top    + gripShortIndent,
            left  + longOffset,     bottom - gripShortIndent,
            edgeColor);
        line(canvas,
            right - longOffset,     top    + gripShortIndent,
            right - longOffset,     bottom - gripShortIndent,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarVerticalThumb: {
        // Draw a shorter box on top of the outside box.
        nestedBoxes(canvas, irect, thumbShortIndent, thumbLongIndent,
            thumbShortIndent, thumbLongIndent,
            bgColors[state], bgColors[state]);
        // Draw a vertical crosshatch for the grip.
        int longOffset = halfHeight - gripLongIndent;
        line(canvas,
            left  + halfWidth,       top    + gripLongIndent,
            left  + halfWidth,       bottom - gripLongIndent,
            edgeColor);
        line(canvas,
            left  + gripShortIndent, top    + longOffset,
            right - gripShortIndent, top    + longOffset,
            edgeColor);
        line(canvas,
            left  + gripShortIndent, bottom - longOffset,
            right - gripShortIndent, bottom - longOffset,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarHorizontalTrack: {
        int longOffset = halfHeight - notchLongOffset;
        int shortOffset = irect.width() - notchShortOffset;
        if (extraParams->scrollbarTrack.isBack) {
            // back, notch on left
            nestedBoxes(canvas, irect, noOffset, longOffset, shortOffset,
                longOffset, bgColors[state], edgeColor);
        } else {
            // forward, notch on right
            nestedBoxes(canvas, irect, shortOffset, longOffset, noOffset,
                longOffset, bgColors[state], edgeColor);
        }

        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarVerticalTrack: {
        int longOffset = halfWidth - notchLongOffset;
        int shortOffset = irect.height() - notchShortOffset;
        if (extraParams->scrollbarTrack.isBack) {
            // back, notch at top
            nestedBoxes(canvas, irect, longOffset, noOffset, longOffset,
                shortOffset, bgColors[state], edgeColor);
        } else {
            // forward, notch at bottom
            nestedBoxes(canvas, irect, longOffset, shortOffset, longOffset,
                noOffset, bgColors[state], edgeColor);
        }

        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartCheckbox:
        if (extraParams->button.indeterminate) {
            nestedBoxes(canvas, irect,
                checkIndent, halfHeight,
                checkIndent, halfHeight,
                bgColors[state], edgeColor);
        } else if (extraParams->button.checked) {
            irect = validate(irect, part);
            nestedBoxes(canvas, irect,
                checkIndent, checkIndent,
                checkIndent, checkIndent,
                bgColors[state], edgeColor);
        } else {
            irect = validate(irect, part);
            box(canvas, irect, bgColors[state]);
        }
        break;

    case WebThemeEngine::PartRadio:
        irect = validate(irect, part);
        halfHeight = irect.height() / 2;
        if (extraParams->button.checked) {
            circle(canvas, irect, SkIntToScalar(halfHeight), bgColors[state]);
            circle(canvas, irect, SkIntToScalar(halfHeight - checkIndent), edgeColor);
        } else {
            circle(canvas, irect, SkIntToScalar(halfHeight), bgColors[state]);
        }
        break;

    case WebThemeEngine::PartButton:
        roundRect(canvas, irect, bgColors[state]);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartTextField:
        paint.setColor(extraParams->textField.backgroundColor);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(irect, paint);

        paint.setColor(edgeColor);
        paint.setStyle(SkPaint::kStroke_Style);
        canvas->drawIRect(irect, paint);

        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartMenuList:
        if (extraParams->menuList.fillContentArea) {
            box(canvas, irect, extraParams->menuList.backgroundColor);
        } else {
            SkPaint paint;
            paint.setColor(edgeColor);
            paint.setStyle(SkPaint::kStroke_Style);
            canvas->drawIRect(irect, paint);
        }

        // clip the drop-down arrow to be inside the select box
        if (extraParams->menuList.arrowX - 4 > irect.fLeft)
            irect.fLeft = extraParams->menuList.arrowX - 4;
        if (extraParams->menuList.arrowX + 12 < irect.fRight)
            irect.fRight = extraParams->menuList.arrowX + 12;

        irect.fTop = extraParams->menuList.arrowY - (extraParams->menuList.arrowHeight) / 2;
        irect.fBottom = extraParams->menuList.arrowY + (extraParams->menuList.arrowHeight - 1) / 2;
        halfWidth = irect.width() / 2;
        quarterWidth = irect.width() / 4;

        if (state == WebThemeEngine::StateFocused) // FIXME: draw differenty?
            state = WebThemeEngine::StateNormal;
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            irect.fLeft  + quarterWidth, irect.fTop,
            irect.fRight - quarterWidth, irect.fTop,
            irect.fLeft  + halfWidth,    irect.fBottom,
            edgeColor);

        break;

    case WebThemeEngine::PartSliderTrack: {
        SkIRect lirect =  irect;

        // Draw a narrow rect for the track plus box hatches on the ends.
        if (state == WebThemeEngine::StateFocused) // FIXME: draw differently?
            state = WebThemeEngine::StateNormal;
        if (extraParams->slider.vertical) {
            lirect.inset(halfWidth - sliderIndent, noOffset);
            box(canvas, lirect, bgColors[state]);
            line(canvas, left, top, right, top, edgeColor);
            line(canvas, left, bottom, right, bottom, edgeColor);
        } else {
            lirect.inset(noOffset, halfHeight - sliderIndent);
            box(canvas, lirect, bgColors[state]);
            line(canvas, left, top, left, bottom, edgeColor);
            line(canvas, right, top, right, bottom, edgeColor);
        }
        break;
    }

    case WebThemeEngine::PartSliderThumb:
        if (state == WebThemeEngine::StateFocused) // FIXME: draw differently?
            state = WebThemeEngine::StateNormal;
        oval(canvas, irect, bgColors[state]);
        break;

    case WebThemeEngine::PartInnerSpinButton: {
        // stack half-height up and down arrows on top of each other
        SkIRect lirect;
        int halfHeight = rect.height / 2;
        if (extraParams->innerSpin.readOnly)
            state = blink::WebThemeEngine::StateDisabled;

        lirect.set(rect.x, rect.y, rect.x + rect.width - 1, rect.y + halfHeight - 1);
        box(canvas, lirect, bgColors[state]);
        bottom = lirect.fBottom;
        quarterHeight = lirect.height() / 4;
        triangle(canvas,
            left  + quarterWidth, bottom - quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            left  + halfWidth,    top    + quarterHeight,
            edgeColor);

        lirect.set(rect.x, rect.y + halfHeight, rect.x + rect.width - 1,
            rect.y + 2 * halfHeight - 1);
        top = lirect.fTop;
        bottom = lirect.fBottom;
        quarterHeight = lirect.height() / 4;
        box(canvas, lirect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + quarterHeight,
            left  + halfWidth,    bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }
    case WebThemeEngine::PartProgressBar: {
        paint.setColor(bgColors[state]);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(irect, paint);

        // Emulate clipping
        SkIRect tofill = irect;
        if (extraParams->progressBar.determinate) {
            tofill.set(extraParams->progressBar.valueRectX,
                extraParams->progressBar.valueRectY,
                extraParams->progressBar.valueRectX +
                extraParams->progressBar.valueRectWidth - 1,
                extraParams->progressBar.valueRectY +
                extraParams->progressBar.valueRectHeight);
        }

        tofill.intersect(irect, tofill);
        paint.setColor(edgeColor);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(tofill, paint);

        markState(canvas, irect, state);
        break;
    }
    default:
        // FIXME: Should we do something here to indicate that we got an invalid part?
        // Unfortunately, we can't assert because we don't have access to WTF or base.
        break;
    }
}
Example #4
0
void CTLCheck::processFormula(int root)
{
#undef pt
#define pt(a) //pr(a)

	pt(("processFormula root=%d formula=%s\n",root,f_.s(root) ));

	Model &m = model();
	Token &t = f_.token(root);
	int type = f_.nType(root);
	//	pt((" type=%d, str=%s\n",type,Formula::ts(t) ));
	//pt((" %s\n",Formula::ts(t) ));

	switch (type) {
		case TK_PROPVAR: {
			int var = vars_->var(t.str(),true);
			//int var = Model::varToInt(t.str().charAt(0));
			if (!m.propVarUsed(var)) {
				if (!pvWarn_.get(var)) {
					pvWarn_.set(var);
					Cout << "Warning: Variable '" << t.str() << "' not used in model\n";
				}
			}
			for (int i = 0; i < m.states(); i++) {

				if (m.propVar(m.stateName(i),var)) {
					//pt((" setting flag %d, %d\n",i,root));
					pt(("     +%d\n",i));
//				pr(("  +#%2d: %s\n",i,f_.s(root,true)));
//
					pt((" setting flag %d, %d\n",i,root));
					markState(i,root);
	//				setFlag(i,root);
				}
			}
			}
			break;
		case TK_BOTTOM: 
			break;
		case TK_NEGATION:
			{
				int child = childFormula(root,0);
				for (int i = 0; i < m.states(); i++) {
					if (!getFlag(i,child)) {
						pt((" flag %d, child %d not set\n",i,child));
						pt(("     +%d\n",i));
//						pr(("  +#%2d: %s\n",i,f_.s(root,true)));
					markState(i,root);
	//					setFlag(i,root);
					}
				}
			}
			break;
		case TK_AND:
			{
				int ca = childFormula(root,0),
					cb = childFormula(root,1);

				for (int i = 0; i < m.states(); i++) {
					if (getFlag(i,ca) && getFlag(i,cb)) {
						pt(("     +%d\n",i));
//						pr(("  +#%2d: %s\n",i,f_.s(root,true)));
							markState(i,root);
//				setFlag(i,root);
					}
				}
			}
			break;
		case TK_EX:
			{
				int c = childFormula(root,0);

				for (int i = 0; i < m.states(); i++) {
					int in = m.stateName(i);
					for (int j = m.degree(in)-1; j >= 0; j--) {
						int xs = m.next(in,j);
						if (getFlag(m.stateId(xs),c)) {
							pt(("     +%d\n",i));
							markState(i,root);
//							setFlag(i,root);
							//pr(("  +#%2d: %s\n",i,f_.s(root,true)));
							break;
						}
					}
				}
			}
			break;
		case TK_AF:
			{
				int c = childFormula(root,0);

				bool changed = true;
				while (changed) {
					changed = false;
					for (int i = 0; i < m.states(); i++) {
						int iName = m.stateName(i);
						if (getFlag(i,root)) continue;
						if (getFlag(i,c)) {
							pt(("     +%d\n",i));
							changed = true;
							markState(i,root);
//pr(("  +#%2d: %s\n",i,f_.s(root,true)));
//							setFlag(i,root);
							continue;
						}

						bool allNb = true;
						for (int j = m.degree(iName)-1; j >= 0; j--) {
							int xs = m.next(iName,j);
							if (!getFlag(m.stateId(xs),root)) {
								allNb = false; break;
							}
						}
						if (allNb) {
							pt(("     +%d\n",i));
							changed = true;
						markState(i,root);
						//pr(("  +#%2d: %s\n",i,f_.s(root,true)));
						//	setFlag(i,root);
						}
					}
				}
			}
			break;
		case TK_EU:
			{
#undef pt
#define pt(a) //pr(a)
	pt(("processFormula root=%d [%s]\n",root,f_.s(root,true) ));

				int ca = childFormula(root,0);
				int cb = childFormula(root,1);

				bool changed = true;
				while (changed) {
					changed = false;
					for (int i = 0; i < m.states(); i++) {
						int in = m.stateName(i);

						if (getFlag(i,root)) continue;
						if (getFlag(i,cb)) {
							pt(("     +%d (second part true)\n",i));
							changed = true;
							markState(i,root);
//							setFlag(i,root);
	//						pr(("  +#%2d: %s\n",i,f_.s(root,true)));
							continue;
						}

						// first part must be true in this state
						if (!getFlag(i,ca)) continue;

						// check if second part is true in any successor
						for (int j = m.degree(in)-1; j >= 0; j--) {
							int xs = m.next(in,j);
							if (getFlag(m.stateId(xs, true),root)) {
								pt(("     +%d (neighbor %d has first true)\n",i,xs));
								changed = true;
								markState(i,root);
								break;
							}
						}
					}
				}
			}
			break;
		}
}
void WebTestThemeControlWin::draw()
{
    int halfWidth = m_width / 2;
    int halfHeight = m_height / 2;
    int quarterWidth = m_width / 4;
    int quarterHeight = m_height / 4;

    // Indent amounts for the check in a checkbox or radio button.
    const int checkIndent = 3;

    // Indent amounts for short and long sides of the scrollbar notches.
    const int notchLongOffset = 1;
    const int notchShortOffset = 4;
    const int noOffset = 0;

    // Indent amounts for the short and long sides of a scroll thumb box.
    const int thumbLongIndent = 0;
    const int thumbShortIndent = 2;

    // Indents for the crosshatch on a scroll grip.
    const int gripLongIndent = 3;
    const int gripShortIndent = 5;

    // Indents for the the slider track.
    const int sliderIndent = 2;

    switch (m_type) {
    case UnknownType:
        BLINK_ASSERT_NOT_REACHED();
        break;

    case TextFieldType:
        // We render this by hand outside of this function.
        BLINK_ASSERT_NOT_REACHED();
        break;

    case PushButtonType:
        // push buttons render as a rounded rectangle
        roundRect(m_bgColor);
        break;

    case UncheckedBoxType:
        // Unchecked boxes are simply plain boxes.
        box(m_irect, m_bgColor);
        break;

    case CheckedBoxType:
        nestedBoxes(checkIndent, checkIndent, checkIndent, checkIndent, m_bgColor, m_fgColor);
        break;

    case IndeterminateCheckboxType:
        // Indeterminate checkbox is a box containing '-'.
        nestedBoxes(checkIndent, halfHeight, checkIndent, halfHeight, m_bgColor, m_fgColor);
        break;

    case UncheckedRadioType:
        circle(SkIntToScalar(halfHeight), m_bgColor);
        break;

    case CheckedRadioType:
        circle(SkIntToScalar(halfHeight), m_bgColor);
        circle(SkIntToScalar(halfHeight - checkIndent), m_fgColor);
        break;

    case HorizontalScrollTrackBackType: {
        // Draw a box with a notch at the left.
        int longOffset = halfHeight - notchLongOffset;
        int shortOffset = m_width - notchShortOffset;
        nestedBoxes(noOffset, longOffset, shortOffset, longOffset, m_bgColor, m_edgeColor);
        break;
    }

    case HorizontalScrollTrackForwardType: {
        // Draw a box with a notch at the right.
        int longOffset  = halfHeight - notchLongOffset;
        int shortOffset = m_width - notchShortOffset;
        nestedBoxes(shortOffset, longOffset, noOffset, longOffset, m_bgColor, m_fgColor);
        break;
    }

    case VerticalScrollTrackBackType: {
        // Draw a box with a notch at the top.
        int longOffset  = halfWidth - notchLongOffset;
        int shortOffset = m_height - notchShortOffset;
        nestedBoxes(longOffset, noOffset, longOffset, shortOffset, m_bgColor, m_fgColor);
        break;
    }

    case VerticalScrollTrackForwardType: {
        // Draw a box with a notch at the bottom.
        int longOffset  = halfWidth - notchLongOffset;
        int shortOffset = m_height - notchShortOffset;
        nestedBoxes(longOffset, shortOffset, longOffset, noOffset, m_bgColor, m_fgColor);
        break;
    }

    case HorizontalScrollThumbType:
        // Draw a narrower box on top of the outside box.
        nestedBoxes(thumbLongIndent, thumbShortIndent, thumbLongIndent, thumbShortIndent, m_bgColor, m_bgColor);
        break;

    case VerticalScrollThumbType:
        // Draw a shorter box on top of the outside box.
        nestedBoxes(thumbShortIndent, thumbLongIndent, thumbShortIndent, thumbLongIndent, m_bgColor, m_bgColor);
        break;

    case HorizontalSliderThumbType:
    case VerticalSliderThumbType:
        // Slider thumbs are ovals.
        oval(m_bgColor);
        break;

    case HorizontalScrollGripType: {
        // Draw a horizontal crosshatch for the grip.
        int longOffset = halfWidth - gripLongIndent;
        line(m_left + gripLongIndent, m_top + halfHeight, m_right - gripLongIndent, m_top + halfHeight, m_fgColor);
        line(m_left + longOffset, m_top + gripShortIndent, m_left + longOffset, m_bottom - gripShortIndent, m_fgColor);
        line(m_right - longOffset, m_top + gripShortIndent, m_right - longOffset, m_bottom - gripShortIndent, m_fgColor);
        break;
    }

    case VerticalScrollGripType: {
        // Draw a vertical crosshatch for the grip.
        int longOffset = halfHeight - gripLongIndent;
        line(m_left + halfWidth, m_top + gripLongIndent, m_left + halfWidth, m_bottom - gripLongIndent, m_fgColor);
        line(m_left + gripShortIndent, m_top + longOffset, m_right - gripShortIndent, m_top + longOffset, m_fgColor);
        line(m_left + gripShortIndent, m_bottom - longOffset, m_right - gripShortIndent, m_bottom - longOffset, m_fgColor);
        break;
    }

    case LeftArrowType:
        // Draw a left arrow inside a box.
        box(m_irect, m_bgColor);
        triangle(m_right - quarterWidth, m_top + quarterHeight, m_right - quarterWidth, m_bottom - quarterHeight, m_left + quarterWidth, m_top + halfHeight, m_fgColor);
        break;

    case RightArrowType:
        // Draw a left arrow inside a box.
        box(m_irect, m_bgColor);
        triangle(m_left + quarterWidth, m_top + quarterHeight, m_right - quarterWidth, m_top + halfHeight, m_left + quarterWidth, m_bottom - quarterHeight, m_fgColor);
        break;

    case UpArrowType:
        // Draw an up arrow inside a box.
        box(m_irect, m_bgColor);
        triangle(m_left + quarterWidth, m_bottom - quarterHeight, m_left + halfWidth, m_top + quarterHeight, m_right - quarterWidth, m_bottom - quarterHeight, m_fgColor);
        break;

    case DownArrowType:
        // Draw a down arrow inside a box.
        box(m_irect, m_bgColor);
        triangle(m_left + quarterWidth, m_top + quarterHeight, m_right - quarterWidth, m_top + quarterHeight, m_left + halfWidth, m_bottom - quarterHeight, m_fgColor);
        break;

    case HorizontalSliderTrackType: {
        // Draw a narrow rect for the track plus box hatches on the ends.
        SkIRect lirect;
        lirect = m_irect;
        lirect.inset(noOffset, halfHeight - sliderIndent);
        box(lirect, m_bgColor);
        line(m_left,  m_top, m_left,  m_bottom, m_edgeColor);
        line(m_right, m_top, m_right, m_bottom, m_edgeColor);
        break;
    }

    case VerticalSliderTrackType: {
        // Draw a narrow rect for the track plus box hatches on the ends.
        SkIRect lirect;
        lirect = m_irect;
        lirect.inset(halfWidth - sliderIndent, noOffset);
        box(lirect, m_bgColor);
        line(m_left, m_top, m_right, m_top, m_edgeColor);
        line(m_left, m_bottom, m_right, m_bottom, m_edgeColor);
        break;
    }

    case DropDownButtonType:
        // Draw a box with a big down arrow on top.
        box(m_irect, m_bgColor);
        triangle(m_left + quarterWidth, m_top, m_right - quarterWidth, m_top, m_left + halfWidth, m_bottom, m_fgColor);
        break;

    default:
        BLINK_ASSERT_NOT_REACHED();
        break;
    }

    markState();
}