hunk.code_window: import ImportThemeModal from '../components/user_settings/import_theme_modal.jsx';
   import InviteMemberModal from '../components/invite_member_modal.jsx';
   import * as AsyncClient from '../utils/async_client.jsx';
   import * as EventHelpers from '../dispatcher/event_helpers.jsx';
  
hunk.labels: keep keep add keep keep keep
hunk.after_edit: import PreferenceStore from '../stores/preference_store.jsx';
   import * as Utils from '../utils/utils.jsx';
  
hunk.file_path: web/react/pages/channel.jsx
hunk.type: add
file: // Copyright 2010 The Freetype-Go Authors. All rights reserved.
  // Use of this source code is governed by your choice of either the
  // FreeType License or the GNU General Public License version 2 (or
  // any later version), both of which can be found in the LICENSE file.
  
  package truetype
  
  import (
  	"golang.org/x/image/font"
  	"golang.org/x/image/math/fixed"
  )
  
  // TODO: implement VerticalHinting.
  
  // A Point is a co-ordinate pair plus whether it is 'on' a contour or an 'off'
  // control point.
  type Point struct {
  	X, Y fixed.Int26_6
  	// The Flags' LSB means whether or not this Point is 'on' the contour.
  	// Other bits are reserved for internal use.
  	Flags uint32
  }
  
  // A GlyphBuf holds a glyph's contours. A GlyphBuf can be re-used to load a
  // series of glyphs from a Font.
  type GlyphBuf struct {
  	// AdvanceWidth is the glyph's advance width.
  	AdvanceWidth fixed.Int26_6
  	// Bounds is the glyph's bounding box.
  	Bounds fixed.Rectangle26_6
  	// Points contains all Points from all contours of the glyph. If hinting
  	// was used to load a glyph then Unhinted contains those Points before they
  	// were hinted, and InFontUnits contains those Points before they were
  	// hinted and scaled.
  	Points, Unhinted, InFontUnits []Point
  	// Ends is the point indexes of the end point of each contour. The length
  	// of Ends is the number of contours in the glyph. The i'th contour
  	// consists of points Points[Ends[i-1]:Ends[i]], where Ends[-1] is
  	// interpreted to mean zero.
  	Ends []int
  
  	font    *Font
  	scale   fixed.Int26_6
  	hinting font.Hinting
  	hinter  hinter
  	// phantomPoints are the co-ordinates of the synthetic phantom points
  	// used for hinting and bounding box calculations.
  	phantomPoints [4]Point
  	// pp1x is the X co-ordinate of the first phantom point. The '1' is
  	// using 1-based indexing; pp1x is almost always phantomPoints[0].X.
  	// TODO: eliminate this and consistently use phantomPoints[0].X.
  	pp1x fixed.Int26_6
  	// metricsSet is whether the glyph's metrics have been set yet. For a
  	// compound glyph, a sub-glyph may override the outer glyph's metrics.
  	metricsSet bool
  	// tmp is a scratch buffer.
  	tmp []Point
  }
  
  // Flags for decoding a glyph's contours. These flags are documented at
  // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html.
  const (
  	flagOnCurve = 1 << iota
  	flagXShortVector
  	flagYShortVector
  	flagRepeat
  	flagPositiveXShortVector
  	flagPositiveYShortVector
  
  	// The remaining flags are for internal use.
  	flagTouchedX
  	flagTouchedY
  )
  
  // The same flag bits (0x10 and 0x20) are overloaded to have two meanings,
  // dependent on the value of the flag{X,Y}ShortVector bits.
  const (
  	flagThisXIsSame = flagPositiveXShortVector
  	flagThisYIsSame = flagPositiveYShortVector
  )
  
  // Load loads a glyph's contours from a Font, overwriting any previously loaded
  // contours for this GlyphBuf. scale is the number of 26.6 fixed point units in
  // 1 em, i is the glyph index, and h is the hinting policy.
  func (g *GlyphBuf) Load(f *Font, scale fixed.Int26_6, i Index, h font.Hinting) error {
  	g.Points = g.Points[:0]
  	g.Unhinted = g.Unhinted[:0]
  	g.InFontUnits = g.InFontUnits[:0]
  	g.Ends = g.Ends[:0]
  	g.font = f
  	g.hinting = h
  	g.scale = scale
  	g.pp1x = 0
  	g.phantomPoints = [4]Point{}
  	g.metricsSet = false
  
  	if h != font.HintingNone {
  		if err := g.hinter.init(f, scale); err != nil {
  			return err
  		}
  	}
  	if err := g.load(0, i, true); err != nil {
  		return err
  	}
  	// TODO: this selection of either g.pp1x or g.phantomPoints[0].X isn't ideal,
  	// and should be cleaned up once we have all the testScaling tests passing,
  	// plus additional tests for Freetype-Go's bounding boxes matching C Freetype's.
  	pp1x := g.pp1x
  	if h != font.HintingNone {
  		pp1x = g.phantomPoints[0].X
  	}
  	if pp1x != 0 {
  		for i := range g.Points {
  			g.Points[i].X -= pp1x
  		}
  	}
  
  	advanceWidth := g.phantomPoints[1].X - g.phantomPoints[0].X
  	if h != font.HintingNone {
  		if len(f.hdmx) >= 8 {
  			if n := u32(f.hdmx, 4); n > 3+uint32(i) {
  				for hdmx := f.hdmx[8:]; uint32(len(hdmx)) >= n; hdmx = hdmx[n:] {
  					if fixed.Int26_6(hdmx[0]) == scale>>6 {
  						advanceWidth = fixed.Int26_6(hdmx[2+i]) << 6
  						break
  					}
  				}
  			}
  		}
  		advanceWidth = (advanceWidth + 32) &^ 63
  	}
  	g.AdvanceWidth = advanceWidth
  
  	// Set g.Bounds to the 'control box', which is the bounding box of the
  	// Bézier curves' control points. This is easier to calculate, no smaller
  	// than and often equal to the tightest possible bounding box of the curves
  	// themselves. This approach is what C Freetype does. We can't just scale
  	// the nominal bounding box in the glyf data as the hinting process and
  	// phantom point adjustment may move points outside of that box.
  	if len(g.Points) == 0 {
  		g.Bounds = fixed.Rectangle26_6{}
  	} else {
  		p := g.Points[0]
  		g.Bounds.Min.X = p.X
  		g.Bounds.Max.X = p.X
  		g.Bounds.Min.Y = p.Y
  		g.Bounds.Max.Y = p.Y
  		for _, p := range g.Points[1:] {
  			if g.Bounds.Min.X > p.X {
  				g.Bounds.Min.X = p.X
  			} else if g.Bounds.Max.X < p.X {
  				g.Bounds.Max.X = p.X
  			}
  			if g.Bounds.Min.Y > p.Y {
  				g.Bounds.Min.Y = p.Y
  			} else if g.Bounds.Max.Y < p.Y {
  				g.Bounds.Max.Y = p.Y
  			}
  		}
  		// Snap the box to the grid, if hinting is on.
  		if h != font.HintingNone {
  			g.Bounds.Min.X &^= 63
  			g.Bounds.Min.Y &^= 63
  			g.Bounds.Max.X += 63
  			g.Bounds.Max.X &^= 63
  			g.Bounds.Max.Y += 63
  			g.Bounds.Max.Y &^= 63
  		}
  	}
  	return nil
  }
  
  func (g *GlyphBuf) load(recursion uint32, i Index, useMyMetrics bool) (err error) {
  	// The recursion limit here is arbitrary, but defends against malformed glyphs.
  	if recursion >= 32 {
  		return UnsupportedError("excessive compound glyph recursion")
  	}
  	// Find the relevant slice of g.font.glyf.
  	var g0, g1 uint32
  	if g.font.locaOffsetFormat == locaOffsetFormatShort {
  		g0 = 2 * uint32(u16(g.font.loca, 2*int(i)))
  		g1 = 2 * uint32(u16(g.font.loca, 2*int(i)+2))
  	} else {
  		g0 = u32(g.font.loca, 4*int(i))
  		g1 = u32(g.font.loca, 4*int(i)+4)
  	}
  
  	// Decode the contour count and nominal bounding box, from the first
  	// 10 bytes of the glyf data. boundsYMin and boundsXMax, at offsets 4
  	// and 6, are unused.
  	glyf, ne, boundsXMin, boundsYMax := []byte(nil), 0, fixed.Int26_6(0), fixed.Int26_6(0)
  	if g0+10 <= g1 {
  		glyf = g.font.glyf[g0:g1]
  		ne = int(int16(u16(glyf, 0)))
  		boundsXMin = fixed.Int26_6(int16(u16(glyf, 2)))
  		boundsYMax = fixed.Int26_6(int16(u16(glyf, 8)))
  	}
  
  	// Create the phantom points.
  	uhm, pp1x := g.font.unscaledHMetric(i), fixed.Int26_6(0)
  	uvm := g.font.unscaledVMetric(i, boundsYMax)
  	g.phantomPoints = [4]Point{
  		{X: boundsXMin - uhm.LeftSideBearing},
  		{X: boundsXMin - uhm.LeftSideBearing + uhm.AdvanceWidth},
  		{X: uhm.AdvanceWidth / 2, Y: boundsYMax + uvm.TopSideBearing},
  		{X: uhm.AdvanceWidth / 2, Y: boundsYMax + uvm.TopSideBearing - uvm.AdvanceHeight},
  	}
  	if len(glyf) == 0 {
  		g.addPhantomsAndScale(len(g.Points), len(g.Points), true, true)
  		copy(g.phantomPoints[:], g.Points[len(g.Points)-4:])
  		g.Points = g.Points[:len(g.Points)-4]
  		return nil
  	}
  
  	// Load and hint the contours.
  	if ne < 0 {
  		if ne != -1 {
  			// http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html says that
  			// "the values -2, -3, and so forth, are reserved for future use."
  			return UnsupportedError("negative number of contours")
  		}
  		pp1x = g.font.scale(g.scale * (boundsXMin - uhm.LeftSideBearing))
  		if err := g.loadCompound(recursion, uhm, i, glyf, useMyMetrics); err != nil {
  			return err
  		}
  	} else {
  		np0, ne0 := len(g.Points), len(g.Ends)
  		program := g.loadSimple(glyf, ne)
  		g.addPhantomsAndScale(np0, np0, true, true)
  		pp1x = g.Points[len(g.Points)-4].X
  		if g.hinting != font.HintingNone {
  			if len(program) != 0 {
  				err := g.hinter.run(
  					program,
  					g.Points[np0:],
  					g.Unhinted[np0:],
  					g.InFontUnits[np0:],
  					g.Ends[ne0:],
  				)
  				if err != nil {
  					return err
  				}
  			}
  			// Drop the four phantom points.
  			g.InFontUnits = g.InFontUnits[:len(g.InFontUnits)-4]
  			g.Unhinted = g.Unhinted[:len(g.Unhinted)-4]
  		}
  		if useMyMetrics {
  			copy(g.phantomPoints[:], g.Points[len(g.Points)-4:])
  		}
  		g.Points = g.Points[:len(g.Points)-4]
  		if np0 != 0 {
  			// The hinting program expects the []Ends values to be indexed
  			// relative to the inner glyph, not the outer glyph, so we delay
  			// adding np0 until after the hinting program (if any) has run.
  			for i := ne0; i < len(g.Ends); i++ {
  				g.Ends[i] += np0
  			}
  		}
  	}
  	if useMyMetrics && !g.metricsSet {
  		g.metricsSet = true
  		g.pp1x = pp1x
  	}
  	return nil
  }
  
  // loadOffset is the initial offset for loadSimple and loadCompound. The first
  // 10 bytes are the number of contours and the bounding box.
  const loadOffset = 10
  
  func (g *GlyphBuf) loadSimple(glyf []byte, ne int) (program []byte) {
  	offset := loadOffset
  	for i := 0; i < ne; i++ {
  		g.Ends = append(g.Ends, 1+int(u16(glyf, offset)))
  		offset += 2
  	}
  
  	// Note the TrueType hinting instructions.
  	instrLen := int(u16(glyf, offset))
  	offset += 2
  	program = glyf[offset : offset+instrLen]
  	offset += instrLen
  
  	np0 := len(g.Points)
  	np1 := np0 + int(g.Ends[len(g.Ends)-1])
  
  	// Decode the flags.
  	for i := np0; i < np1; {
  		c := uint32(glyf[offset])
  		offset++
  		g.Points = append(g.Points, Point{Flags: c})
  		i++
  		if c&flagRepeat != 0 {
  			count := glyf[offset]
  			offset++
  			for ; count > 0; count-- {
  				g.Points = append(g.Points, Point{Flags: c})
  				i++
  			}
  		}
  	}
  
  	// Decode the co-ordinates.
  	var x int16
  	for i := np0; i < np1; i++ {
  		f := g.Points[i].Flags
  		if f&flagXShortVector != 0 {
  			dx := int16(glyf[offset])
  			offset++
  			if f&flagPositiveXShortVector == 0 {
  				x -= dx
  			} else {
  				x += dx
  			}
  		} else if f&flagThisXIsSame == 0 {
  			x += int16(u16(glyf, offset))
  			offset += 2
  		}
  		g.Points[i].X = fixed.Int26_6(x)
  	}
  	var y int16
  	for i := np0; i < np1; i++ {
  		f := g.Points[i].Flags
  		if f&flagYShortVector != 0 {
  			dy := int16(glyf[offset])
  			offset++
  			if f&flagPositiveYShortVector == 0 {
  				y -= dy
  			} else {
  				y += dy
  			}
  		} else if f&flagThisYIsSame == 0 {
  			y += int16(u16(glyf, offset))
  			offset += 2
  		}
  		g.Points[i].Y = fixed.Int26_6(y)
  	}
  
  	return program
  }
  
  func (g *GlyphBuf) loadCompound(recursion uint32, uhm HMetric, i Index,
  	glyf []byte, useMyMetrics bool) error {
  
  	// Flags for decoding a compound glyph. These flags are documented at
  	// http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html.
  	const (
  		flagArg1And2AreWords = 1 << iota
  		flagArgsAreXYValues
  		flagRoundXYToGrid
  		flagWeHaveAScale
  		flagUnused
  		flagMoreComponents
  		flagWeHaveAnXAndYScale
  		flagWeHaveATwoByTwo
  		flagWeHaveInstructions
  		flagUseMyMetrics
  		flagOverlapCompound
  	)
  	np0, ne0 := len(g.Points), len(g.Ends)
  	offset := loadOffset
  	for {
  		flags := u16(glyf, offset)
  		component := Index(u16(glyf, offset+2))
  		dx, dy, transform, hasTransform := fixed.Int26_6(0), fixed.Int26_6(0), [4]int16{}, false
  		if flags&flagArg1And2AreWords != 0 {
  			dx = fixed.Int26_6(int16(u16(glyf, offset+4)))
  			dy = fixed.Int26_6(int16(u16(glyf, offset+6)))
  			offset += 8
  		} else {
  			dx = fixed.Int26_6(int16(int8(glyf[offset+4])))
  			dy = fixed.Int26_6(int16(int8(glyf[offset+5])))
  			offset += 6
  		}
  		if flags&flagArgsAreXYValues == 0 {
  			return UnsupportedError("compound glyph transform vector")
  		}
  		if flags&(flagWeHaveAScale|flagWeHaveAnXAndYScale|flagWeHaveATwoByTwo) != 0 {
  			hasTransform = true
  			switch {
  			case flags&flagWeHaveAScale != 0:
  				transform[0] = int16(u16(glyf, offset+0))
  				transform[3] = transform[0]
  				offset += 2
  			case flags&flagWeHaveAnXAndYScale != 0:
  				transform[0] = int16(u16(glyf, offset+0))
  				transform[3] = int16(u16(glyf, offset+2))
  				offset += 4
  			case flags&flagWeHaveATwoByTwo != 0:
  				transform[0] = int16(u16(glyf, offset+0))
  				transform[1] = int16(u16(glyf, offset+2))
  				transform[2] = int16(u16(glyf, offset+4))
  				transform[3] = int16(u16(glyf, offset+6))
  				offset += 8
  			}
  		}
  		savedPP := g.phantomPoints
  		np0 := len(g.Points)
  		componentUMM := useMyMetrics && (flags&flagUseMyMetrics != 0)
  		if err := g.load(recursion+1, component, componentUMM); err != nil {
  			return err
  		}
  		if flags&flagUseMyMetrics == 0 {
  			g.phantomPoints = savedPP
  		}
  		if hasTransform {
  			for j := np0; j < len(g.Points); j++ {
  				p := &g.Points[j]
  				newX := 0 +
  					fixed.Int26_6((int64(p.X)*int64(transform[0])+1<<13)>>14) +
  					fixed.Int26_6((int64(p.Y)*int64(transform[2])+1<<13)>>14)
  				newY := 0 +
  					fixed.Int26_6((int64(p.X)*int64(transform[1])+1<<13)>>14) +
  					fixed.Int26_6((int64(p.Y)*int64(transform[3])+1<<13)>>14)
  				p.X, p.Y = newX, newY
  			}
  		}
  		dx = g.font.scale(g.scale * dx)
  		dy = g.font.scale(g.scale * dy)
  		if flags&flagRoundXYToGrid != 0 {
  			dx = (dx + 32) &^ 63
  			dy = (dy + 32) &^ 63
  		}
  		for j := np0; j < len(g.Points); j++ {
  			p := &g.Points[j]
  			p.X += dx
  			p.Y += dy
  		}
  		// TODO: also adjust g.InFontUnits and g.Unhinted?
  		if flags&flagMoreComponents == 0 {
  			break
  		}
  	}
  
  	instrLen := 0
  	if g.hinting != font.HintingNone && offset+2 <= len(glyf) {
  		instrLen = int(u16(glyf, offset))
  		offset += 2
  	}
  
  	g.addPhantomsAndScale(np0, len(g.Points), false, instrLen > 0)
  	points, ends := g.Points[np0:], g.Ends[ne0:]
  	g.Points = g.Points[:len(g.Points)-4]
  	for j := range points {
  		points[j].Flags &^= flagTouchedX | flagTouchedY
  	}
  
  	if instrLen == 0 {
  		if !g.metricsSet {
  			copy(g.phantomPoints[:], points[len(points)-4:])
  		}
  		return nil
  	}
  
  	// Hint the compound glyph.
  	program := glyf[offset : offset+instrLen]
  	// Temporarily adjust the ends to be relative to this compound glyph.
  	if np0 != 0 {
  		for i := range ends {
  			ends[i] -= np0
  		}
  	}
  	// Hinting instructions of a composite glyph completely refer to the
  	// (already) hinted subglyphs.
  	g.tmp = append(g.tmp[:0], points...)
  	if err := g.hinter.run(program, points, g.tmp, g.tmp, ends); err != nil {
  		return err
  	}
  	if np0 != 0 {
  		for i := range ends {
  			ends[i] += np0
  		}
  	}
  	if !g.metricsSet {
  		copy(g.phantomPoints[:], points[len(points)-4:])
  	}
  	return nil
  }
  
  func (g *GlyphBuf) addPhantomsAndScale(np0, np1 int, simple, adjust bool) {
  	// Add the four phantom points.
  	g.Points = append(g.Points, g.phantomPoints[:]...)
  	// Scale the points.
  	if simple && g.hinting != font.HintingNone {
  		g.InFontUnits = append(g.InFontUnits, g.Points[np1:]...)
  	}
  	for i := np1; i < len(g.Points); i++ {
  		p := &g.Points[i]
  		p.X = g.font.scale(g.scale * p.X)
  		p.Y = g.font.scale(g.scale * p.Y)
  	}
  	if g.hinting == font.HintingNone {
  		return
  	}
  	// Round the 1st phantom point to the grid, shifting all other points equally.
  	// Note that "all other points" starts from np0, not np1.
  	// TODO: delete this adjustment and the np0/np1 distinction, when
  	// we update the compatibility tests to C Freetype 2.5.3.
  	// See http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=05c786d990390a7ca18e62962641dac740bacb06
  	if adjust {
  		pp1x := g.Points[len(g.Points)-4].X
  		if dx := ((pp1x + 32) &^ 63) - pp1x; dx != 0 {
  			for i := np0; i < len(g.Points); i++ {
  				g.Points[i].X += dx
  			}
  		}
  	}
  	if simple {
  		g.Unhinted = append(g.Unhinted, g.Points[np1:]...)
  	}
  	// Round the 2nd and 4th phantom point to the grid.
  	p := &g.Points[len(g.Points)-3]
  	p.X = (p.X + 32) &^ 63
  	p = &g.Points[len(g.Points)-1]
  	p.Y = (p.Y + 32) &^ 63
  }
  