...

Source file src/golang.org/x/image/font/sfnt/example_test.go

Documentation: golang.org/x/image/font/sfnt

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sfnt_test
     6  
     7  import (
     8  	"image"
     9  	"image/draw"
    10  	"log"
    11  	"os"
    12  
    13  	"golang.org/x/image/font/gofont/goregular"
    14  	"golang.org/x/image/font/sfnt"
    15  	"golang.org/x/image/math/fixed"
    16  	"golang.org/x/image/vector"
    17  )
    18  
    19  func Example_rasterizeGlyph() {
    20  	const (
    21  		ppem    = 32
    22  		width   = 24
    23  		height  = 36
    24  		originX = 0
    25  		originY = 32
    26  	)
    27  
    28  	// Load the 'G' glyph from the Go Regular font.
    29  	f, err := sfnt.Parse(goregular.TTF)
    30  	if err != nil {
    31  		log.Fatalf("Parse: %v", err)
    32  	}
    33  	var b sfnt.Buffer
    34  	x, err := f.GlyphIndex(&b, 'Ġ')
    35  	if err != nil {
    36  		log.Fatalf("GlyphIndex: %v", err)
    37  	}
    38  	if x == 0 {
    39  		log.Fatalf("GlyphIndex: no glyph index found for the rune 'Ġ'")
    40  	}
    41  	segments, err := f.LoadGlyph(&b, x, fixed.I(ppem), nil)
    42  	if err != nil {
    43  		log.Fatalf("LoadGlyph: %v", err)
    44  	}
    45  
    46  	// Translate and scale that glyph as we pass it to a vector.Rasterizer.
    47  	r := vector.NewRasterizer(width, height)
    48  	r.DrawOp = draw.Src
    49  	for _, seg := range segments {
    50  		// The divisions by 64 below is because the seg.Args values have type
    51  		// fixed.Int26_6, a 26.6 fixed point number, and 1<<6 == 64.
    52  		switch seg.Op {
    53  		case sfnt.SegmentOpMoveTo:
    54  			r.MoveTo(
    55  				originX+float32(seg.Args[0].X)/64,
    56  				originY+float32(seg.Args[0].Y)/64,
    57  			)
    58  		case sfnt.SegmentOpLineTo:
    59  			r.LineTo(
    60  				originX+float32(seg.Args[0].X)/64,
    61  				originY+float32(seg.Args[0].Y)/64,
    62  			)
    63  		case sfnt.SegmentOpQuadTo:
    64  			r.QuadTo(
    65  				originX+float32(seg.Args[0].X)/64,
    66  				originY+float32(seg.Args[0].Y)/64,
    67  				originX+float32(seg.Args[1].X)/64,
    68  				originY+float32(seg.Args[1].Y)/64,
    69  			)
    70  		case sfnt.SegmentOpCubeTo:
    71  			r.CubeTo(
    72  				originX+float32(seg.Args[0].X)/64,
    73  				originY+float32(seg.Args[0].Y)/64,
    74  				originX+float32(seg.Args[1].X)/64,
    75  				originY+float32(seg.Args[1].Y)/64,
    76  				originX+float32(seg.Args[2].X)/64,
    77  				originY+float32(seg.Args[2].Y)/64,
    78  			)
    79  		}
    80  	}
    81  
    82  	// Finish the rasterization: the conversion from vector graphics (shapes)
    83  	// to raster graphics (pixels).
    84  	dst := image.NewAlpha(image.Rect(0, 0, width, height))
    85  	r.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
    86  
    87  	// Visualize the pixels.
    88  	const asciiArt = ".++8"
    89  	buf := make([]byte, 0, height*(width+1))
    90  	for y := 0; y < height; y++ {
    91  		for x := 0; x < width; x++ {
    92  			a := dst.AlphaAt(x, y).A
    93  			buf = append(buf, asciiArt[a>>6])
    94  		}
    95  		buf = append(buf, '\n')
    96  	}
    97  	os.Stdout.Write(buf)
    98  
    99  	// Output:
   100  	// ........................
   101  	// ........................
   102  	// ........................
   103  	// ............888.........
   104  	// ............888.........
   105  	// ............888.........
   106  	// ............+++.........
   107  	// ........................
   108  	// ..........+++++++++.....
   109  	// .......+8888888888888+..
   110  	// ......8888888888888888..
   111  	// ....+8888+........++88..
   112  	// ....8888................
   113  	// ...8888.................
   114  	// ..+888+.................
   115  	// ..+888..................
   116  	// ..888+..................
   117  	// .+888+..................
   118  	// .+888...................
   119  	// .+888...................
   120  	// .+888...................
   121  	// .+888..........+++++++..
   122  	// .+888..........8888888..
   123  	// .+888+.........+++8888..
   124  	// ..888+............+888..
   125  	// ..8888............+888..
   126  	// ..+888+...........+888..
   127  	// ...8888+..........+888..
   128  	// ...+8888+.........+888..
   129  	// ....+88888+.......+888..
   130  	// .....+8888888888888888..
   131  	// .......+888888888888++..
   132  	// ..........++++++++......
   133  	// ........................
   134  	// ........................
   135  	// ........................
   136  }
   137  

View as plain text