func loadFont(path string) (*truetype.Font, error) { file, err := ioutil.ReadFile(path) if err != nil { return nil, err } return truetype.Parse(file) }
func main() { flag.Parse() fmt.Printf("Loading fontfile %q\n", *fontfile) b, err := ioutil.ReadFile(*fontfile) if err != nil { log.Println(err) return } font, err := truetype.Parse(b) if err != nil { log.Println(err) return } fupe := font.FUnitsPerEm() printBounds(font.Bounds(fupe)) fmt.Printf("FUnitsPerEm:%d\n\n", fupe) c0, c1 := 'A', 'V' i0 := font.Index(c0) hm := font.HMetric(fupe, i0) g := truetype.NewGlyphBuf() err = g.Load(font, fupe, i0, nil) if err != nil { log.Println(err) return } fmt.Printf("'%c' glyph\n", c0) fmt.Printf("AdvanceWidth:%d LeftSideBearing:%d\n", hm.AdvanceWidth, hm.LeftSideBearing) printGlyph(g) i1 := font.Index(c1) fmt.Printf("\n'%c', '%c' Kerning:%d\n", c0, c1, font.Kerning(fupe, i0, i1)) }
func getFont(path string, sizePts int) font { sizePx := int(float64(sizePts)/ptInch*pxInch + 0.5) if f, ok := fonts[path]; ok { f.size = sizePx return f } in, err := os.Open(path) if err != nil { panic(err) } defer in.Close() fdata, err := ioutil.ReadAll(in) if err != nil { panic(err) } f := font{ path: path, Context: freetype.NewContext(), } if f.Font, err = truetype.Parse(fdata); err != nil { panic(err) } f.SetFont(f.Font) f.SetDPI(pxInch) fonts[path] = f f.size = sizePx return f }
/* 生成验证码 bg:背景色 fg:前景色 length:字符长度 width:宽度 height:高度 size:字体大小 fontPath:字体文件路径 */ func GenerateCaptcha(bg, fg *image.Uniform, length int, width int, height int, size float64, fontPath string) *Captcha { fontBytes, err := ioutil.ReadFile(fontPath) if err != nil { panic(err) } font, err := truetype.Parse(fontBytes) if err != nil { panic(err) } cap := &Captcha{} cap.Text = randString(length) cap.Image = image.NewRGBA(image.Rect(0, 0, width, height)) draw.Draw(cap.Image, cap.Image.Bounds(), bg, image.ZP, draw.Src) c := freetype.NewContext() c.SetFont(font) c.SetFontSize(size) c.SetClip(cap.Image.Bounds()) c.SetDst(cap.Image) c.SetSrc(fg) pt := freetype.Pt(0, int(c.PointToFix32(size)>>8)) for _, s := range cap.Text { _, err = c.DrawString(string(s), pt) if err != nil { panic(err) return nil } pt.X += c.PointToFix32(size * 0.5) } return cap }
// LoadFont loads the given truetype font file data and returns a new // *TruetypeFont. For easier loading, consider using LoadTTFFile instead. This // method is simply short-hand for: // tt, err := truetype.Parse(data) // if err != nil { // return nil, err // } // return &TruetypeFont{ // Font: tt, // } func LoadFont(data []byte) (*TruetypeFont, error) { f, err := truetype.Parse(data) if err != nil { return nil, err } return &TruetypeFont{ Font: f, }, nil }
func init() { font, err := truetype.Parse(luxisr_ttf()) if err != nil { // TODO: log error println("error!") println(err.Error()) } draw2d.RegisterFont(DefaultFontData, font) }
func LoadFont(path string) (*truetype.Font, error) { bs, err := ioutil.ReadFile(path) // quick debug if err != nil { fmt.Println(err) } f, err := truetype.Parse(bs) return f, err }
func loadFont(fontFileName string) *truetype.Font { fontBytes, err := ioutil.ReadFile(path.Join(fontFolder, fontFileName)) if err != nil { log.Println(err) return nil } font, err := truetype.Parse(fontBytes) if err != nil { log.Println(err) return nil } return font }
//AddFont will add a new font file to the list func (fm *FontManager) AddFont(pathToFontFile string) error { fontBytes, err := ioutil.ReadFile(pathToFontFile) if err != nil { return err } font, err := truetype.Parse(fontBytes) if err != nil { return err } fm.fontFiles = append(fm.fontFiles, pathToFontFile) fm.fontObjects[pathToFontFile] = font return nil }
func loadFont() (*truetype.Font, error) { f, err := os.Open(filepath.Join(datadir, "fonts", "luxisr.ttf")) if err != nil { return nil, err } data, err := ioutil.ReadAll(f) f.Close() if err != nil { return nil, err } font, err := truetype.Parse(data) if err != nil { return nil, err } return font, nil }
func defaultFont() *truetype.Font { goroot := os.Getenv("GOROOT") if goroot == "" { log.Fatal("no goroot set") } path := goroot + "/src/pkg/freetype-go.googlecode.com/hg/luxi-fonts/luxisr.ttf" // Read the font data. fontBytes, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } font, err := truetype.Parse(fontBytes) if err != nil { log.Fatal(err) } return font }
func analyzeFont(ttfFile string) SortedGS { defer trackTime(time.Now(), "analyze_font") f, err := ioutil.ReadFile(ttfFile) if err != nil { log.Fatal(err) } font, err := truetype.Parse(f) if err != nil { log.Fatal(err) } a := make(SortedGS, len(*alphabet)) for i, char := range *alphabet { rgba := getRGBA(string(char), font) nbp := getNumBlackPixels(rgba) a[i] = &Artifact{string(char), nbp, nbp} } a.Normalize() sort.Sort(a) a = removeDuplicates(a) //saveCharacterMap(a) return a }
func testFontFile(fontfile string) (*truetype.Font, error) { fontfile = LocateFont(fontfile) fmt.Printf("Testing fontfile %q\n", fontfile) b, err := ioutil.ReadFile(fontfile) if err != nil { return nil, err } font, err := truetype.Parse(b) if err != nil { return nil, err } fupe := font.FUnitsPerEm() printBounds(font.Bounds(font.FUnitsPerEm())) fmt.Printf("FUnitsPerEm:%d\n\n", fupe) // printGlyph(font, 'A', fupe) printGlyph(font, 'V', fupe) // printGlyph(font, 'a', fupe) // printGlyph(font, 'v', fupe) return font, nil }
func newFont(data []byte, size int) (*font, error) { ttf, err := truetype.Parse(data) if err != nil { return nil, err } scale := int32(size << 6) bounds := ttf.Bounds(scale) glyphMaxSizeDips := math.Size{ W: int(bounds.XMax-bounds.XMin) >> 6, H: int(bounds.YMax-bounds.YMin) >> 6, } ascentDips := int(bounds.YMax >> 6) return &font{ size: size, scale: scale, glyphMaxSizeDips: glyphMaxSizeDips, ascentDips: ascentDips, ttf: ttf, resolutions: make(map[resolution]*glyphTable), glyphs: make(map[rune]*glyph), }, nil }
// ParseFont just calls the Parse function from the freetype/truetype package. // It is provided here so that code that imports this package doesn't need // to also include the freetype/truetype package. func ParseFont(b []byte) (*truetype.Font, error) { return truetype.Parse(b) }
func main() { b, _ := ioutil.ReadFile("./roboto/roboto-light.ttf") font, ferr := tt.Parse(b) if ferr != nil { fmt.Println("can't parse font %v , len %v", ferr.Error(), len(b)) } fc := ft.NewContext() fc.SetFont(font) glfw.SetErrorCallback(errorCallback) if !glfw.Init() { panic("Can't init glfw!") } defer glfw.Terminate() window, err := glfw.CreateWindow(800, 600, "Testing", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() gl.Init() program := gl.CreateProgram() vertexShader := gl.CreateShader(gl.VERTEX_SHADER) vertexShader.Source(` attribute vec4 a_position; attribute vec2 a_coord; varying vec2 v_coord; void main() { gl_Position = a_position; v_coord = a_coord; } `) vertexShader.Compile() fmt.Printf("vertex: %v\n", vertexShader.GetInfoLog()) fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER) fragmentShader.Source(` varying vec2 v_coord; uniform sampler2D s_picture; uniform vec4 color; uniform bool has_picture; void main() { if(has_picture) { gl_FragColor = texture2D(s_picture, v_coord); } else { gl_FragColor = color; } } `) fragmentShader.Compile() fmt.Printf("fragment %v \n", fragmentShader.GetInfoLog()) program.AttachShader(vertexShader) program.AttachShader(fragmentShader) program.Link() // ini //gl.MatrixMode(gl.PROJECTION) //gl.Ortho(0, 640, 0, 480, 0, 1) gl.ClearColor(0.5, 0.5, 0.5, 0.0) root := widget.Widget{ Name: "Red", Rect: image.Rect(0, 0, 800, 600), Background: color.RGBA{255, 128, 128, 126}, OnClick: widget.ClickInner, OnDrag: widget.DragInner, OnHover: widget.HoverInner, OnResize: widget.ResizeItself, } blue := root.AddWidget(&widget.Widget{ Name: "Blue", Rect: image.Rect(100, 100, 200, 200), Image: LoadImage("./test.png"), Background: color.RGBA{128, 128, 255, 126}, OnClick: func(w *widget.Widget, p image.Point) { root.SetTop(w) fmt.Println("Clicked blue box") widget.ClickInner(w, p) }, OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool { widget.DragInner(w, p, d) widget.DragItself(w, p, d) return true }, OnResize: widget.ResizeItself, }) blue.AddWidget(&widget.Widget{ Name: "White", Rect: image.Rect(90, 90, 100, 100), Background: color.RGBA{250, 250, 250, 250}, OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool { widget.DragItself(w, p, d) blue.Resize(d) return true }, }) root.AddWidget(&widget.Widget{ Name: "Green", Rect: image.Rect(100, 300, 200, 400), Background: color.RGBA{128, 255, 128, 126}, OnClick: func(w *widget.Widget, p image.Point) { root.SetTop(w) w.Image = LoadImage("./test2.png") }, OnDrag: widget.DragItself, }) root.AddWidget(&widget.Widget{ Name: "Black", Rect: image.Rect(100, 400, 150, 450), Background: color.RGBA{0, 0, 0, 126}, OnHover: func(w *widget.Widget, p0 image.Point, p1 image.Point) { if p1.In(w.Rect) { w.Background = color.RGBA{255, 255, 255, 126} } else { w.Background = color.RGBA{0, 0, 0, 126} } }, }) white := root.AddWidget(&widget.Widget{ Name: "White", Text: "Меня зовут Светлана, я из города Иваново. «Единая Россия» очень много сделала достижений: они подняли экономик… экономику, мы стали более лучшие… одеваться, и не было того что щас — это очень большие достижения! В сельском хозяйстве очень хорошо. (Гладин: Что именно в сельском хозяйстве они сделали?) Стало больше… земель за-а… много, ну… я не знаю даже как сказать… засеивать больше земель… а-а-а вот, овощи там, рожь — вот это всё. Что еще сказать… Так как у нас страна многонациональная, у нас в Москве очень много людей, которые очень помогают нам… с других городов… (вопрос Гладина: Вы считаете это достижение «Единой России»?) Да, это большое достижение! Очень хорошее даже! Видите ну… да… Видите ну у нас в Иванове очень хорошая стала медицина… а…что ещё… благоустройство в городах хорошее… с жильём… никаких проблем. Люди подмогают очень хорошо", Rect: image.Rect(400, 200, 700, 500), Foreground: color.RGBA{0, 0, 0, 0}, Background: color.RGBA{255, 255, 255, 126}, OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool { root.SetTop(w) widget.DragInner(w, p, d) widget.DragItself(w, p, d) return true }, OnResize: widget.ResizeItself, Padding: image.Rect(20, 20, 20, 20), }) white.AddWidget(&widget.Widget{ Name: "White", Rect: image.Rect(290, 290, 300, 300), Background: color.RGBA{0, 0, 0, 250}, OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool { widget.DragItself(w, p, d) white.Resize(d) return true }, }) x0 := 0.0 y0 := 0.0 window.SetMouseButtonCallback(func(w *glfw.Window, but glfw.MouseButton, act glfw.Action, key glfw.ModifierKey) { xpos, ypos := w.GetCursorPosition() if act == glfw.Press { root.Click(image.Point{X: int(xpos), Y: int(ypos)}) x0, y0 = xpos, ypos } }) window.SetCursorPositionCallback(func(w *glfw.Window, xpos float64, ypos float64) { root.Hover(image.Point{X: int(x0), Y: int(y0)}, image.Point{X: int(xpos), Y: int(ypos)}) if w.GetMouseButton(glfw.MouseButtonLeft) == glfw.Press { root.Drag(image.Point{X: int(x0), Y: int(y0)}, image.Point{X: int(xpos - x0), Y: int(ypos - y0)}) x0, y0 = xpos, ypos } x0, y0 = xpos, ypos }) width0, height0 := window.GetSize() window.SetSizeCallback(func(w *glfw.Window, width int, height int) { gl.Viewport(0, 0, width, height) root.Rect.Max = image.Point{width, height} width0, height0 = width, height }) /*switch(color_type){ case PNG_COLOR_TYPE_GRAY: return GL_LUMINANCE; case PNG_COLOR_TYPE_GRAY_ALPHA: return GL_LUMINANCE_ALPHA; case PNG_COLOR_TYPE_RGB: return GL_RGB; case PNG_COLOR_TYPE_RGB_ALPHA: return GL_RGBA; */ /* here init texture pool texturePool := make([widget.Widget]texture) */ for !window.ShouldClose() { //Do OpenGL stuff program.Use() gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) root.DrawBy(image.Point{}, func(w *widget.Widget, corner image.Point) { var texture gl.Texture if w.Image != nil { texture = gl.GenTexture() texture.Bind(gl.TEXTURE_2D) gl.ActiveTexture(gl.TEXTURE0) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w.Image.Rect.Dx(), w.Image.Rect.Dy(), 0, gl.RGBA, gl.UNSIGNED_BYTE, w.Image.Pix) } leftX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0 leftY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy()) rightX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0 rightY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy()) bottomX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0 bottomY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy()) topX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0 topY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy()) vertices := []float32{ leftX, leftY, rightX, rightY, bottomX, bottomY, topX, topY, } texturePoints := []float32{ 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, } s_picture := program.GetUniformLocation("s_picture") s_picture.Uniform1i(0) has_picture := program.GetUniformLocation("has_picture") if w.Image != nil { has_picture.Uniform1i(1) } else { has_picture.Uniform1i(0) } col := program.GetUniformLocation("color") r, g, b, a := w.Background.RGBA() col.Uniform4f(float32(r)/float32(0xFFFF), float32(g)/float32(0xFFFF), float32(b)/float32(0xFFFF), float32(a)/float32(0xFFFF)) gl.PixelStorei(gl.UNPACK_ALIGNMENT, gl.UNSIGNED_BYTE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) a_position := program.GetAttribLocation("a_position") a_position.AttribPointer(2, gl.FLOAT, false, 0, vertices) a_position.EnableArray() a_coord := program.GetAttribLocation("a_coord") a_coord.AttribPointer(2, gl.FLOAT, false, 0, texturePoints) a_coord.EnableArray() gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) gl.Flush() texture.Delete() if len(w.Text) > 0 { rct := w.Rect rct.Max = rct.Max.Sub(w.Rect.Min) rct.Min = rct.Min.Sub(w.Rect.Min) fg := image.NewRGBA(rct) fgu := image.NewUniform(color.RGBA{0, 16, 32, 255}) draw.Draw(fg, fg.Bounds(), fgu, image.ZP, draw.Src) bg := image.NewRGBA(rct) bgu := image.NewUniform(color.RGBA{255, 255, 255, 255}) draw.Draw(bg, bg.Bounds(), bgu, image.ZP, draw.Src) lineHeight := 20.0 fc.SetDPI(100.0) fc.SetFont(font) fc.SetFontSize(12.0) fc.SetClip(bg.Bounds()) fc.SetDst(bg) fc.SetSrc(fg) p0 := ft.Pt(w.Padding.Min.X, w.Padding.Min.Y) p := p0 for _, s := range w.Text { p, _ = fc.DrawString(string(s), p) if int(p.X>>8) > rct.Max.X-w.Padding.Max.X-w.Padding.Min.X { p.X = p0.X p.Y += raster.Fix32(lineHeight * 256) } } var texture gl.Texture if bg != nil { texture = gl.GenTexture() texture.Bind(gl.TEXTURE_2D) gl.ActiveTexture(gl.TEXTURE0) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, bg.Rect.Dx(), bg.Rect.Dy(), 0, gl.RGBA, gl.UNSIGNED_BYTE, bg.Pix) } leftX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0 leftY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy()) rightX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0 rightY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy()) bottomX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0 bottomY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy()) topX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0 topY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy()) vertices := []float32{ leftX, leftY, rightX, rightY, bottomX, bottomY, topX, topY, } texturePoints := []float32{ 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, } s_picture := program.GetUniformLocation("s_picture") s_picture.Uniform1i(0) has_picture := program.GetUniformLocation("has_picture") if bg != nil { has_picture.Uniform1i(1) } else { has_picture.Uniform1i(0) } col := program.GetUniformLocation("color") r, g, b, a := w.Background.RGBA() col.Uniform4f(float32(r)/float32(0xFFFF), float32(g)/float32(0xFFFF), float32(b)/float32(0xFFFF), float32(a)/float32(0xFFFF)) gl.PixelStorei(gl.UNPACK_ALIGNMENT, gl.UNSIGNED_BYTE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) a_position := program.GetAttribLocation("a_position") a_position.AttribPointer(2, gl.FLOAT, false, 0, vertices) a_position.EnableArray() a_coord := program.GetAttribLocation("a_coord") a_coord.AttribPointer(2, gl.FLOAT, false, 0, texturePoints) a_coord.EnableArray() gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) gl.Flush() texture.Delete() } }) window.SwapBuffers() glfw.PollEvents() } }
// LoadTruetype loads a truetype font from the given stream and // applies the given font scale in points. // // The low and high values determine the lower and upper rune limits // we should load for this font. For standard ASCII this would be: 32, 127. func LoadTruetype(r io.Reader, scale int32, low, high rune) (*Font, error) { data, err := ioutil.ReadAll(r) if err != nil { return nil, err } // Read the truetype font. ttf, err := truetype.Parse(data) if err != nil { return nil, err } // Create our FontConfig type. var fc FontConfig fc.Low = low fc.High = high fc.Glyphs = make(Charset, high-low+1) // Create an image, large enough to store all requested glyphs. // // We limit the image to 16 glyphs per row. Then add as many rows as // needed to encompass all glyphs, while making sure the resulting image // has power-of-two dimensions. gc := int32(len(fc.Glyphs)) glyphsPerRow := int32(16) glyphsPerCol := (gc / glyphsPerRow) + 1 gb := ttf.Bounds(scale) gw := (gb.XMax - gb.XMin) // why? gh := (gb.YMax - gb.YMin) + 5 iw := Pow2(uint32(gw * glyphsPerRow)) ih := Pow2(uint32(gh * glyphsPerCol)) fg, bg := image.White, image.Transparent rect := image.Rect(0, 0, int(iw), int(ih)) img := image.NewRGBA(rect) draw.Draw(img, img.Bounds(), bg, image.ZP, draw.Src) // Use a freetype context to do the drawing. c := freetype.NewContext() c.SetDPI(72) // Do not change this. It is required in order to have a properly aligned bounding box!!! c.SetFont(ttf) c.SetFontSize(float64(scale)) c.SetClip(img.Bounds()) c.SetDst(img) c.SetSrc(fg) // Iterate over all relevant glyphs in the truetype font and // draw them all to the image buffer. // // For each glyph, we also create a corresponding Glyph structure // for our Charset. It contains the appropriate glyph coordinate offsets. var gi int var gx, gy int32 for ch := low; ch <= high; ch++ { index := ttf.Index(ch) metric := ttf.HMetric(scale, index) fc.Glyphs[gi].Advance = int(metric.AdvanceWidth) fc.Glyphs[gi].X = int(gx) fc.Glyphs[gi].Y = int(gy) fc.Glyphs[gi].Width = int(gw) fc.Glyphs[gi].Height = int(gh) pt := freetype.Pt(int(gx), int(gy)+int(c.PointToFix32(float64(scale))>>8)) c.DrawString(string(ch), pt) if gi%16 == 0 { gx = 0 gy += gh } else { gx += gw } gi++ } return loadFont(img, &fc) }