// draw multiple instances of a set of elements
432125
func DrawElementsInstanced(mode uint32, count int32, xtype uint32, indices unsafe.Pointer, instancecount int32) {
	C.glowDrawElementsInstanced(gpDrawElementsInstanced, (C.GLenum)(mode), (C.GLsizei)(count), (C.GLenum)(xtype), indices, (C.GLsizei)(instancecount))
}
1302659
func (p *Padder) Draw(painter *Painter) {
	painter.Translate(p.padding.X, p.padding.Y)
	defer painter.Restore()

	p.widget.Draw(painter)
}
761735
func (c *InputField) Draw() {
	maxWidth := c.width
	maxHeight := c.height
	x, y := c.x, c.y
	startX := c.x
	startY := c.y
	useFg, useBg := c.fg, c.bg
	if c.active {
		useFg, useBg = c.activeFg, c.activeBg
	}
	if c.bordered {
		DrawBorder(c.x, c.y, c.x+c.width, c.y+c.height, useFg, useBg)
		maxWidth--
		maxHeight--
		x++
		y++
		startX++
		startY++
	}

	var strPt1, strPt2 string
	var cursorRune rune
	if len(c.value) > 0 {
		if c.cursor+len(c.value) == 0 {
			strPt1 = ""
			strPt2 = c.value[1:]
			cursorRune = rune(c.value[0])
		} else if c.cursor == 0 {
			strPt1 = c.value
			strPt2 = ""
			cursorRune = ' '
		} else {
			strPt1 = c.value[:(len(c.value) + c.cursor)]
			strPt2 = c.value[(len(c.value)+c.cursor)+1:]
			cursorRune = rune(c.value[len(c.value)+c.cursor])
		}
	} else {
		strPt1, strPt2, cursorRune = "", "", ' '
	}
	if c.title != "" {
		if c.active {
			DrawStringAtPoint(c.title, x, y, c.activeFg, c.activeBg)
		} else {
			DrawStringAtPoint(c.title, x, y, useFg, useBg)
		}
	}
	if c.wrap {
		// Split the text into maxWidth chunks
		for len(strPt1) > maxWidth {
			breakAt := maxWidth
			DrawStringAtPoint(strPt1[:breakAt], x, y, useFg, useBg)
			x = startX
			y++
			strPt1 = strPt1[breakAt:]
		}
		x, y = DrawStringAtPoint(strPt1, x, y, useFg, useBg)
		if x >= maxWidth {
			y++
			x = startX
		}
		termbox.SetCell(x, y, cursorRune, c.cursorFg, c.cursorBg)
		x++
		if len(strPt2) > 0 {
			lenLeft := maxWidth - len(strPt1) - 1
			if lenLeft > 0 && len(strPt2) > lenLeft {
				DrawStringAtPoint(strPt2[:lenLeft], x+1, y, useFg, useBg)
				strPt2 = strPt2[lenLeft:]
			}
			for len(strPt2) > maxWidth {
				breakAt := maxWidth
				DrawStringAtPoint(strPt2[:breakAt], x, y, useFg, useBg)
				x = startX
				y++
				strPt2 = strPt2[breakAt:]
			}
			x, y = DrawStringAtPoint(strPt2, x, y, useFg, useBg)
		}
	} else {
		for len(strPt1)+len(strPt2)+1 > maxWidth {
			if len(strPt1) >= len(strPt2) {
				if len(strPt1) == 0 {
					break
				}
				strPt1 = strPt1[1:]
			} else {
				strPt2 = strPt2[:len(strPt2)-1]
			}
		}
		x, y = DrawStringAtPoint(strPt1, c.x+len(c.title), c.y, useFg, useBg)
		if c.active {
			termbox.SetCell(x, y, cursorRune, c.cursorFg, c.cursorBg)
		} else {
			termbox.SetCell(x, y, cursorRune, useFg, useBg)
		}
		DrawStringAtPoint(strPt2, x+1, y, useFg, useBg)
	}
}
850762
func (p *Panel) Draw() {
	p.BoxLayout.SetOrientation(Vertical)
	p.BoxLayout.Draw()
}
295775
func (d Sierra24A) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
	pd, ok := dst.(*image.Paletted)
	if !ok {
		// dither211 currently requires a palette
		draw.Draw(dst, r, src, sp, draw.Src)
		return
	}
	// intersect r with both dst and src bounds, fix up sp.
	ir := r.Intersect(pd.Bounds()).
		Intersect(src.Bounds().Add(r.Min.Sub(sp)))
	if ir.Empty() {
		return // no work to do.
	}
	sp = ir.Min.Sub(r.Min)
	// get subimage of src
	sr := ir.Add(sp)
	if !sr.Eq(src.Bounds()) {
		s, ok := src.(interface {
			SubImage(image.Rectangle) image.Image
		})
		if !ok {
			// dither211 currently works on whole images
			draw.Draw(dst, r, src, sp, draw.Src)
			return
		}
		src = s.SubImage(sr)
	}
	// dither211 currently returns a new image, or nil if dithering not
	// possible.
	if s := dither211(src, pd.Palette); s != nil {
		src = s
	}
	// this avoids any problem of src dst overlap but it would usually
	// work to render directly into dst.  todo.
	draw.Draw(dst, r, src, image.Point{}, draw.Src)
}
806688
func (g *Gui) drawFrameCorners(v *View, fgColor, bgColor Attribute) error {
	runeTL, runeTR, runeBL, runeBR := '┌', '┐', '└', '┘'
	if g.ASCII {
		runeTL, runeTR, runeBL, runeBR = '+', '+', '+', '+'
	}

	corners := []struct {
		x, y int
		ch   rune
	}{{v.x0, v.y0, runeTL}, {v.x1, v.y0, runeTR}, {v.x0, v.y1, runeBL}, {v.x1, v.y1, runeBR}}

	for _, c := range corners {
		if c.x >= 0 && c.y >= 0 && c.x < g.maxX && c.y < g.maxY {
			if err := g.SetRune(c.x, c.y, c.ch, fgColor, bgColor); err != nil {
				return err
			}
		}
	}
	return nil
}
1091948
func (v *View) draw() error {
	maxX, maxY := v.Size()

	if v.Wrap {
		if maxX == 0 {
			return errors.New("X size of the view cannot be 0")
		}
		v.ox = 0
	}
	if v.tainted {
		v.viewLines = nil
		for i, line := range v.lines {
			if v.Wrap {
				if len(line) < maxX {
					vline := viewLine{linesX: 0, linesY: i, line: line}
					v.viewLines = append(v.viewLines, vline)
					continue
				} else {
					for n := 0; n <= len(line); n += maxX {
						if len(line[n:]) <= maxX {
							vline := viewLine{linesX: n, linesY: i, line: line[n:]}
							v.viewLines = append(v.viewLines, vline)
						} else {
							vline := viewLine{linesX: n, linesY: i, line: line[n : n+maxX]}
							v.viewLines = append(v.viewLines, vline)
						}
					}
				}
			} else {
				vline := viewLine{linesX: 0, linesY: i, line: line}
				v.viewLines = append(v.viewLines, vline)
			}
		}
		v.tainted = false
	}

	if v.Autoscroll && len(v.viewLines) > maxY {
		v.oy = len(v.viewLines) - maxY
	}
	y := 0
	for i, vline := range v.viewLines {
		if i < v.oy {
			continue
		}
		if y >= maxY {
			break
		}
		x := 0
		for j, c := range vline.line {
			if j < v.ox {
				continue
			}
			if x >= maxX {
				break
			}

			fgColor := c.fgColor
			if fgColor == ColorDefault {
				fgColor = v.FgColor
			}
			bgColor := c.bgColor
			if bgColor == ColorDefault {
				bgColor = v.BgColor
			}

			if err := v.setRune(x, y, c.chr, fgColor, bgColor); err != nil {
				return err
			}
			x++
		}
		y++
	}
	return nil
}
9255
func (t *Table) Draw(screen tcell.Screen) {
	t.Box.Draw(screen)

	// What's our available screen space?
	x, y, width, height := t.GetInnerRect()
	if t.borders {
		t.visibleRows = height / 2
	} else {
		t.visibleRows = height
	}

	// Return the cell at the specified position (nil if it doesn't exist).
	getCell := func(row, column int) *TableCell {
		if row < 0 || column < 0 || row >= len(t.cells) || column >= len(t.cells[row]) {
			return nil
		}
		return t.cells[row][column]
	}

	// If this cell is not selectable, find the next one.
	if t.rowsSelectable || t.columnsSelectable {
		if t.selectedColumn < 0 {
			t.selectedColumn = 0
		}
		if t.selectedRow < 0 {
			t.selectedRow = 0
		}
		for t.selectedRow < len(t.cells) {
			cell := getCell(t.selectedRow, t.selectedColumn)
			if cell == nil || !cell.NotSelectable {
				break
			}
			t.selectedColumn++
			if t.selectedColumn > t.lastColumn {
				t.selectedColumn = 0
				t.selectedRow++
			}
		}
	}

	// Clamp row offsets.
	if t.rowsSelectable {
		if t.selectedRow >= t.fixedRows && t.selectedRow < t.fixedRows+t.rowOffset {
			t.rowOffset = t.selectedRow - t.fixedRows
			t.trackEnd = false
		}
		if t.borders {
			if 2*(t.selectedRow+1-t.rowOffset) >= height {
				t.rowOffset = t.selectedRow + 1 - height/2
				t.trackEnd = false
			}
		} else {
			if t.selectedRow+1-t.rowOffset >= height {
				t.rowOffset = t.selectedRow + 1 - height
				t.trackEnd = false
			}
		}
	}
	if t.borders {
		if 2*(len(t.cells)-t.rowOffset) < height {
			t.trackEnd = true
		}
	} else {
		if len(t.cells)-t.rowOffset < height {
			t.trackEnd = true
		}
	}
	if t.trackEnd {
		if t.borders {
			t.rowOffset = len(t.cells) - height/2
		} else {
			t.rowOffset = len(t.cells) - height
		}
	}
	if t.rowOffset < 0 {
		t.rowOffset = 0
	}

	// Clamp column offset. (Only left side here. The right side is more
	// difficult and we'll do it below.)
	if t.columnsSelectable && t.selectedColumn >= t.fixedColumns && t.selectedColumn < t.fixedColumns+t.columnOffset {
		t.columnOffset = t.selectedColumn - t.fixedColumns
	}
	if t.columnOffset < 0 {
		t.columnOffset = 0
	}
	if t.selectedColumn < 0 {
		t.selectedColumn = 0
	}

	// Determine the indices and widths of the columns and rows which fit on the
	// screen.
	var (
		columns, rows, widths   []int
		tableHeight, tableWidth int
	)
	rowStep := 1
	if t.borders {
		rowStep = 2    // With borders, every table row takes two screen rows.
		tableWidth = 1 // We start at the second character because of the left table border.
	}
	indexRow := func(row int) bool { // Determine if this row is visible, store its index.
		if tableHeight >= height {
			return false
		}
		rows = append(rows, row)
		tableHeight += rowStep
		return true
	}
	for row := 0; row < t.fixedRows && row < len(t.cells); row++ { // Do the fixed rows first.
		if !indexRow(row) {
			break
		}
	}
	for row := t.fixedRows + t.rowOffset; row < len(t.cells); row++ { // Then the remaining rows.
		if !indexRow(row) {
			break
		}
	}
	var (
		skipped, lastTableWidth, expansionTotal int
		expansions                              []int
	)
ColumnLoop:
	for column := 0; ; column++ {
		// If we've moved beyond the right border, we stop or skip a column.
		for tableWidth-1 >= width { // -1 because we include one extra column if the separator falls on the right end of the box.
			// We've moved beyond the available space.
			if column < t.fixedColumns {
				break ColumnLoop // We're in the fixed area. We're done.
			}
			if !t.columnsSelectable && skipped >= t.columnOffset {
				break ColumnLoop // There is no selection and we've already reached the offset.
			}
			if t.columnsSelectable && t.selectedColumn-skipped == t.fixedColumns {
				break ColumnLoop // The selected column reached the leftmost point before disappearing.
			}
			if t.columnsSelectable && skipped >= t.columnOffset &&
				(t.selectedColumn < column && lastTableWidth < width-1 && tableWidth < width-1 || t.selectedColumn < column-1) {
				break ColumnLoop // We've skipped as many as requested and the selection is visible.
			}
			if len(columns) <= t.fixedColumns {
				break // Nothing to skip.
			}

			// We need to skip a column.
			skipped++
			lastTableWidth -= widths[t.fixedColumns] + 1
			tableWidth -= widths[t.fixedColumns] + 1
			columns = append(columns[:t.fixedColumns], columns[t.fixedColumns+1:]...)
			widths = append(widths[:t.fixedColumns], widths[t.fixedColumns+1:]...)
			expansions = append(expansions[:t.fixedColumns], expansions[t.fixedColumns+1:]...)
		}

		// What's this column's width (without expansion)?
		maxWidth := -1
		expansion := 0
		for _, row := range rows {
			if cell := getCell(row, column); cell != nil {
				_, _, _, _, _, _, cellWidth := decomposeString(cell.Text, true, false)
				if cell.MaxWidth > 0 && cell.MaxWidth < cellWidth {
					cellWidth = cell.MaxWidth
				}
				if cellWidth > maxWidth {
					maxWidth = cellWidth
				}
				if cell.Expansion > expansion {
					expansion = cell.Expansion
				}
			}
		}
		if maxWidth < 0 {
			break // No more cells found in this column.
		}

		// Store new column info at the end.
		columns = append(columns, column)
		widths = append(widths, maxWidth)
		lastTableWidth = tableWidth
		tableWidth += maxWidth + 1
		expansions = append(expansions, expansion)
		expansionTotal += expansion
	}
	t.columnOffset = skipped

	// If we have space left, distribute it.
	if tableWidth < width {
		toDistribute := width - tableWidth
		for index, expansion := range expansions {
			if expansionTotal <= 0 {
				break
			}
			expWidth := toDistribute * expansion / expansionTotal
			widths[index] += expWidth
			toDistribute -= expWidth
			expansionTotal -= expansion
		}
	}

	// Helper function which draws border runes.
	borderStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.bordersColor)
	drawBorder := func(colX, rowY int, ch rune) {
		screen.SetContent(x+colX, y+rowY, ch, nil, borderStyle)
	}

	// Draw the cells (and borders).
	var columnX int
	if !t.borders {
		columnX--
	}
	for columnIndex, column := range columns {
		columnWidth := widths[columnIndex]
		for rowY, row := range rows {
			if t.borders {
				// Draw borders.
				rowY *= 2
				for pos := 0; pos < columnWidth && columnX+1+pos < width; pos++ {
					drawBorder(columnX+pos+1, rowY, Borders.Horizontal)
				}
				ch := Borders.Cross
				if columnIndex == 0 {
					if rowY == 0 {
						ch = Borders.TopLeft
					} else {
						ch = Borders.LeftT
					}
				} else if rowY == 0 {
					ch = Borders.TopT
				}
				drawBorder(columnX, rowY, ch)
				rowY++
				if rowY >= height {
					break // No space for the text anymore.
				}
				drawBorder(columnX, rowY, Borders.Vertical)
			} else if columnIndex > 0 {
				// Draw separator.
				drawBorder(columnX, rowY, t.separator)
			}

			// Get the cell.
			cell := getCell(row, column)
			if cell == nil {
				continue
			}

			// Draw text.
			finalWidth := columnWidth
			if columnX+1+columnWidth >= width {
				finalWidth = width - columnX - 1
			}
			cell.x, cell.y, cell.width = x+columnX+1, y+rowY, finalWidth
			_, printed := printWithStyle(screen, cell.Text, x+columnX+1, y+rowY, finalWidth, cell.Align, tcell.StyleDefault.Foreground(cell.Color)|tcell.Style(cell.Attributes))
			if TaggedStringWidth(cell.Text)-printed > 0 && printed > 0 {
				_, _, style, _ := screen.GetContent(x+columnX+1+finalWidth-1, y+rowY)
				printWithStyle(screen, string(SemigraphicsHorizontalEllipsis), x+columnX+1+finalWidth-1, y+rowY, 1, AlignLeft, style)
			}
		}

		// Draw bottom border.
		if rowY := 2 * len(rows); t.borders && rowY < height {
			for pos := 0; pos < columnWidth && columnX+1+pos < width; pos++ {
				drawBorder(columnX+pos+1, rowY, Borders.Horizontal)
			}
			ch := Borders.BottomT
			if columnIndex == 0 {
				ch = Borders.BottomLeft
			}
			drawBorder(columnX, rowY, ch)
		}

		columnX += columnWidth + 1
	}

	// Draw right border.
	if t.borders && len(t.cells) > 0 && columnX < width {
		for rowY := range rows {
			rowY *= 2
			if rowY+1 < height {
				drawBorder(columnX, rowY+1, Borders.Vertical)
			}
			ch := Borders.RightT
			if rowY == 0 {
				ch = Borders.TopRight
			}
			drawBorder(columnX, rowY, ch)
		}
		if rowY := 2 * len(rows); rowY < height {
			drawBorder(columnX, rowY, Borders.BottomRight)
		}
	}

	// Helper function which colors the background of a box.
	// backgroundColor == tcell.ColorDefault => Don't color the background.
	// textColor == tcell.ColorDefault => Don't change the text color.
	// attr == 0 => Don't change attributes.
	// invert == true => Ignore attr, set text to backgroundColor or t.backgroundColor;
	//                   set background to textColor.
	colorBackground := func(fromX, fromY, w, h int, backgroundColor, textColor tcell.Color, attr tcell.AttrMask, invert bool) {
		for by := 0; by < h && fromY+by < y+height; by++ {
			for bx := 0; bx < w && fromX+bx < x+width; bx++ {
				m, c, style, _ := screen.GetContent(fromX+bx, fromY+by)
				fg, bg, a := style.Decompose()
				if invert {
					if fg == textColor || fg == t.bordersColor {
						fg = backgroundColor
					}
					if fg == tcell.ColorDefault {
						fg = t.backgroundColor
					}
					style = style.Background(textColor).Foreground(fg)
				} else {
					if backgroundColor != tcell.ColorDefault {
						bg = backgroundColor
					}
					if textColor != tcell.ColorDefault {
						fg = textColor
					}
					if attr != 0 {
						a = attr
					}
					style = style.Background(bg).Foreground(fg) | tcell.Style(a)
				}
				screen.SetContent(fromX+bx, fromY+by, m, c, style)
			}
		}
	}

	// Color the cell backgrounds. To avoid undesirable artefacts, we combine
	// the drawing of a cell by background color, selected cells last.
	type cellInfo struct {
		x, y, w, h int
		text       tcell.Color
		selected   bool
	}
	cellsByBackgroundColor := make(map[tcell.Color][]*cellInfo)
	var backgroundColors []tcell.Color
	for rowY, row := range rows {
		columnX := 0
		rowSelected := t.rowsSelectable && !t.columnsSelectable && row == t.selectedRow
		for columnIndex, column := range columns {
			columnWidth := widths[columnIndex]
			cell := getCell(row, column)
			if cell == nil {
				continue
			}
			bx, by, bw, bh := x+columnX, y+rowY, columnWidth+1, 1
			if t.borders {
				by = y + rowY*2
				bw++
				bh = 3
			}
			columnSelected := t.columnsSelectable && !t.rowsSelectable && column == t.selectedColumn
			cellSelected := !cell.NotSelectable && (columnSelected || rowSelected || t.rowsSelectable && t.columnsSelectable && column == t.selectedColumn && row == t.selectedRow)
			entries, ok := cellsByBackgroundColor[cell.BackgroundColor]
			cellsByBackgroundColor[cell.BackgroundColor] = append(entries, &cellInfo{
				x:        bx,
				y:        by,
				w:        bw,
				h:        bh,
				text:     cell.Color,
				selected: cellSelected,
			})
			if !ok {
				backgroundColors = append(backgroundColors, cell.BackgroundColor)
			}
			columnX += columnWidth + 1
		}
	}
	sort.Slice(backgroundColors, func(i int, j int) bool {
		// Draw brightest colors last (i.e. on top).
		r, g, b := backgroundColors[i].RGB()
		c := colorful.Color{R: float64(r) / 255, G: float64(g) / 255, B: float64(b) / 255}
		_, _, li := c.Hcl()
		r, g, b = backgroundColors[j].RGB()
		c = colorful.Color{R: float64(r) / 255, G: float64(g) / 255, B: float64(b) / 255}
		_, _, lj := c.Hcl()
		return li < lj
	})
	selFg, selBg, selAttr := t.selectedStyle.Decompose()
	for _, bgColor := range backgroundColors {
		entries := cellsByBackgroundColor[bgColor]
		for _, cell := range entries {
			if cell.selected {
				if t.selectedStyle != 0 {
					defer colorBackground(cell.x, cell.y, cell.w, cell.h, selBg, selFg, selAttr, false)
				} else {
					defer colorBackground(cell.x, cell.y, cell.w, cell.h, bgColor, cell.text, 0, true)
				}
			} else {
				colorBackground(cell.x, cell.y, cell.w, cell.h, bgColor, tcell.ColorDefault, 0, false)
			}
		}
	}
}
1353792
func (c *Menu) Draw() {
	useFg, useBg := c.fg, c.bg
	if c.active {
		useFg, useBg = c.activeFg, c.activeBg
	}
	// First blank out the area we'll be putting the menu
	FillWithChar(' ', c.x, c.y, c.x+c.width, c.y+c.height, useFg, useBg)
	// Now draw the border
	optionStartX := c.x
	optionStartY := c.y
	optionWidth := c.width
	_ = optionWidth
	optionHeight := c.height
	if optionHeight == -1 {
		optionHeight = len(c.options)
	}
	if c.bordered {
		pct := float64(c.GetSelectedIndex()) / float64(len(c.options))
		if c.title == "" {
			if len(c.options) > c.height-2 {
				DrawBorderWithPct(c.x, c.y, c.x+c.width, c.y+c.height, pct, useFg, useBg)
			} else {
				DrawBorder(c.x, c.y, c.x+c.width, c.y+c.height, useFg, useBg)
			}
		} else {
			if len(c.options) > c.height-2 {
				DrawBorderWithTitleAndPct(c.x, c.y, c.x+c.width, c.y+c.height, " "+c.title+" ", pct, useFg, useBg)
			} else {
				DrawBorderWithTitle(c.x, c.y, c.x+c.width, c.y+c.height, " "+c.title+" ", useFg, useBg)
			}
		}
		optionStartX = c.x + 1
		optionStartY = c.y + 1
		optionWidth = c.width - 1
		optionHeight -= 2
	}

	if len(c.options) > 0 {
		firstDispIdx := 0
		lastDispIdx := len(c.options) - 1
		if len(c.options) > c.height-2 {
			lastDispIdx = c.height - 2
		}
		if c.GetSelectedIndex() > c.height-2 {
			firstDispIdx = c.GetSelectedIndex() - (c.height - 2)
			lastDispIdx = c.GetSelectedIndex()
		}
		for idx := firstDispIdx; idx < lastDispIdx; idx++ {
			currOpt := &c.options[idx]
			outTxt := currOpt.GetText()
			if currOpt.IsDisabled() {
				DrawStringAtPoint(outTxt, optionStartX, optionStartY, c.disabledFg, c.disabledBg)
			} else if c.GetSelectedOption() == currOpt {
				DrawStringAtPoint(outTxt, optionStartX, optionStartY, c.selectedFg, c.selectedBg)
			} else {
				DrawStringAtPoint(outTxt, optionStartX, optionStartY, useFg, useBg)
			}
			optionStartY++
		}
	}
	/*
			// Print the options
			bldHeight := (optionHeight / 2)
			startIdx := c.GetSelectedIndex()
			endIdx := c.GetSelectedIndex()
			for bldHeight > 0 && startIdx >= 1 {
				startIdx--
				bldHeight--
			}
			bldHeight += (optionHeight / 2)
			for bldHeight > 0 && endIdx < len(c.options) {
				endIdx++
				bldHeight--
			}

			for idx := startIdx; idx < endIdx; idx++ {
				if c.GetSelectedIndex()-idx >= optionHeight-1 {
					// Skip this one
					continue
				}
				currOpt := &c.options[idx]
				outTxt := currOpt.GetText()
				if len(outTxt) >= c.width {
					outTxt = outTxt[:c.width]
				}
				if currOpt.IsDisabled() {
					DrawStringAtPoint(outTxt, optionStartX, optionStartY, c.disabledFg, c.disabledBg)
				} else if c.GetSelectedOption() == currOpt {
					DrawStringAtPoint(outTxt, optionStartX, optionStartY, c.selectedFg, c.selectedBg)
				} else {
					DrawStringAtPoint(outTxt, optionStartX, optionStartY, useFg, useBg)
				}
				optionStartY++
				if optionStartY > c.y+optionHeight-1 {
					break
				}
			}
		}
	*/
}
842581
func (f *Form) Draw(screen tcell.Screen) {
	f.Box.Draw(screen)

	// Determine the dimensions.
	x, y, width, height := f.GetInnerRect()
	topLimit := y
	bottomLimit := y + height
	rightLimit := x + width
	startX := x

	// Find the longest label.
	var maxLabelWidth int
	for _, item := range f.items {
		labelWidth := TaggedStringWidth(item.GetLabel())
		if labelWidth > maxLabelWidth {
			maxLabelWidth = labelWidth
		}
	}
	maxLabelWidth++ // Add one space.

	// Calculate positions of form items.
	positions := make([]struct{ x, y, width, height int }, len(f.items)+len(f.buttons))
	var focusedPosition struct{ x, y, width, height int }
	for index, item := range f.items {
		// Calculate the space needed.
		labelWidth := TaggedStringWidth(item.GetLabel())
		var itemWidth int
		if f.horizontal {
			fieldWidth := item.GetFieldWidth()
			if fieldWidth == 0 {
				fieldWidth = DefaultFormFieldWidth
			}
			labelWidth++
			itemWidth = labelWidth + fieldWidth
		} else {
			// We want all fields to align vertically.
			labelWidth = maxLabelWidth
			itemWidth = width
		}

		// Advance to next line if there is no space.
		if f.horizontal && x+labelWidth+1 >= rightLimit {
			x = startX
			y += 2
		}

		// Adjust the item's attributes.
		if x+itemWidth >= rightLimit {
			itemWidth = rightLimit - x
		}
		item.SetFormAttributes(
			labelWidth,
			f.labelColor,
			f.backgroundColor,
			f.fieldTextColor,
			f.fieldBackgroundColor,
		)

		// Save position.
		positions[index].x = x
		positions[index].y = y
		positions[index].width = itemWidth
		positions[index].height = 1
		if item.GetFocusable().HasFocus() {
			focusedPosition = positions[index]
		}

		// Advance to next item.
		if f.horizontal {
			x += itemWidth + f.itemPadding
		} else {
			y += 1 + f.itemPadding
		}
	}

	// How wide are the buttons?
	buttonWidths := make([]int, len(f.buttons))
	buttonsWidth := 0
	for index, button := range f.buttons {
		w := TaggedStringWidth(button.GetLabel()) + 4
		buttonWidths[index] = w
		buttonsWidth += w + 1
	}
	buttonsWidth--

	// Where do we place them?
	if !f.horizontal && x+buttonsWidth < rightLimit {
		if f.buttonsAlign == AlignRight {
			x = rightLimit - buttonsWidth
		} else if f.buttonsAlign == AlignCenter {
			x = (x + rightLimit - buttonsWidth) / 2
		}

		// In vertical layouts, buttons always appear after an empty line.
		if f.itemPadding == 0 {
			y++
		}
	}

	// Calculate positions of buttons.
	for index, button := range f.buttons {
		space := rightLimit - x
		buttonWidth := buttonWidths[index]
		if f.horizontal {
			if space < buttonWidth-4 {
				x = startX
				y += 2
				space = width
			}
		} else {
			if space < 1 {
				break // No space for this button anymore.
			}
		}
		if buttonWidth > space {
			buttonWidth = space
		}
		button.SetLabelColor(f.buttonTextColor).
			SetLabelColorActivated(f.buttonBackgroundColor).
			SetBackgroundColorActivated(f.buttonTextColor).
			SetBackgroundColor(f.buttonBackgroundColor)

		buttonIndex := index + len(f.items)
		positions[buttonIndex].x = x
		positions[buttonIndex].y = y
		positions[buttonIndex].width = buttonWidth
		positions[buttonIndex].height = 1

		if button.HasFocus() {
			focusedPosition = positions[buttonIndex]
		}

		x += buttonWidth + 1
	}

	// Determine vertical offset based on the position of the focused item.
	var offset int
	if focusedPosition.y+focusedPosition.height > bottomLimit {
		offset = focusedPosition.y + focusedPosition.height - bottomLimit
		if focusedPosition.y-offset < topLimit {
			offset = focusedPosition.y - topLimit
		}
	}

	// Draw items.
	for index, item := range f.items {
		// Set position.
		y := positions[index].y - offset
		height := positions[index].height
		item.SetRect(positions[index].x, y, positions[index].width, height)

		// Is this item visible?
		if y+height <= topLimit || y >= bottomLimit {
			continue
		}

		// Draw items with focus last (in case of overlaps).
		if item.GetFocusable().HasFocus() {
			defer item.Draw(screen)
		} else {
			item.Draw(screen)
		}
	}

	// Draw buttons.
	for index, button := range f.buttons {
		// Set position.
		buttonIndex := index + len(f.items)
		y := positions[buttonIndex].y - offset
		height := positions[buttonIndex].height
		button.SetRect(positions[buttonIndex].x, y, positions[buttonIndex].width, height)

		// Is this button visible?
		if y+height <= topLimit || y >= bottomLimit {
			continue
		}

		// Draw button.
		button.Draw(screen)
	}
}
420956
func (a *CellView) Draw() {

	port := a.port
	model := a.model
	port.Fill(' ', a.style)

	if a.view == nil {
		return
	}
	if model == nil {
		return
	}
	vw, vh := a.view.Size()
	for y := 0; y < vh; y++ {
		for x := 0; x < vw; x++ {
			a.view.SetContent(x, y, ' ', nil, a.style)
		}
	}

	ex, ey := model.GetBounds()
	vx, vy := port.Size()
	if ex < vx {
		ex = vx
	}
	if ey < vy {
		ey = vy
	}

	cx, cy, en, sh := a.model.GetCursor()
	for y := 0; y < ey; y++ {
		for x := 0; x < ex; x++ {
			ch, style, comb, wid := model.GetCell(x, y)
			if ch == 0 {
				ch = ' '
				style = a.style
			}
			if en && x == cx && y == cy && sh {
				style = style.Reverse(true)
			}
			port.SetContent(x, y, ch, comb, style)
			x += wid - 1
		}
	}
}
1218680
func (img *Image) DrawCircle(xc, yc, r int, fill bool, c color.Color) {
	size := img.Bounds().Size()
	// 如果圆在图片可见区域外，直接退出
	if xc+r < 0 || xc-r >= size.X || yc+r < 0 || yc-r >= size.Y {
		return
	}
	x, y, d := 0, r, 3-2*r
	for x <= y {
		if fill {
			for yi := x; yi <= y; yi++ {
				img.drawCircle8(xc, yc, x, yi, c)
			}
		} else {
			img.drawCircle8(xc, yc, x, y, c)
		}
		if d < 0 {
			d = d + 4*x + 6
		} else {
			d = d + 4*(x-y) + 10
			y--
		}
		x++
	}
}
949761
func (d draw) LineSeries(r Renderer, canvasBox Box, xrange, yrange Range, style Style, vs ValuesProvider) {
	if vs.Len() == 0 {
		return
	}

	cb := canvasBox.Bottom
	cl := canvasBox.Left

	v0x, v0y := vs.GetValues(0)
	x0 := cl + xrange.Translate(v0x)
	y0 := cb - yrange.Translate(v0y)

	yv0 := yrange.Translate(0)

	var vx, vy float64
	var x, y int

	if style.ShouldDrawStroke() && style.ShouldDrawFill() {
		style.GetFillOptions().WriteDrawingOptionsToRenderer(r)
		r.MoveTo(x0, y0)
		for i := 1; i < vs.Len(); i++ {
			vx, vy = vs.GetValues(i)
			x = cl + xrange.Translate(vx)
			y = cb - yrange.Translate(vy)
			r.LineTo(x, y)
		}
		r.LineTo(x, util.Math.MinInt(cb, cb-yv0))
		r.LineTo(x0, util.Math.MinInt(cb, cb-yv0))
		r.LineTo(x0, y0)
		r.Fill()
	}

	if style.ShouldDrawStroke() {
		style.GetStrokeOptions().WriteDrawingOptionsToRenderer(r)

		r.MoveTo(x0, y0)
		for i := 1; i < vs.Len(); i++ {
			vx, vy = vs.GetValues(i)
			x = cl + xrange.Translate(vx)
			y = cb - yrange.Translate(vy)
			r.LineTo(x, y)
		}
		r.Stroke()
	}

	if style.ShouldDrawDot() {
		defaultDotWidth := style.GetDotWidth()

		style.GetDotOptions().WriteDrawingOptionsToRenderer(r)
		for i := 0; i < vs.Len(); i++ {
			vx, vy = vs.GetValues(i)
			x = cl + xrange.Translate(vx)
			y = cb - yrange.Translate(vy)

			dotWidth := defaultDotWidth
			if style.DotWidthProvider != nil {
				dotWidth = style.DotWidthProvider(xrange, yrange, i, vx, vy)
			}

			if style.DotColorProvider != nil {
				dotColor := style.DotColorProvider(xrange, yrange, i, vx, vy)

				r.SetFillColor(dotColor)
				r.SetStrokeColor(dotColor)
			}

			r.Circle(dotWidth, x, y)
			r.FillStroke()
		}
	}
}
463384
func NewDrawing(init ...*Drawing) *Drawing {
	var o *Drawing
	if len(init) == 1 {
		o = init[0]
	} else {
		o = new(Drawing)
	}
	return o.Init()
}
164099
func (e *Entry) Draw(p *Painter) {
	style := "entry"
	if e.IsFocused() {
		style += ".focused"
	}
	p.WithStyle(style, func(p *Painter) {
		s := e.Size()
		e.text.SetMaxWidth(s.X)

		text := e.visibleText()

		p.FillRect(0, 0, s.X, 1)

		switch e.echoMode {
		case EchoModeNormal:
			p.DrawText(0, 0, text)
		case EchoModePassword:
			p.DrawText(0, 0, strings.Repeat("*", len(text)))
		}

		if e.IsFocused() {
			var off int
			if e.echoMode != EchoModeNoEcho {
				off = e.text.CursorPos().X - e.offset
			}
			p.DrawCursor(off, 0)
		}
	})
}
600878
func (b *BoxLayout) Draw() {

	if b.view == nil {
		return
	}
	if b.changed {
		b.layout()
	}
	b.view.Fill(' ', b.style)
	for i := range b.cells {
		b.cells[i].widget.Draw()
	}
}
916143
func (vs *VertexSlice) Draw() {
	vs.va.draw(vs.i, vs.j)
}