Example #1
0
// Trimmed ...
func (t *Tree) Trimmed() *Tree {
	var leafs []image.Rectangle
	t.Visit(func(other *Tree) {
		if len(other.points) == 0 {
			return
		}
		leafs = append(leafs, image.Rectangle{
			Min: other.Extents.Min,
			Max: other.Extents.Max,
		})
	})

	var r *image.Rectangle
	for _, b := range leafs {
		if r == nil {
			r = new(image.Rectangle)
			*r = b
			continue
		}
		*r = r.Union(b)
	}

	tr := New(*r, t.capacity)

	t.Visit(func(other *Tree) {
		for p := range other.points {
			tr.Insert(p)
		}
	})

	return tr
}
Example #2
0
//
//		Private functions
//
func ContainerFit(outer, inner image.Rectangle) image.Rectangle {
	borderTop := image.Point{-18, -30}
	borderBottom := image.Point{18, 18}
	test := image.Rectangle{inner.Min.Add(borderTop), inner.Max.Add(borderBottom)}
	if outer.Size().X == 0 {
		return test
	}
	return outer.Union(test)
}
Example #3
0
func Invalidate(rect image.Rectangle) {
	for {
		select {
		case shouldPaint <- rect:
			return
		case r2 := <-shouldPaint:
			rect = rect.Union(r2)
		}
	}
}
Example #4
0
// NewBackground creates an xgraphics.Image which spans the entire screen,
// initialized to black.
func NewBackground(X *xgbutil.XUtil) (*xgraphics.Image, error) {
	res, err := randr.GetScreenResources(X.Conn(), X.RootWin()).Reply()
	if err != nil {
		return nil, err
	}
	var bgRect image.Rectangle
	for _, output := range res.Outputs {
		r, err := util.OutputRect(X, output)
		// NOTE: It doesn't really matter if this returns a Zero Rectangle.
		if err != nil {
			return nil, err
		}
		bgRect = bgRect.Union(r)
	}
	return xgraphics.New(X, bgRect), nil
}
Example #5
0
//Returns the rate of the union of r and rects.
func rateOf(r image.Rectangle, union image.Rectangle, totalArea int) float64 {
	unionAndR := union.Union(r)

	wastedArea := area(unionAndR) - totalArea - area(r)
	return float64(wastedArea) * aspectRatio(unionAndR)
}
Example #6
0
func Paint(w wde.Window, rect image.Rectangle) {
	xOffset, yOffset := GetTopLeft()
	center := layout.Coord{ViewportWidth/2 - xOffset, ViewportHeight/2 - yOffset}

	if center != oldCenter || layout.Version() != oldVersion {
		oldCenter = center
		oldVersion = layout.Version()

		for x := 0; x <= ViewportWidth; x++ {
			for y := 0; y <= ViewportHeight; y++ {
				if layout.Visible(center, layout.Coord{x - xOffset, y - yOffset}) {
					res.Tile(terrain, res.Terrain, uint16(layout.GetSpace(x-xOffset, y-yOffset)), x, y)
					draw.Draw(terrain, image.Rect(x<<res.TileSize, y<<res.TileSize, (x+1)<<res.TileSize, (y+1)<<res.TileSize), image.Transparent, image.ZP, draw.Src)
					for _, t := range layout.Get(x-xOffset, y-yOffset) {
						if !t.NoClient() {
							res.Tile(terrain, res.Terrain, uint16(t), x, y)
						}
					}
				} else {
					res.Tile(terrain, image.Black, 0, x, y)
				}
			}
		}

		switch GetPlayerFlags() & packet.FlagSpriteMask {
		case packet.FlagEngineer:
			for x := 0; x <= ViewportWidth; x++ {
				for y := 0; y <= ViewportHeight; y++ {
					dx, dy := x-ViewportWidth/2, y-ViewportHeight/2
					dist := dx*dx + dy*dy
					if dist <= 3*3 && layout.Visible(center, layout.Coord{x - xOffset, y - yOffset}) {
						for _, t := range layout.Get(x-xOffset, y-yOffset) {
							if t >= layout.WireW && t <= layout.WireS {
								res.Tile(terrain, res.Terrain, uint16(t), x, y)
							}
						}
					}
				}
			}
		}
	}

	minX, maxX := rect.Min.X>>res.TileSize, (rect.Max.X-1)>>res.TileSize+1
	minY, maxY := rect.Min.Y>>res.TileSize, (rect.Max.Y-1)>>res.TileSize+1

	draw.Draw(sprites, sprites.Bounds(), image.Transparent, image.ZP, draw.Src)

	var pixOffset image.Point

	var hasAnimation image.Rectangle
	paintLock.Lock()
	for _, p := range paintContexts {
		if layout.Visible(center, p.To) {
			x1, y1 := p.From.X+xOffset, p.From.Y+yOffset
			x2, y2 := p.To.X+xOffset, p.To.Y+yOffset

			if minX <= x2 && x2 <= maxX && minY <= y2 && y2 <= maxY {
				interp := float32(time.Since(p.Changed)*5) / float32(time.Second)
				if interp >= 1 {
					res.Tile(sprites, res.Actors, p.Sprite, x2, y2)
				} else {
					toInvalidate := image.Rect(x1, y1, x1+1, y1+1).Union(image.Rect(x2, y2, x2+1, y2+1))
					if hasAnimation.Empty() {
						hasAnimation = toInvalidate
					} else {
						hasAnimation = hasAnimation.Union(toInvalidate)
					}
					if p == thePlayer.paint {
						pixOffset.X = int(float32((x1-x2)<<res.TileSize) * (1 - interp))
						pixOffset.Y = int(float32((y1-y2)<<res.TileSize) * (1 - interp))
						hasAnimation = viewport.Bounds()
					}
					res.TileFloat(sprites, res.Actors, p.Sprite, x1, y1, x2, y2, interp)
				}
			}
		}
	}
	paintLock.Unlock()

	draw.Draw(viewport, rect, terrain, rect.Min.Add(pixOffset), draw.Src)
	draw.Draw(viewport, rect, sprites, rect.Min.Add(pixOffset), draw.Over)
	draw.DrawMask(viewport, rect, image.Black, image.ZP, light.Image(-xOffset, -yOffset), rect.Min.Add(light.Origin(-xOffset, -yOffset)).Add(pixOffset), draw.Over)

	if image.Rect(0, 0, 1, 1).Overlaps(rect) {
		mouseTileLock.Lock()
		res.DrawString(viewport, mouseTileString, color.White, res.FontSmall, 1, 1)
		mouseTileLock.Unlock()
	}

	if !hasAnimation.Empty() {
		Invalidate(image.Rectangle{hasAnimation.Min.Mul(1 << res.TileSize), hasAnimation.Max.Mul(1 << res.TileSize)})
	}

	paints++
	/* // For debugging paints
	res.DrawString(viewport, strconv.FormatUint(paints, 10), color.White, res.FontSmall, 300, 1)
	draw.Draw(viewport, image.Rectangle{rect.Min, image.Pt(rect.Max.X+1, rect.Min.Y+1)}, image.White, image.ZP, draw.Src)
	draw.Draw(viewport, image.Rectangle{image.Pt(rect.Min.X-1, rect.Max.Y-1), rect.Max}, image.White, image.ZP, draw.Src)
	draw.Draw(viewport, image.Rectangle{rect.Min, image.Pt(rect.Min.X+1, rect.Max.Y+1)}, image.White, image.ZP, draw.Src)
	draw.Draw(viewport, image.Rectangle{image.Pt(rect.Max.X-1, rect.Min.Y-1), rect.Max}, image.White, image.ZP, draw.Src)
	//*/

	w.Screen().CopyRGBA(viewport, viewport.Bounds())

	w.FlushImage(rect)
}
Example #7
0
func main() {
	flag.Parse()
	b, err := loadFontFile()
	if err != nil {
		log.Fatal(err)
	}
	f, err := truetype.Parse(b)
	if err != nil {
		log.Fatal(err)
	}
	face := truetype.NewFace(f, &truetype.Options{
		Size:    *size,
		Hinting: parseHinting(*hinting),
	})
	defer face.Close()

	fBounds := f.Bounds(fixed.Int26_6(*size * 64))
	iBounds := image.Rect(
		+fBounds.Min.X.Floor(),
		-fBounds.Max.Y.Ceil(),
		+fBounds.Max.X.Ceil(),
		-fBounds.Min.Y.Floor(),
	)

	tBounds := image.Rectangle{}
	glyphs := map[rune]*image.Gray{}
	advance := fixed.Int26_6(-1)

	ranges := loadRanges(f)
	for _, rr := range ranges {
		for r := rr[0]; r < rr[1]; r++ {
			dr, mask, maskp, adv, ok := face.Glyph(fixed.Point26_6{}, r)
			if !ok {
				log.Fatalf("could not load glyph for %U", r)
			}
			if advance < 0 {
				advance = adv
			} else if advance != adv {
				log.Fatalf("advance was not constant: got %v and %v", advance, adv)
			}
			dst := image.NewGray(iBounds)
			draw.DrawMask(dst, dr, image.White, image.Point{}, mask, maskp, draw.Src)
			glyphs[r] = dst
			tBounds = tBounds.Union(tightBounds(dst))
		}
	}

	// height is the glyph image height, not the inter-line spacing.
	width, height := tBounds.Dx(), tBounds.Dy()

	buf := new(bytes.Buffer)
	fmt.Fprintf(buf, "// generated by go generate; DO NOT EDIT.\n\npackage %s\n\n", *pkg)
	fmt.Fprintf(buf, "import (\n\"image\"\n\n\"golang.org/x/image/font/basicfont\"\n)\n\n")
	fmt.Fprintf(buf, "// %s contains %d %d×%d glyphs in %d Pix bytes.\n",
		*vr, len(glyphs), width, height, len(glyphs)*width*height)
	fmt.Fprintf(buf, `var %s = basicfont.Face{
		Advance: %d,
		Width:   %d,
		Height:  %d,
		Ascent:  %d,
		Descent: %d,
		Left: %d,
		Mask: &image.Alpha{
			Stride: %d,
			Rect: image.Rectangle{Max: image.Point{%d, %d*%d}},
			Pix: []byte{
				%s
			},
		},
		Ranges: []basicfont.Range{
			%s
		},
	}`, *vr, advance.Ceil(), width, face.Metrics().Height.Ceil(), -tBounds.Min.Y, +tBounds.Max.Y, tBounds.Min.X,
		width, width, len(glyphs), height,
		printPix(ranges, glyphs, tBounds), printRanges(ranges))

	fmted, err := format.Source(buf.Bytes())
	if err != nil {
		log.Fatalf("format.Source: %v", err)
	}
	if err := ioutil.WriteFile(*vr+".go", fmted, 0644); err != nil {
		log.Fatalf("ioutil.WriteFile: %v", err)
	}
}