예제 #1
0
func (self *face) Glyph(dot fixed.Point26_6, char rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
	var bounds fixed.Rectangle26_6
	var cached bool
	var cachedGlyph glyph

	if cachedGlyph, cached = self.cache.get(char); cached {
		bounds, advance, mask = cachedGlyph.bounds, cachedGlyph.advance, cachedGlyph.mask
	}

	if bounds == (fixed.Rectangle26_6{}) || advance == 0 {
		if bounds, advance, ok = self.GlyphBounds(char); !ok {
			return
		}
	}

	offset := fixed.Point26_6{
		X: abs26_6(bounds.Min.X),
		Y: self.metrics.Ascent,
	}

	origin := C.CGPoint{
		x: C.CGFloat(f64(offset.X)),
		y: C.CGFloat(f64(offset.Y)),
	}

	dx := (int(bounds.Max.X+offset.X) >> 6) + 1
	dy := (int(self.metrics.Ascent+self.metrics.Descent) >> 6) + 1

	dr.Min.X = (int(dot.X) >> 6) - int(origin.x)
	dr.Min.Y = (int(dot.Y) >> 6) - int(origin.y)
	dr.Max.X = dr.Min.X + dx
	dr.Max.Y = dr.Min.Y + dy

	if mask == nil {
		alpha := image.NewAlpha(image.Rect(0, 0, dx, dy))

		if !C.CTFontGlyphDraw__(
			self.ref,
			C.UTF32Char(char),
			origin,
			(*C.UInt8)(unsafe.Pointer(&alpha.Pix[0])),
			C.size_t(alpha.Stride),
			C.size_t(dx),
			C.size_t(dy),
		) {
			dr, advance = image.Rectangle{}, 0
			return
		}

		mask = alpha
		self.cache.set(glyph{rune: char, bounds: bounds, advance: advance, mask: mask})
	}

	ok = true
	return
}
예제 #2
0
func makeLineDash(in graphic.LineDash) []C.CGFloat {
	out := make([]C.CGFloat, len(in))

	for i, d := range in {
		out[i] = C.CGFloat(d)
	}

	return out
}
예제 #3
0
func makeCGPathElementPoints(p [3]geom.Point) [3]C.CGPoint {
	return [3]C.CGPoint{
		C.CGPoint{
			x: C.CGFloat(p[0].X),
			y: C.CGFloat(p[0].Y),
		},
		C.CGPoint{
			x: C.CGFloat(p[1].X),
			y: C.CGFloat(p[1].Y),
		},
		C.CGPoint{
			x: C.CGFloat(p[2].X),
			y: C.CGFloat(p[2].Y),
		},
	}
}
예제 #4
0
func (m CGPoint) C() C.CGPoint {
	return C.CGPoint{C.CGFloat(m.x), C.CGFloat(m.y)}
}
예제 #5
0
func moveWindow(id uintptr, p geom.Point) {
	C.DesktopWindow_Move(unsafe.Pointer(id), C.CGFloat(p.X), C.CGFloat(p.Y))
}
예제 #6
0
func makeCGSize(s geom.Size) C.CGSize {
	return C.CGSize{
		width:  C.CGFloat(s.W),
		height: C.CGFloat(s.H),
	}
}
예제 #7
0
func makeCGPoint(p geom.Point) C.CGPoint {
	return C.CGPoint{
		x: C.CGFloat(p.X),
		y: C.CGFloat(p.Y),
	}
}
예제 #8
0
func (self gc) Configure(state graphic.State) {
	var s C.CGState__
	var d []C.CGFloat
	var p []C.CGPathElement__

	if state.Color != nil {
		r, g, b, a := state.Color.RGBA()
		s.flags |= C.CGStateHasColor__
		s.color[0] = C.CGFloat(r) / 65535
		s.color[1] = C.CGFloat(g) / 65535
		s.color[2] = C.CGFloat(b) / 65535
		s.color[3] = C.CGFloat(a) / 65535
	}

	if state.Transform != nil {
		tm := state.Transform.TM()
		s.flags |= C.CGStateHasTransform__
		s.transform[0] = C.CGFloat(tm[0])
		s.transform[1] = C.CGFloat(tm[1])
		s.transform[2] = C.CGFloat(tm[2])
		s.transform[3] = C.CGFloat(tm[3])
		s.transform[4] = C.CGFloat(tm[4])
		s.transform[5] = C.CGFloat(tm[5])
	}

	if state.Opacity != nil {
		s.flags |= C.CGStateHasAlpha__
		s.alpha = C.CGFloat(state.Opacity.Opacity())
	}

	if state.Interpolation != nil {
		s.flags |= C.CGStateHasInterpolation__

		switch state.Interpolation.Interpolation() {
		case graphic.InterpolationDefault:
			s.interpolation = C.kCGInterpolationDefault

		case graphic.InterpolationNone:
			s.interpolation = C.kCGInterpolationNone

		case graphic.InterpolationCheap:
			s.interpolation = C.kCGInterpolationLow

		case graphic.InterpolationAverage:
			s.interpolation = C.kCGInterpolationMedium

		case graphic.InterpolationExpensive:
			s.interpolation = C.kCGInterpolationHigh
		}
	}

	if state.LineCap != nil {
		s.flags |= C.CGStateHasLineCap__

		switch state.LineCap.LineCap() {
		case graphic.LineCapButt:
			s.lineCap = C.kCGLineCapButt

		case graphic.LineCapSquare:
			s.lineCap = C.kCGLineCapRound

		case graphic.LineCapRound:
			s.lineCap = C.kCGLineCapSquare
		}
	}

	if state.LineJoin != nil {
		s.flags |= C.CGStateHasLineJoin__

		switch state.LineJoin.LineJoin() {
		case graphic.LineJoinMiter:
			s.lineJoin = C.kCGLineJoinMiter

		case graphic.LineJoinRound:
			s.lineJoin = C.kCGLineJoinRound

		case graphic.LineJoinBevel:
			s.lineJoin = C.kCGLineJoinBevel
		}
	}

	if state.LineWidth != nil {
		s.flags |= C.CGStateHasLineWidth__
		s.lineWidth = C.CGFloat(state.LineWidth.LineWidth())
	}

	if state.LineDash != nil {
		d = makeLineDash(state.LineDash.LineDash())
	}

	if state.Clip != nil {
		p = makeCGPathElements__(state.Clip.Path())

		switch state.ClipRule {
		case graphic.ClipWindingCount:
			s.clipRule = C.CGClipWindingCount__

		case graphic.ClipEvenOdd:
			s.clipRule = C.CGClipEvenOdd__
		}
	}

	self <- func(ctx C.CGContextRef) {
		if n := len(p); n != 0 {
			s.flags |= C.CGStateHasClip__
			s.clipElements = &p[0]
			s.clipLength = C.size_t(n)
		}

		if n := len(d); n != 0 {
			s.flags |= C.CGStateHasLineDash__
			s.lineDashLengths = &d[0]
			s.lineDashCount = C.size_t(n)
		}

		if s.flags != 0 {
			C.CGContextConfigure__(ctx, s)
		}
	}
}
예제 #9
0
func makeRGBA__(c color.Color) C.RGBA__ {
	switch x := c.(type) {
	case color.NRGBA:
		return C.RGBA__{
			R: C.CGFloat(x.R) / 255.0,
			G: C.CGFloat(x.G) / 255.0,
			B: C.CGFloat(x.B) / 255.0,
			A: C.CGFloat(x.A) / 255.0,
		}

	case color.NRGBA64:
		return C.RGBA__{
			R: C.CGFloat(x.R) / 65535.0,
			G: C.CGFloat(x.G) / 65535.0,
			B: C.CGFloat(x.B) / 65535.0,
			A: C.CGFloat(x.A) / 65535.0,
		}
	}

	r, g, b, a := c.RGBA()

	fr := C.CGFloat(r) / 65535.0
	fg := C.CGFloat(g) / 65535.0
	fb := C.CGFloat(b) / 65535.0
	fa := C.CGFloat(a) / 65535.0

	if fa != 0.0 {
		fr /= fa
		fg /= fa
		fb /= fa
	}

	// The RGBA method gives us pre-multiplied values, but the generic RGB color
	// constructor expects values between 0 and 1 so we have to convert them
	// back to non-multiplied.
	return C.RGBA__{R: fr, G: fg, B: fb, A: fa}
}
예제 #10
0
func newFace(ctfont C.CTFontRef, data text.FaceData) *face {
	if data.Size == 0.0 {
		data.Size = 12.0
	}

	if data.DPI == 0.0 {
		data.DPI = 72.0
	}

	if data.Stretch == 0 {
		data.Stretch = font.StretchNormal
	}

	if data.Style == 0 {
		data.Style = font.StyleNormal
	}

	if data.Weight == 0 {
		data.Weight = font.WeightNormal
	}

	data.Hinting = font.HintingNone

	scale := C.CGFloat(data.DPI / 72.0)
	traits := C.CTFontSymbolicTraits(C.kCTFontUIOptimizedTrait)

	switch data.Stretch {
	case font.StretchUltraCondensed, font.StretchExtraCondensed, font.StretchCondensed, font.StretchSemiCondensed:
		data.Stretch = font.StretchCondensed
		traits |= C.kCTFontCondensedTrait

	case font.StretchSemiExpanded, font.StretchExpanded, font.StretchExtraExpanded, font.StretchUltraExpanded:
		data.Stretch = font.StretchExpanded
		traits |= C.kCTFontExpandedTrait
	}

	switch data.Style {
	case font.StyleItalic, font.StyleOblique:
		data.Style = font.StyleItalic
		traits |= C.kCTFontItalicTrait
	}

	switch data.Weight {
	case font.WeightMedium, font.WeightSemiBold, font.WeightBold, font.WeightExtraBold, font.WeightBlack:
		data.Weight = font.WeightBold
		traits |= C.kCTFontBoldTrait
	}

	tm := C.CGAffineTransform{a: scale, d: scale}
	ref := C.CTFontCreateCopyWithSymbolicTraits(
		ctfont,
		C.CGFloat(data.Size),
		&tm,
		traits,
		C.kCTFontItalicTrait|C.kCTFontBoldTrait|C.kCTFontExpandedTrait|C.kCTFontCondensedTrait|C.kCTFontUIOptimizedTrait,
	)

	if ref == nil {
		// The request couldn't be satisfied, no font in the system were found
		// that matched the face configuration.
		// We create a simple copy of the font without changing the symbolic
		// traits.
		ref = C.CTFontCreateCopyWithSymbolicTraits(
			ctfont,
			C.CGFloat(data.Size),
			&tm,
			0,
			0,
		)

		if ref == nil {
			panic(fmt.Sprintf("CoreText failed to create a CTFontRef for %#v", data))
		}
	}

	self := &face{
		ref:  ref,
		data: data,
	}

	runtime.SetFinalizer(self, (*face).release)

	self.metrics.Ascent = i26_6(C.CTFontGetAscent(ref))
	self.metrics.Descent = i26_6(C.CTFontGetDescent(ref))
	self.metrics.Height = self.metrics.Ascent + self.metrics.Descent + i26_6(C.CTFontGetLeading(ref))

	name := C.CTFontCopyFullName(ref)
	defer C.CFRelease(C.CFTypeRef(name))

	self.name = CFStringToGoString(name)
	self.cache.index = make(map[rune]int, glyphCacheSize)
	return self
}
예제 #11
0
func (m CGSize) C() C.CGSize {
	return C.CGSize{C.CGFloat(m.width), C.CGFloat(m.height)}
}
예제 #12
0
func CGColorRGB(r, g, b, a int) CGColor {
	return CGColor{unsafe.Pointer(C.CGColorCreateGenericRGB(C.CGFloat(r), C.CGFloat(g), C.CGFloat(b), C.CGFloat(a)))}
}
예제 #13
0
func (point Size) innerType() C.NSSize {
	return C.NSSize{
		width:  C.CGFloat(point.Width),
		height: C.CGFloat(point.Height),
	}
}
예제 #14
0
func (point Point) innerType() C.NSPoint {
	return C.NSPoint{
		x: C.CGFloat(point.X),
		y: C.CGFloat(point.Y),
	}
}