Beispiel #1
0
// Input shouldn't have newlines
func (o *OpenGlStream) PrintLine(s string) {
	if o.BorderColor != nil {
		gl.PushAttrib(gl.CURRENT_BIT)

		expandedLineLength := caret.ExpandedLength(s, o.advance)

		backgroundColor := nearlyWhiteColor
		if o.BackgroundColor != nil {
			backgroundColor = *o.BackgroundColor
		}

		DrawInnerRoundedBox(o.pos, mgl64.Vec2{fontWidth * float64(expandedLineLength), fontHeight}, *o.BorderColor, backgroundColor)

		gl.PopAttrib()
	}

	segments := strings.Split(s, "\t")
	for index, segment := range segments {
		o.PrintSegment(segment)
		o.advanceBy(uint32(len(segment)))
		if index+1 < len(segments) {
			tabSpaces := 4 - (o.advance % 4)
			o.PrintSegment(strings.Repeat(" ", int(tabSpaces))) // Tab.
			if o.ShowInvisibles {
				gl.PushAttrib(gl.CURRENT_BIT)
				DrawBorderlessBox(o.pos.Add(mgl64.Vec2{1, fontHeight/2 - 1}), mgl64.Vec2{fontWidth*float64(tabSpaces) - 2, 2}, selectedTextDarkColor)
				gl.PopAttrib()
			}
			o.advanceBy(tabSpaces)
		}
	}
}
Beispiel #2
0
// Shouldn't have tabs nor newlines
func (o *OpenGlStream) PrintSegment(s string) {
	if s == "" {
		return
	}

	if o.BackgroundColor != nil && o.BorderColor == nil {
		gl.PushAttrib(gl.CURRENT_BIT)
		gl.Color3dv((*float64)(&o.BackgroundColor[0]))
		gl.PushMatrix()
		gl.Translated(float64(o.pos[0]), float64(o.pos[1]), 0)
		for range s {
			gl.CallList(oFontBackground)
		}
		gl.PopMatrix()
		gl.PopAttrib()
	}

	gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_LOD_BIAS, float32(lodBias*0.01))

	gl.Enable(gl.BLEND)
	defer gl.Disable(gl.BLEND)
	gl.Enable(gl.TEXTURE_2D)
	defer gl.Disable(gl.TEXTURE_2D)

	gl.PushMatrix()
	gl.Translated(float64(o.pos[0]), float64(o.pos[1]), 0)
	gl.ListBase(oFontBase + uint32(o.FontOptions)*96)
	gl.CallLists(int32(len(s)), gl.UNSIGNED_BYTE, gl.Ptr(&[]byte(s)[0]))
	gl.PopMatrix()

	//CheckGLError()
}
Beispiel #3
0
// Printf draws the given string at the specified coordinates.
// It expects the string to be a single line. Line breaks are not
// handled as line breaks and are rendered as glyphs.
//
// In order to render multi-line text, it is up to the caller to split
// the text up into individual lines of adequate length and then call
// this method for each line seperately.
func (f *Font) Printf(x, y float32, fs string, argv ...interface{}) error {
	indices := []rune(fmt.Sprintf(fs, argv...))

	if len(indices) == 0 {
		return nil
	}

	// Runes form display list indices.
	// For this purpose, they need to be offset by -FontConfig.Low
	low := f.config.Low
	for i := range indices {
		indices[i] -= low
	}

	var vp [4]int32
	gl.GetIntegerv(gl.VIEWPORT, &vp[0])

	gl.PushAttrib(gl.TRANSFORM_BIT)
	gl.MatrixMode(gl.PROJECTION)
	gl.PushMatrix()
	gl.LoadIdentity()
	gl.Ortho(float64(vp[0]), float64(vp[2]), float64(vp[1]), float64(vp[3]), 0, 1)
	gl.PopAttrib()

	gl.PushAttrib(gl.LIST_BIT | gl.CURRENT_BIT | gl.ENABLE_BIT | gl.TRANSFORM_BIT)
	{
		gl.MatrixMode(gl.MODELVIEW)
		gl.Disable(gl.LIGHTING)
		gl.Disable(gl.DEPTH_TEST)
		gl.Enable(gl.BLEND)
		gl.Enable(gl.TEXTURE_2D)

		gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
		gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE)
		gl.BindTexture(gl.TEXTURE_2D, f.texture)
		gl.ListBase(f.listbase)

		var mv [16]float32
		gl.GetFloatv(gl.MODELVIEW_MATRIX, &mv[0])

		gl.PushMatrix()
		{
			gl.LoadIdentity()

			mgw := float32(f.maxGlyphWidth)
			mgh := float32(f.maxGlyphHeight)

			switch f.config.Dir {
			case LeftToRight, TopToBottom:
				gl.Translatef(x, float32(vp[3])-y-mgh, 0)
			case RightToLeft:
				gl.Translatef(x-mgw, float32(vp[3])-y-mgh, 0)
			}

			gl.MultMatrixf(&mv[0])
			gl.CallLists(int32(len(indices)), gl.UNSIGNED_INT, unsafe.Pointer(&indices[0]))
		}
		gl.PopMatrix()
		gl.BindTexture(gl.TEXTURE_2D, 0)
	}
	gl.PopAttrib()

	gl.PushAttrib(gl.TRANSFORM_BIT)
	gl.MatrixMode(gl.PROJECTION)
	gl.PopMatrix()
	gl.PopAttrib()
	return checkGLError()
}