Text rendering is a thing again
This commit is contained in:
		
							parent
							
								
									34bf3038ac
								
							
						
					
					
						commit
						ec24eb7b4f
					
				
							
								
								
									
										12
									
								
								artist/pattern.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								artist/pattern.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | package artist | ||||||
|  | 
 | ||||||
|  | import "image/color" | ||||||
|  | 
 | ||||||
|  | // Pattern is capable of generating a pattern pixel by pixel. | ||||||
|  | type Pattern interface { | ||||||
|  | 	// AtWhen returns the color of the pixel located at (x, y) relative to | ||||||
|  | 	// the origin point of the pattern (0, 0), when the pattern has the | ||||||
|  | 	// specified width and height. Patterns may ignore the width and height | ||||||
|  | 	// parameters, but it may be useful for some patterns such as gradients. | ||||||
|  | 	AtWhen (x, y, width, height int) (color.RGBA) | ||||||
|  | } | ||||||
| @ -29,6 +29,7 @@ func Paste ( | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // FillRectangle draws a filled rectangle with the specified pattern. | ||||||
| func FillRectangle ( | func FillRectangle ( | ||||||
| 	destination tomo.Canvas, | 	destination tomo.Canvas, | ||||||
| 	source Pattern, | 	source Pattern, | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ package artist | |||||||
| // import "fmt" | // import "fmt" | ||||||
| import "image" | import "image" | ||||||
| import "unicode" | import "unicode" | ||||||
| // import "image/draw" | import "image/draw" | ||||||
| import "golang.org/x/image/font" | import "golang.org/x/image/font" | ||||||
| import "golang.org/x/image/math/fixed" | import "golang.org/x/image/math/fixed" | ||||||
| import "git.tebibyte.media/sashakoshka/tomo" | import "git.tebibyte.media/sashakoshka/tomo" | ||||||
| @ -100,30 +100,36 @@ func (drawer *TextDrawer) Draw ( | |||||||
| ) ( | ) ( | ||||||
| 	updatedRegion image.Rectangle, | 	updatedRegion image.Rectangle, | ||||||
| ) { | ) { | ||||||
|  | 	wrappedSource := WrappedPattern { | ||||||
|  | 		Pattern: source, | ||||||
|  | 		Width:  0, | ||||||
|  | 		Height: 0, // TODO: choose a better width and height | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if !drawer.layoutClean { drawer.recalculate() } | 	if !drawer.layoutClean { drawer.recalculate() } | ||||||
| 	// TODO: reimplement a version of draw mask that takes in a pattern | 	// TODO: reimplement a version of draw mask that takes in a pattern | ||||||
| 	// for _, word := range drawer.layout { | 	for _, word := range drawer.layout { | ||||||
| 	// for _, character := range word.text { | 	for _, character := range word.text { | ||||||
| 		// destinationRectangle, | 		destinationRectangle, | ||||||
| 		// mask, maskPoint, _, ok := drawer.face.Glyph ( | 		mask, maskPoint, _, ok := drawer.face.Glyph ( | ||||||
| 			// fixed.P ( | 			fixed.P ( | ||||||
| 				// offset.X + word.position.X + character.x, | 				offset.X + word.position.X + character.x, | ||||||
| 				// offset.Y + word.position.Y), | 				offset.Y + word.position.Y), | ||||||
| 			// character.character) | 			character.character) | ||||||
| 		// if !ok { continue } | 		if !ok { continue } | ||||||
| 
 | 
 | ||||||
| 		// FIXME: clip destination rectangle if we are on the cusp of | 		// FIXME: clip destination rectangle if we are on the cusp of | ||||||
| 		// the maximum height. | 		// the maximum height. | ||||||
| 
 | 
 | ||||||
| 		// draw.DrawMask ( | 		draw.DrawMask ( | ||||||
| 			// destination, | 			destination, | ||||||
| 			// destinationRectangle, | 			destinationRectangle, | ||||||
| 			// source, image.Point { }, | 			wrappedSource, image.Point { }, | ||||||
| 			// mask, maskPoint, | 			mask, maskPoint, | ||||||
| 			// draw.Over) | 			draw.Over) | ||||||
| 
 | 
 | ||||||
| 		// updatedRegion = updatedRegion.Union(destinationRectangle) | 		updatedRegion = updatedRegion.Union(destinationRectangle) | ||||||
| 	// }} | 	}} | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,15 +3,6 @@ package artist | |||||||
| import "image" | import "image" | ||||||
| import "image/color" | import "image/color" | ||||||
| 
 | 
 | ||||||
| // Pattern is capable of generating a pattern pixel by pixel. |  | ||||||
| type Pattern interface { |  | ||||||
| 	// AtWhen returns the color of the pixel located at (x, y) relative to |  | ||||||
| 	// the origin point of the pattern (0, 0), when the pattern has the |  | ||||||
| 	// specified width and height. Patterns may ignore the width and height |  | ||||||
| 	// parameters, but it may be useful for some patterns such as gradients. |  | ||||||
| 	AtWhen (x, y, width, height int) (color.RGBA) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Texture is a struct that allows an image to be converted into a tiling | // Texture is a struct that allows an image to be converted into a tiling | ||||||
| // texture pattern. | // texture pattern. | ||||||
| type Texture struct { | type Texture struct { | ||||||
| @ -4,61 +4,52 @@ import "image" | |||||||
| import "image/color" | import "image/color" | ||||||
| 
 | 
 | ||||||
| // Uniform is an infinite-sized pattern of uniform color. It implements the | // Uniform is an infinite-sized pattern of uniform color. It implements the | ||||||
| // color.Color, color.Model, and image.Image interfaces. | // Pattern, color.Color, color.Model, and image.Image interfaces. | ||||||
| type Uniform struct { | type Uniform color.RGBA | ||||||
| 	C color.RGBA |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| // NewUniform returns a new Uniform image of the given color. | // NewUniform returns a new Uniform image of the given color. | ||||||
| func NewUniform (c color.Color) (uniform *Uniform) { | func NewUniform (c color.Color) (uniform Uniform) { | ||||||
| 	uniform = &Uniform { } |  | ||||||
| 	r, g, b, a := c.RGBA() | 	r, g, b, a := c.RGBA() | ||||||
| 	uniform.C.R = uint8(r >> 8) | 	uniform.R = uint8(r >> 8) | ||||||
| 	uniform.C.G = uint8(g >> 8) | 	uniform.G = uint8(g >> 8) | ||||||
| 	uniform.C.B = uint8(b >> 8) | 	uniform.B = uint8(b >> 8) | ||||||
| 	uniform.C.A = uint8(a >> 8) | 	uniform.A = uint8(a >> 8) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (uniform *Uniform) RGBA () (r, g, b, a uint32) { | // ColorModel satisfies the image.Image interface. | ||||||
| 	r = uint32(uniform.C.R) << 8 | uint32(uniform.C.R) | func (uniform Uniform) ColorModel () (model color.Model) { | ||||||
| 	g = uint32(uniform.C.G) << 8 | uint32(uniform.C.G) |  | ||||||
| 	b = uint32(uniform.C.B) << 8 | uint32(uniform.C.B) |  | ||||||
| 	a = uint32(uniform.C.A) << 8 | uint32(uniform.C.A) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (uniform *Uniform) ColorModel () (model color.Model) { |  | ||||||
| 	return uniform | 	return uniform | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (uniform *Uniform) Convert (in color.Color) (c color.Color) { | // Convert satisfies the color.Model interface. | ||||||
| 	return uniform.C | func (uniform Uniform) Convert (in color.Color) (c color.Color) { | ||||||
|  | 	return color.RGBA(uniform) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (uniform *Uniform) Bounds () (rectangle image.Rectangle) { | // Bounds satisfies the image.Image interface. | ||||||
|  | func (uniform Uniform) Bounds () (rectangle image.Rectangle) { | ||||||
| 	rectangle.Min = image.Point { -1e9, -1e9 } | 	rectangle.Min = image.Point { -1e9, -1e9 } | ||||||
| 	rectangle.Max = image.Point {  1e9,  1e9 } | 	rectangle.Max = image.Point {  1e9,  1e9 } | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (uniform *Uniform) At (x, y int) (c color.Color) { | // At satisfies the image.Image interface. | ||||||
| 	return uniform.C | func (uniform Uniform) At (x, y int) (c color.Color) { | ||||||
|  | 	return color.RGBA(uniform) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (uniform *Uniform) AtWhen (x, y, width, height int) (c color.RGBA) { | // AtWhen satisfies the Pattern interface. | ||||||
| 	return uniform.C | func (uniform Uniform) AtWhen (x, y, width, height int) (c color.RGBA) { | ||||||
|  | 	return color.RGBA(uniform) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (uniform *Uniform) RGBA64At (x, y int) (c color.RGBA64) { | // RGBA satisfies the color.Color interface. | ||||||
| 	r := uint16(uniform.C.R) << 8 | uint16(uniform.C.R) | func (uniform Uniform) RGBA () (r, g, b, a uint32) { | ||||||
| 	g := uint16(uniform.C.G) << 8 | uint16(uniform.C.G) | 	return color.RGBA(uniform).RGBA() | ||||||
| 	b := uint16(uniform.C.B) << 8 | uint16(uniform.C.B) |  | ||||||
| 	a := uint16(uniform.C.A) << 8 | uint16(uniform.C.A) |  | ||||||
| 	return color.RGBA64 { R: r, G: g, B: b, A: a } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Opaque scans the entire image and reports whether it is fully opaque. | // Opaque scans the entire image and reports whether it is fully opaque. | ||||||
| func (uniform *Uniform) Opaque () (opaque bool) { | func (uniform Uniform) Opaque () (opaque bool) { | ||||||
| 	return uniform.C.A == 0xFF | 	return uniform.A == 0xFF | ||||||
| } | } | ||||||
|  | |||||||
| @ -1 +1,27 @@ | |||||||
| package artist | package artist | ||||||
|  | 
 | ||||||
|  | import "image" | ||||||
|  | import "image/color" | ||||||
|  | 
 | ||||||
|  | // WrappedPattern is a pattern that is able to behave like an image.Image. | ||||||
|  | type WrappedPattern struct { | ||||||
|  | 	Pattern | ||||||
|  | 	Width, Height int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // At satisfies the image.Image interface. | ||||||
|  | func (pattern WrappedPattern) At (x, y int) (c color.Color) { | ||||||
|  | 	return pattern.Pattern.AtWhen(x, y, pattern.Width, pattern.Height) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bounds satisfies the image.Image interface. | ||||||
|  | func (pattern WrappedPattern) Bounds () (rectangle image.Rectangle) { | ||||||
|  | 	rectangle.Min = image.Point { -1e9, -1e9 } | ||||||
|  | 	rectangle.Max = image.Point {  1e9,  1e9 } | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ColorModel satisfies the image.Image interface. | ||||||
|  | func (pattern WrappedPattern) ColorModel () (model color.Model) { | ||||||
|  | 	return color.RGBAModel | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user