func renderPage(ctx *fz.Context, doc *fz.Document, pageIndex int, opt *RenderOption, buf []Pixel) { page := doc.LoadPage(pageIndex) defer doc.FreePage(page) var bounds fz.Rect doc.BoundPage(page, &bounds) zoom := float32(opt.Width) / bounds.X1 var transform fz.Matrix transform.Scale(zoom, zoom) bounds.Transform(&transform) var bbox fz.Irect bbox.RoundRect(&bounds) pix := ctx.NewPixmapWithBboxAndData(ctx.DeviceRgb(), &bbox, (*byte)(unsafe.Pointer(&buf[0]))) ctx.ClearPixmapWithValue(pix, 0xFF) dev := fz.NewDeviceHook(ctx.NewDrawDevice(pix)) defer dev.Free() var imgRects Rects dev.ImageHook = func(image *fz.Image, ctm *fz.Matrix, alpha float32) { pt := fz.Point{0, 0} pt.Transform(ctm) x, y := int(pt.X), int(pt.Y) w := round(sqrtf(ctm.A*ctm.A+ctm.B*ctm.B) + 1) h := round(sqrtf(ctm.C*ctm.C+ctm.D*ctm.D) + 1) imgRects = append(imgRects, &Rect{x, y, w, h}) } doc.RunPage(page, dev.ToDevice(), &transform, nil) if opt.Dark { pixels := buf off := 0 b := opt.Brightness bb := b * b for y := 0; y < int(pix.H); y++ { for x := 0; x < int(pix.W); x++ { pixel := pixels[off+x] rgb := color.RGBFromBytes(pixel.GetRGB()) if !imgRects.In(x, y) { hcl := rgb.ToHCL() hcl.L = 1 - hcl.L rgb = hcl.ToRGB() rgb.Times(b) } else { rgb.Times(bb) } pixels[off+x].SetRGB(rgb.ToBytes()) } off += int(pix.W) } } }
func (m *Model) setWidth(width int) { if width != m.Width { m.Width = width m.heights = make([]int, m.PageCount()) m.height = 0 for i := 0; i < m.PageCount(); i++ { page := m.doc.LoadPage(i) var bounds fz.Rect m.doc.BoundPage(page, &bounds) zoom := float32(width) / bounds.X1 var transform fz.Matrix transform.Scale(zoom, zoom) bounds.Transform(&transform) var bbox fz.Irect bbox.RoundRect(&bounds) m.height += int(bbox.Y1) m.heights[i] = int(bbox.Y1) m.doc.FreePage(page) } m.cache = make([]Pixel, m.Width*m.height) m.cached = make([]bool, m.PageCount()) } }