func (p Page) Content() Content {
	strm := p.V.Key("Contents")
	var enc TextEncoding = &nopEncoder{}

	var g = gstate{
		Th:  1,
		CTM: ident,
	}

	var text []Text
	showText := func(s string) {
		n := 0
		for _, ch := range enc.Decode(s) {
			Trm := matrix{{g.Tfs * g.Th, 0, 0}, {0, g.Tfs, 0}, {0, g.Trise, 1}}.mul(g.Tm).mul(g.CTM)
			w0 := g.Tf.Width(int(s[n]))
			n++
			if ch != ' ' {
				f := g.Tf.BaseFont()
				if i := strings.Index(f, "+"); i >= 0 {
					f = f[i+1:]
				}
				text = append(text, Text{f, Trm[0][0], Trm[2][0], Trm[2][1], w0 / 1000 * Trm[0][0], string(ch)})
			}
			tx := w0/1000*g.Tfs + g.Tc
			if ch == ' ' {
				tx += g.Tw
			}
			tx *= g.Th
			g.Tm = matrix{{1, 0, 0}, {0, 1, 0}, {tx, 0, 1}}.mul(g.Tm)
		}
	}

	var rect []Rect
	var gstack []gstate
	Interpret(strm, func(stk *Stack, op string) {
		n := stk.Len()
		args := make([]Value, n)
		for i := n - 1; i >= 0; i-- {
			args[i] = stk.Pop()
		}
		switch op {
		default:
			//fmt.Println(op, args)
			return

		case "cm": // update g.CTM
			if len(args) != 6 {
				panic("bad g.Tm")
			}
			var m matrix
			for i := 0; i < 6; i++ {
				m[i/2][i%2] = args[i].Float64()
			}
			m[2][2] = 1
			g.CTM = m.mul(g.CTM)

		case "gs": // set parameters from graphics state resource
			gs := p.Resources().Key("ExtGState").Key(args[0].Name())
			font := gs.Key("Font")
			if font.Kind() == Array && font.Len() == 2 {
				//fmt.Println("FONT", font)
			}

		case "f": // fill
		case "g": // setgray
		case "l": // lineto
		case "m": // moveto

		case "cs": // set colorspace non-stroking
		case "scn": // set color non-stroking

		case "re": // append rectangle to path
			if len(args) != 4 {
				panic("bad re")
			}
			x, y, w, h := args[0].Float64(), args[1].Float64(), args[2].Float64(), args[3].Float64()
			rect = append(rect, Rect{Point{x, y}, Point{x + w, y + h}})

		case "q": // save graphics state
			gstack = append(gstack, g)

		case "Q": // restore graphics state
			n := len(gstack) - 1
			g = gstack[n]
			gstack = gstack[:n]

		case "BT": // begin text (reset text matrix and line matrix)
			g.Tm = ident
			g.Tlm = g.Tm

		case "ET": // end text

		case "T*": // move to start of next line
			x := matrix{{1, 0, 0}, {0, 1, 0}, {0, -g.Tl, 1}}
			g.Tlm = x.mul(g.Tlm)
			g.Tm = g.Tlm

		case "Tc": // set character spacing
			if len(args) != 1 {
				panic("bad g.Tc")
			}
			g.Tc = args[0].Float64()

		case "TD": // move text position and set leading
			if len(args) != 2 {
				panic("bad Td")
			}
			g.Tl = -args[1].Float64()
			fallthrough
		case "Td": // move text position
			if len(args) != 2 {
				panic("bad Td")
			}
			tx := args[0].Float64()
			ty := args[1].Float64()
			x := matrix{{1, 0, 0}, {0, 1, 0}, {tx, ty, 1}}
			g.Tlm = x.mul(g.Tlm)
			g.Tm = g.Tlm

		case "Tf": // set text font and size
			if len(args) != 2 {
				panic("bad TL")
			}
			f := args[0].Name()
			g.Tf = p.Font(f)
			enc = g.Tf.Encoder()
			if enc == nil {
				println("no cmap for", f)
				enc = &nopEncoder{}
			}
			g.Tfs = args[1].Float64()

		case "\"": // set spacing, move to next line, and show text
			if len(args) != 3 {
				panic("bad \" operator")
			}
			g.Tw = args[0].Float64()
			g.Tc = args[1].Float64()
			args = args[2:]
			fallthrough
		case "'": // move to next line and show text
			if len(args) != 1 {
				panic("bad ' operator")
			}
			x := matrix{{1, 0, 0}, {0, 1, 0}, {0, -g.Tl, 1}}
			g.Tlm = x.mul(g.Tlm)
			g.Tm = g.Tlm
			fallthrough
		case "Tj": // show text
			if len(args) != 1 {
				panic("bad Tj operator")
			}
			showText(args[0].RawString())

		case "TJ": // show text, allowing individual glyph positioning
			v := args[0]
			for i := 0; i < v.Len(); i++ {
				x := v.Index(i)
				if x.Kind() == String {
					showText(x.RawString())
				} else {
					tx := -x.Float64() / 1000 * g.Tfs * g.Th
					g.Tm = matrix{{1, 0, 0}, {0, 1, 0}, {tx, 0, 1}}.mul(g.Tm)
				}
			}

		case "TL": // set text leading
			if len(args) != 1 {
				panic("bad TL")
			}
			g.Tl = args[0].Float64()

		case "Tm": // set text matrix and line matrix
			if len(args) != 6 {
				panic("bad g.Tm")
			}
			var m matrix
			for i := 0; i < 6; i++ {
				m[i/2][i%2] = args[i].Float64()
			}
			m[2][2] = 1
			g.Tm = m
			g.Tlm = m

		case "Tr": // set text rendering mode
			if len(args) != 1 {
				panic("bad Tr")
			}
			g.Tmode = int(args[0].Int64())

		case "Ts": // set text rise
			if len(args) != 1 {
				panic("bad Ts")
			}
			g.Trise = args[0].Float64()

		case "Tw": // set word spacing
			if len(args) != 1 {
				panic("bad g.Tw")
			}
			g.Tw = args[0].Float64()

		case "Tz": // set horizontal text scaling
			if len(args) != 1 {
				panic("bad Tz")
			}
			g.Th = args[0].Float64() / 100
		}
	})
	return Content{text, rect}
}
func (p Page) Content() Content {
	strm := p.V.Key("Contents")
	var enc TextEncoding = &nopEncoder{}

	var g = gstate{
		Th:  1,
		CTM: ident,
	}

	var text []Text
	showText := func(s string) {
		n := 0
		for _, ch := range enc.Decode(s) {
			Trm := matrix{{g.Tfs * g.Th, 0, 0}, {0, g.Tfs, 0}, {0, g.Trise, 1}}.mul(g.Tm).mul(g.CTM)
			w0 := g.Tf.Width(int(s[n]))
			n++
			if ch != ' ' {
				f := g.Tf.BaseFont()
				if i := strings.Index(f, "+"); i >= 0 {
					f = f[i+1:]
				}
				text = append(text, Text{f, Trm[0][0], Trm[2][0], Trm[2][1], w0 / 1000 * Trm[0][0], string(ch)})
			}
			tx := w0/1000*g.Tfs + g.Tc
			if ch == ' ' {
				tx += g.Tw
			}
			tx *= g.Th
			g.Tm = matrix{{1, 0, 0}, {0, 1, 0}, {tx, 0, 1}}.mul(g.Tm)
		}
	}

	var rect []Rect
	var gstack []gstate
	Interpret(strm, func(stk *Stack, op string) {
		n := stk.Len()
		args := make([]Value, n)
		for i := n - 1; i >= 0; i-- {
			args[i] = stk.Pop()
		}
		switch op {
		default:
			
			return

		case "cm": 
			if len(args) != 6 {
				panic("bad g.Tm")
			}
			var m matrix
			for i := 0; i < 6; i++ {
				m[i/2][i%2] = args[i].Float64()
			}
			m[2][2] = 1
			g.CTM = m.mul(g.CTM)

		case "gs": 
			gs := p.Resources().Key("ExtGState").Key(args[0].Name())
			font := gs.Key("Font")
			if font.Kind() == Array && font.Len() == 2 {
				
			}

		case "f": 
		case "g": 
		case "l": 
		case "m": 

		case "cs": 
		case "scn": 

		case "re": 
			if len(args) != 4 {
				panic("bad re")
			}
			x, y, w, h := args[0].Float64(), args[1].Float64(), args[2].Float64(), args[3].Float64()
			rect = append(rect, Rect{Point{x, y}, Point{x + w, y + h}})

		case "q": 
			gstack = append(gstack, g)

		case "Q": 
			n := len(gstack) - 1
			g = gstack[n]
			gstack = gstack[:n]

		case "BT": 
			g.Tm = ident
			g.Tlm = g.Tm

		case "ET": 

		case "T*": 
			x := matrix{{1, 0, 0}, {0, 1, 0}, {0, -g.Tl, 1}}
			g.Tlm = x.mul(g.Tlm)
			g.Tm = g.Tlm

		case "Tc": 
			if len(args) != 1 {
				panic("bad g.Tc")
			}
			g.Tc = args[0].Float64()

		case "TD": 
			if len(args) != 2 {
				panic("bad Td")
			}
			g.Tl = -args[1].Float64()
			fallthrough
		case "Td": 
			if len(args) != 2 {
				panic("bad Td")
			}
			tx := args[0].Float64()
			ty := args[1].Float64()
			x := matrix{{1, 0, 0}, {0, 1, 0}, {tx, ty, 1}}
			g.Tlm = x.mul(g.Tlm)
			g.Tm = g.Tlm

		case "Tf": 
			if len(args) != 2 {
				panic("bad TL")
			}
			f := args[0].Name()
			g.Tf = p.Font(f)
			enc = g.Tf.Encoder()
			if enc == nil {
				println("no cmap for", f)
				enc = &nopEncoder{}
			}
			g.Tfs = args[1].Float64()

		case "\"": 
			if len(args) != 3 {
				panic("bad \" operator")
			}
			g.Tw = args[0].Float64()
			g.Tc = args[1].Float64()
			args = args[2:]
			fallthrough
		case "'": 
			if len(args) != 1 {
				panic("bad ' operator")
			}
			x := matrix{{1, 0, 0}, {0, 1, 0}, {0, -g.Tl, 1}}
			g.Tlm = x.mul(g.Tlm)
			g.Tm = g.Tlm
			fallthrough
		case "Tj": 
			if len(args) != 1 {
				panic("bad Tj operator")
			}
			showText(args[0].RawString())

		case "TJ": 
			v := args[0]
			for i := 0; i < v.Len(); i++ {
				x := v.Index(i)
				if x.Kind() == String {
					showText(x.RawString())
				} else {
					tx := -x.Float64() / 1000 * g.Tfs * g.Th
					g.Tm = matrix{{1, 0, 0}, {0, 1, 0}, {tx, 0, 1}}.mul(g.Tm)
				}
			}

		case "TL": 
			if len(args) != 1 {
				panic("bad TL")
			}
			g.Tl = args[0].Float64()

		case "Tm": 
			if len(args) != 6 {
				panic("bad g.Tm")
			}
			var m matrix
			for i := 0; i < 6; i++ {
				m[i/2][i%2] = args[i].Float64()
			}
			m[2][2] = 1
			g.Tm = m
			g.Tlm = m

		case "Tr": 
			if len(args) != 1 {
				panic("bad Tr")
			}
			g.Tmode = int(args[0].Int64())

		case "Ts": 
			if len(args) != 1 {
				panic("bad Ts")
			}
			g.Trise = args[0].Float64()

		case "Tw": 
			if len(args) != 1 {
				panic("bad g.Tw")
			}
			g.Tw = args[0].Float64()

		case "Tz": 
			if len(args) != 1 {
				panic("bad Tz")
			}
			g.Th = args[0].Float64() / 100
		}
	})
	return Content{text, rect}
}
func ( p Page ) Content ( ) Content { strm := p . V . Key ( " " ) var enc TextEncoding = & nopEncoder { } var g = gstate { Th : 1 , CTM : ident , } var text [ ] Text showText := func ( s string ) { n := 0 for _ , ch := range enc . Decode ( s ) { Trm := matrix { { g . Tfs * g . Th , 0 , 0 } , { 0 , g . Tfs , 0 } , { 0 , g . Trise , 1 } } . mul ( g . Tm ) . mul ( g . CTM ) w0 := g . Tf . Width ( int ( s [ n ] ) ) n ++ if ch != ' ' { f := g . Tf . BaseFont ( ) if i := strings . Index ( f , " " ) ; i >= 0 { f = f [ i + 1 : ] } text = append ( text , Text { f , Trm [ 0 ] [ 0 ] , Trm [ 2 ] [ 0 ] , Trm [ 2 ] [ 1 ] , w0 / 1000 * Trm [ 0 ] [ 0 ] , string ( ch ) } ) } tx := w0 / 1000 * g . Tfs + g . Tc if ch == ' ' { tx += g . Tw } tx *= g . Th g . Tm = matrix { { 1 , 0 , 0 } , { 0 , 1 , 0 } , { tx , 0 , 1 } } . mul ( g . Tm ) } } var rect [ ] Rect var gstack [ ] gstate Interpret ( strm , func ( stk * Stack , op string ) { n := stk . Len ( ) args := make ( [ ] Value , n ) for i := n - 1 ; i >= 0 ; i -- { args [ i ] = stk . Pop ( ) } switch op { default : //fmt.Println(op, args) return case " " : // update g.CTM if len ( args ) != 6 { panic ( " " ) } var m matrix for i := 0 ; i < 6 ; i ++ { m [ i / 2 ] [ i % 2 ] = args [ i ] . Float64 ( ) } m [ 2 ] [ 2 ] = 1 g . CTM = m . mul ( g . CTM ) case " " : // set parameters from graphics state resource gs := p . Resources ( ) . Key ( " " ) . Key ( args [ 0 ] . Name ( ) ) font := gs . Key ( " " ) if font . Kind ( ) == Array && font . Len ( ) == 2 { //fmt.Println("FONT", font) } case " " : // fill case " " : // setgray case " " : // lineto case " " : // moveto case " " : // set colorspace non-stroking case " " : // set color non-stroking case " " : // append rectangle to path if len ( args ) != 4 { panic ( " " ) } x , y , w , h := args [ 0 ] . Float64 ( ) , args [ 1 ] . Float64 ( ) , args [ 2 ] . Float64 ( ) , args [ 3 ] . Float64 ( ) rect = append ( rect , Rect { Point { x , y } , Point { x + w , y + h } } ) case " " : // save graphics state gstack = append ( gstack , g ) case " " : // restore graphics state n := len ( gstack ) - 1 g = gstack [ n ] gstack = gstack [ : n ] case " " : // begin text (reset text matrix and line matrix) g . Tm = ident g . Tlm = g . Tm case " " : // end text case " " : // move to start of next line x := matrix { { 1 , 0 , 0 } , { 0 , 1 , 0 } , { 0 , - g . Tl , 1 } } g . Tlm = x . mul ( g . Tlm ) g . Tm = g . Tlm case " " : // set character spacing if len ( args ) != 1 { panic ( " " ) } g . Tc = args [ 0 ] . Float64 ( ) case " " : // move text position and set leading if len ( args ) != 2 { panic ( " " ) } g . Tl = - args [ 1 ] . Float64 ( ) fallthrough case " " : // move text position if len ( args ) != 2 { panic ( " " ) } tx := args [ 0 ] . Float64 ( ) ty := args [ 1 ] . Float64 ( ) x := matrix { { 1 , 0 , 0 } , { 0 , 1 , 0 } , { tx , ty , 1 } } g . Tlm = x . mul ( g . Tlm ) g . Tm = g . Tlm case " " : // set text font and size if len ( args ) != 2 { panic ( " " ) } f := args [ 0 ] . Name ( ) g . Tf = p . Font ( f ) enc = g . Tf . Encoder ( ) if enc == nil { println ( " " , f ) enc = & nopEncoder { } } g . Tfs = args [ 1 ] . Float64 ( ) case " \" " : // set spacing, move to next line, and show text if len ( args ) != 3 { panic ( " \" " ) } g . Tw = args [ 0 ] . Float64 ( ) g . Tc = args [ 1 ] . Float64 ( ) args = args [ 2 : ] fallthrough case " " : // move to next line and show text if len ( args ) != 1 { panic ( " " ) } x := matrix { { 1 , 0 , 0 } , { 0 , 1 , 0 } , { 0 , - g . Tl , 1 } } g . Tlm = x . mul ( g . Tlm ) g . Tm = g . Tlm fallthrough case " " : // show text if len ( args ) != 1 { panic ( " " ) } showText ( args [ 0 ] . RawString ( ) ) case " " : // show text, allowing individual glyph positioning v := args [ 0 ] for i := 0 ; i < v . Len ( ) ; i ++ { x := v . Index ( i ) if x . Kind ( ) == String { showText ( x . RawString ( ) ) } else { tx := - x . Float64 ( ) / 1000 * g . Tfs * g . Th g . Tm = matrix { { 1 , 0 , 0 } , { 0 , 1 , 0 } , { tx , 0 , 1 } } . mul ( g . Tm ) } } case " " : // set text leading if len ( args ) != 1 { panic ( " " ) } g . Tl = args [ 0 ] . Float64 ( ) case " " : // set text matrix and line matrix if len ( args ) != 6 { panic ( " " ) } var m matrix for i := 0 ; i < 6 ; i ++ { m [ i / 2 ] [ i % 2 ] = args [ i ] . Float64 ( ) } m [ 2 ] [ 2 ] = 1 g . Tm = m g . Tlm = m case " " : // set text rendering mode if len ( args ) != 1 { panic ( " " ) } g . Tmode = int ( args [ 0 ] . Int64 ( ) ) case " " : // set text rise if len ( args ) != 1 { panic ( " " ) } g . Trise = args [ 0 ] . Float64 ( ) case " " : // set word spacing if len ( args ) != 1 { panic ( " " ) } g . Tw = args [ 0 ] . Float64 ( ) case " " : // set horizontal text scaling if len ( args ) != 1 { panic ( " " ) } g . Th = args [ 0 ] . Float64 ( ) / 100 } } ) return Content { text , rect } }
// Content returns the page's content.
Content returns the page s content .