Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use custom font and fill pentagram? #19

Open
gogolxdong opened this issue Feb 5, 2019 · 5 comments
Open

How to use custom font and fill pentagram? #19

gogolxdong opened this issue Feb 5, 2019 · 5 comments

Comments

@gogolxdong
Copy link

gogolxdong commented Feb 5, 2019

fontmanager.nim

when isMainModule:
  var ff: FontManager
  var dir = @["../demo/fonts"]
  ff.init(dir)

  for key, val in pairs(ff.ttFontList):
    echo key, ": ", val

KaiTi00: ../demo/fonts/simkai.ttf
Times New Roman00: ../demo/fonts/TimesNewRoman.ttf
FangSong00: ../demo/fonts/simfang.ttf
Eunjin00: ../demo/fonts/Eunjin.ttf
FreeMono00: ../demo/fonts/FreeMono.ttf
LFangSong00: ../demo/fonts/gongzhang.ttf
Calligrapher00: ../demo/fonts/calligra.ttf

setFont("LFangSong") but doesn't take effect.

I'm using demo.nim as a base , here is the code of drawing a pentagram without proper filling, thought recordShape helps, so I made the field accessible explicitly,

  var radius = 13.0
  var points : seq[Point2d]
  for i in 0..4:
    var angle = 2 * PI * i.float / 5 - PI / 2
    var x = cx + radius * cos(angle) 
    var y = cy + radius * sin(angle)
    points.add Point2d(x:x,y:y)
  doc.setLineWidth(0.1)
  doc.state.recordShape = true
  for i in 0..4:
    var point = points[i*2 mod 5]
    var nextPoint = points[(i+1)*2 mod 5]
    doc.moveTo(point)
    doc.lineTo(nextPoint)
    doc.stroke()
    doc.fill()

associated with some changes of lineTo as follows:

proc lineTo*(self: ContentBase, x, y: float64) =
  if self.state.recordShape:
    if self.state.shapes.len == 0:
      self.state.shapes.add(makePath())
    self.state.shapes[self.state.shapes.len - 1].addLine(self.state.pathStartX, self.state.pathStartY, x, y)
    if x == self.state.pathStartX and y == self.state.pathStartY:
      self.state.shapes.add(makePath())

it just doesn't fill the pentagram.

@jangko
Copy link
Owner

jangko commented Feb 6, 2019

setFont("LFangSong") but doesn't take effect.

perhaps your font doesn't have Regular font style, you need to specify the correct font style too.
please use overloaded setFont proc.
On windows, you can see the style using windows built in font preview tool.

doc.state.recordShape = true

you don't need to do this, it is for internal use

here is the code of drawing a pentagram without proper filling

you need to call closePath, because an open path cannot be filled.

I'm using demo.nim as a base

this is already a correct way to start using nimPDF

it just doesn't fill the pentagram.

please see demo/demo.nim to see examples how to create fillable shapes, and follow those examples closely.

@gogolxdong
Copy link
Author

gogolxdong commented Feb 7, 2019

Thanks for replying, custom font usage has been solved, it has FS_REGULAR.
We use doc.setFont("LFangSong", {FS_REGULAR}, 10) actually.
Yes, I missed closePath, but filling pentagram seems requiring more guide.

  var radius = 13.0
  var points : seq[Point2d]
  for i in 0..4:
    var angle = 2 * PI * i.float / 5 - PI / 2
    var x = cx + radius * cos(angle) 
    var y = cy + radius * sin(angle)
    points.add Point2d(x:x,y:y)
  doc.setLineWidth(0.1)
  doc.setFillColor(initRGB("red"))
  for i in 0..4:
    var point = points[i*2 mod 5]
    var nextPoint = points[(i+1)*2 mod 5]
    doc.moveTo(point)
    doc.lineTo(nextPoint)
  doc.closePath()
  doc.fill()

It lightens my pentagram instead of filling , how to get it to work?

@jangko
Copy link
Owner

jangko commented Feb 7, 2019

#doc.setFillColor(initRGB("maroon"))
doc.moveTo(points[0])
for i in 1..4:
  var point = points[i*2 mod 5]
  #var nextPoint = points[(i+1)*2 mod 5]
  doc.lineTo(point)
#doc.closePath()
doc.fill()

yeah, I forgot to mention you also cannot fill line segment. Calling moveTo will automatically close previous path. Usually you only call moveTo once at the beginning of the path and then draw the shape using lineTo, curveTo, arcTo, etc.

call closePath also optional because fill or fillAndStroke will automatically close the path for you if it detects open path.

But you still need to call closePath if you only want to stroke it. or leave it open then stroke an open path.

@gogolxdong
Copy link
Author

gogolxdong commented Feb 7, 2019

It fills the pentagram now. BTW, I don't quite understand setTextMatrix ,
1.why converts to fromMM to PT? What's the default unit of nimPDF , point or mm? What's the difference?
2.How to set text transformation properly using setTextMatrix, any reference?
Is there a proc to convert PDF to image format?

@jangko
Copy link
Owner

jangko commented Feb 7, 2019

  1. PDF specs says the default unit is point(pt), nimPDF use point, mm, and inch. actually, any user space units are converted to point before being drawn. please read PDF spec for detailed information.
  2. any matrix in PDF is ordinary 2d matrix, you need to read text on linear algebra or 2d graphics manipulation. or read PDF spec from adobe.
  3. nimPDF is a PDF document writer, it doesn't care how the PDF will be rendered by PDF reader. you could use any PDF to graphics converter. nimPDF does not have any renderer, that is beyond nimPDF domain. PDF to graphics is a renderer domain. (perhaps you could combine my nimPNG/nimBMP with nimAGG to render a PDF)

if anything you need is graphics and not a PDF, use a graphics renderer(nimAGG) although it is very dense and not easy to use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants