github.com/Kintar/etxt@v0.0.0-20221224033739-2fc69f000137/examples/gtxt/aligns/main.go (about)

     1  //go:build gtxt
     2  
     3  package main
     4  
     5  import "os"
     6  import "image"
     7  import "image/color"
     8  import "image/png"
     9  import "path/filepath"
    10  import "log"
    11  import "fmt"
    12  
    13  import "github.com/Kintar/etxt"
    14  
    15  // Must be compiled with '-tags gtxt'
    16  
    17  func main() {
    18  	// get font path
    19  	if len(os.Args) != 2 {
    20  		msg := "Usage: expects one argument with the path to the font to be used\n"
    21  		fmt.Fprint(os.Stderr, msg)
    22  		os.Exit(1)
    23  	}
    24  
    25  	// parse font
    26  	font, fontName, err := etxt.ParseFontFrom(os.Args[1])
    27  	if err != nil {
    28  		log.Fatal(err)
    29  	}
    30  	fmt.Printf("Font loaded: %s\n", fontName)
    31  
    32  	// create cache
    33  	cache := etxt.NewDefaultCache(1024 * 1024 * 1024) // 1GB cache
    34  
    35  	// create and configure renderer
    36  	renderer := etxt.NewStdRenderer()
    37  	renderer.SetCacheHandler(cache.NewHandler())
    38  	renderer.SetSizePx(18)
    39  	renderer.SetFont(font)
    40  	renderer.SetColor(color.RGBA{40, 0, 0, 255})
    41  
    42  	// create target image and fill it with a dark background color,
    43  	// four rectangles to draw text with different aligns within each
    44  	// one, including guide lines and a central mark for each rectangle
    45  	// (this has nothing to do with etxt, it's only to make it look nice)
    46  	outImage, targets := makeFancyOutImage()
    47  
    48  	// set renderer's target and draw on each target point
    49  	// with different aligns
    50  	renderer.SetTarget(outImage)
    51  
    52  	// default (Baseline, Left) align
    53  	// renderer.SetAlign(etxt.Baseline, etxt.Left)
    54  	renderer.Draw("(Baseline, Left)", targets[0].X, targets[0].Y)
    55  
    56  	// (YCenter, XCenter) align
    57  	renderer.SetAlign(etxt.YCenter, etxt.XCenter)
    58  	renderer.Draw("(YCenter, XCenter)", targets[1].X, targets[1].Y)
    59  
    60  	// (Top, Right) align
    61  	renderer.SetAlign(etxt.Top, etxt.Right)
    62  	renderer.Draw("(Top, Right)", targets[2].X, targets[2].Y)
    63  
    64  	// (Bottom, XCenter) align
    65  	renderer.SetAlign(etxt.Bottom, etxt.XCenter)
    66  	renderer.Draw("(Bottom, XCenter)", targets[3].X, targets[3].Y)
    67  
    68  	// store image as png
    69  	filename, err := filepath.Abs("gtxt_aligns.png")
    70  	if err != nil {
    71  		log.Fatal(err)
    72  	}
    73  	fmt.Printf("Output image: %s\n", filename)
    74  	file, err := os.Create(filename)
    75  	if err != nil {
    76  		log.Fatal(err)
    77  	}
    78  	err = png.Encode(file, outImage)
    79  	if err != nil {
    80  		log.Fatal(err)
    81  	}
    82  	err = file.Close()
    83  	if err != nil {
    84  		log.Fatal(err)
    85  	}
    86  	fmt.Print("Program exited successfully.\n")
    87  }
    88  
    89  // Creates an image with four subrectangles in it, each with guide lines
    90  // and a mark at their center, so we can use it to draw with different
    91  // aligns on top and see how they relate to the given marks.
    92  //
    93  // This has nothing to do with etxt itself, so you don't need to understand
    94  // it, and if you are doing game dev this is trivial for you anyway.
    95  func makeFancyOutImage() (*image.RGBA, [4]image.Point) {
    96  	// out image properties
    97  	rectWidth := 301
    98  	rectHeight := 101
    99  	padding := 4
   100  	backColor := color.RGBA{R: 236, G: 236, B: 230, A: 255}
   101  	rectColor := color.RGBA{R: 200, G: 196, B: 206, A: 255}
   102  	guideColor := color.RGBA{R: 220, G: 220, B: 220, A: 255}
   103  	markColor := color.RGBA{R: 0, G: 80, B: 120, A: 255}
   104  	markColor2 := color.RGBA{R: 0, G: 190, B: 80, A: 255}
   105  	totalWidth := rectWidth*2 + padding*3
   106  	totalHeight := rectHeight*2 + padding*3
   107  	outImage := image.NewRGBA(image.Rect(0, 0, totalWidth, totalHeight))
   108  
   109  	// paint background
   110  	for y := 0; y < totalHeight; y++ {
   111  		for x := 0; x < totalWidth; x++ {
   112  			outImage.Set(x, y, backColor)
   113  		}
   114  	}
   115  
   116  	// paint rects
   117  	for y := 0; y < rectHeight; y++ {
   118  		for x := 0; x < rectWidth; x++ {
   119  			// we draw the four rects at once (not ideal for memory accesses)
   120  			outImage.Set(x+padding, y+padding, rectColor)
   121  			outImage.Set(x+padding*2+rectWidth, y+padding, rectColor)
   122  			lowerY := y + rectHeight + padding*2
   123  			outImage.Set(x+padding, lowerY, rectColor)
   124  			outImage.Set(x+padding*2+rectWidth, lowerY, rectColor)
   125  		}
   126  	}
   127  
   128  	// paint guide lines
   129  	for x := 0; x < rectWidth; x++ { // horizontal guide lines
   130  		y := padding + rectHeight/2
   131  		outImage.Set(x+padding, y, guideColor)
   132  		outImage.Set(x+padding*2+rectWidth, y, guideColor)
   133  		yBottom := y + padding + rectHeight
   134  		outImage.Set(x+padding, yBottom, guideColor)
   135  		outImage.Set(x+padding*2+rectWidth, yBottom, guideColor)
   136  	}
   137  	for y := 0; y < rectHeight; y++ { // vertical guide lines
   138  		outImage.Set(padding+rectWidth/2, y+padding, guideColor)
   139  		outImage.Set(padding+rectWidth/2, y+padding*2+rectHeight, guideColor)
   140  		xRight := rectWidth/2 + padding*2 + rectWidth
   141  		outImage.Set(xRight, y+padding, guideColor)
   142  		outImage.Set(xRight, y+padding*2+rectHeight, guideColor)
   143  	}
   144  
   145  	// create target points for reference marks
   146  	ta := image.Pt(rectWidth/2+padding, rectHeight/2+padding)
   147  	tb := image.Pt(rectWidth/2+padding*2+rectWidth, rectHeight/2+padding)
   148  	tc := image.Pt(rectWidth/2+padding, rectHeight/2+padding*2+rectHeight)
   149  	td := image.Pt(rectWidth/2+padding*2+rectWidth, rectHeight/2+padding*2+rectHeight)
   150  
   151  	// paint reference marks
   152  	drawMarkAt := func(x, y int) {
   153  		outImage.Set(x, y, markColor)
   154  		for i := 1; i < 3; i++ {
   155  			outImage.Set(x+i, y, markColor)
   156  			outImage.Set(x-i, y, markColor)
   157  			outImage.Set(x, y-i, markColor)
   158  			outImage.Set(x, y+i, markColor)
   159  		}
   160  		outImage.Set(x+1, y+1, markColor2)
   161  		outImage.Set(x+1, y-1, markColor2)
   162  		outImage.Set(x-1, y+1, markColor2)
   163  		outImage.Set(x-1, y-1, markColor2)
   164  	}
   165  	drawMarkAt(ta.X, ta.Y)
   166  	drawMarkAt(tb.X, tb.Y)
   167  	drawMarkAt(tc.X, tc.Y)
   168  	drawMarkAt(td.X, td.Y)
   169  
   170  	return outImage, [4]image.Point{ta, tb, tc, td}
   171  }