User Tools

Site Tools


pdf:paintingapage

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
pdf:paintingapage [2015/04/02 14:24] – [Painting Text] christianpdf:paintingapage [2016/02/24 17:49] (current) – [Hello World - How text gets onto a page] christian
Line 1: Line 1:
-====== How does text get onto a PDF page ======+====== Hello World - How text gets onto a page ======
  
 A PDF page has a content stream (**''/Contents''**) containing a list of graphics operator with their parameters. The operators are sequentially executed and can set aspects of the **GraphicsState** or paint in the context of the current GraphicsState. A PDF page has a content stream (**''/Contents''**) containing a list of graphics operator with their parameters. The operators are sequentially executed and can set aspects of the **GraphicsState** or paint in the context of the current GraphicsState.
Line 15: Line 15:
       /F1 10 Tf       /F1 10 Tf
       10 5 Td       10 5 Td
-      (Hello) Tj+      (Hello World) Tj
       ET       ET
     endstream     endstream
Line 21: Line 21:
 </code> </code>
  
-This paints the string 'Hello' in black at 10@5 with font **''/F1''** in size 10.+This paints the string ''Hello World'' in black at 10@5 with font **''/F1''** in size 10.
  
 To achieve this in Smalltalk you can write the following: To achieve this in Smalltalk you can write the following:
 <code smalltalk> <code smalltalk>
-page := Page newInBounds: (0 @ 0 corner: 50 @ 20) colorspace: DeviceCMYK new render: [:renderer |+page := Page newInBounds: (0 @ 0 corner: 70 @ 20) colorspace: DeviceCMYK new render: [:renderer |
   renderer fillColor: CmykColor black.   renderer fillColor: CmykColor black.
   renderer textObjectDo: [   renderer textObjectDo: [
     renderer setFont: #Helvetica size: 10.     renderer setFont: #Helvetica size: 10.
-    renderer add: (TextPositioningOperator Td operands: #(10 5)). +    renderer add: (NextLineRelative operands: #(10 5)). 
-    renderer showString: 'Hello']].+    renderer showString: 'Hello World']].
 </code> </code>
 +{{demo01_HelloWorld.pdf}} See the class method ''demo01_HelloWorld'' in class ''Document''.
 +
 You notice that I did not use the font ID **''/F1''** but the font directly (referenced as the global #Helvetica). ''renderer **setFont:**'' takes care of that and puts the font into the resources and assigns it to an internal name which is used in the content stream. This mechanism works for all resource types so that the programmer can always use the appropriate object directly and never needs to care about the internal IDs. You notice that I did not use the font ID **''/F1''** but the font directly (referenced as the global #Helvetica). ''renderer **setFont:**'' takes care of that and puts the font into the resources and assigns it to an internal name which is used in the content stream. This mechanism works for all resource types so that the programmer can always use the appropriate object directly and never needs to care about the internal IDs.
  
 The renderer you get when creating a Page takes care of the **''/Contents''** stream with its **''/Resources''** dictionary. The renderer you get when creating a Page takes care of the **''/Contents''** stream with its **''/Resources''** dictionary.
  
-Common operators are implemented as renderer methods like **''fillColor:''** and **''showString:''**, but not all. In the end, all these methods boil down to expressions creating operators and adding them to the renderer as done with the **''Td''** operator.+Common operators are implemented as renderer methods like **''fillColor:''** and **''showString:''**, but not all. In the end, all these methods boil down to expressions creating operators and adding them to the renderer as done with the **''NextLineRelative (Td)''** operator.
  
-**''Td''** is not covered by a convenience method of the renderer, because there are several ways to put text on a page - and using **''Td''** is not a very practical one.+**''NextLineRelative''** is not covered by a convenience method of the renderer, because there are several ways to put text on a page - and using **''NextLineRelative''** is not a very practical one.
  
 ===== Painting Text ===== ===== Painting Text =====
Line 46: Line 48:
  
   * set the relevant graphics state parameters including the font   * set the relevant graphics state parameters including the font
- 
   * set the position/Matrix   * set the position/Matrix
- 
   * show the string   * show the string
  
-While the state parameters are straight forward (see list below), positioning the string is best done using a matrix. The text matrix is set by **''Tm''** with 6 numbers as parameters.+While the state parameters are straight forward (see list below), positioning the string is best done using a matrix. The text matrix is set by **''SetTextMatrix (Tm)''** operator with 6 numbers as parameters.
 <code smalltalk> <code smalltalk>
-(TextPositioningOperator Tm operands: #(1 0 0 1 10 5))+(SetTextMatrix operands: #(1 0 0 1 10 5))
 </code> </code>
 produces produces
Line 65: Line 65:
   9.5 0 0 10 10 5 Tm   9.5 0 0 10 10 5 Tm
  
-The text state operators: +The text state operators are
-  * **''Tf''** text font and size +  * **''TextFont (Tf)''** 
-  * **''Tr''** rendering mode +  * **''TextRenderingMode (Tr)''** 
-  * **''Tc''** character spacing +  * **''CharacterSpacing (Tc)''** 
-  * **''Tw''** word spacing +  * **''WordSpacing (Tw)''** 
-  * **''TL''** text leading +  * **''Leading (TL)''** 
-  * **''Ts''** rise +  * **''TextRise (Ts)''** 
-  * **''Th''** horizontal scaling (should be done with Tm).+  * **''HorizontalScaling (Th)''** (should better be done with Tm).
  
 The two relevant text showing operators are: The two relevant text showing operators are:
  
-  * **''Tj''** show string +  * **''ShowText (Tj)''** 
-  * **''TJ''** show string with individual character positioning+  * **''ShowTextPositioned (TJ)''** show string with individual character positioning
  
 There are no high-level operations for word wrapping, automatic kerning, hyphenization or even simple justification. This is only about putting characters at specific positions. How you get these positions is up to you or your layout program. There are no high-level operations for word wrapping, automatic kerning, hyphenization or even simple justification. This is only about putting characters at specific positions. How you get these positions is up to you or your layout program.
Line 96: Line 96:
 The implementation may look at bit clumsy. Why should you use The implementation may look at bit clumsy. Why should you use
 <code smalltalk> <code smalltalk>
-renderer add: (TextPositioningOperator Td operands: #(10 5))+renderer add: (NextLineRelative operands: #(10 5))
 </code> </code>
-to get the simple string `'10 5 Td'`?+to get the simple string ''10 5 Td''?
  
-Firstly, I wanted operators as objects and not just as strings you write into the contents stream. The objects can be read from a PDF (try: from the PDFExplorer inspect a **/Contents** object and send it `#operations`) and the list of operator you create can be written to a PDF. There are some things a program could do with operators:+Firstly, I wanted operators as objects and not just as strings you write into the contents stream. The objects can be read from a PDF (try: from the [[PDFExplorer]] inspect a **''/Contents''** object and send it ''#operations'') and the list of operator you create can be written to a PDF. There are some things a program could do with operators:
  
-  * check the consistency/validity. F.ex. /BT must be written before /ET and must enclose certain text operators; they cannot be nested etc. etc.+  * check the consistency/validity. F.ex. **''BeginText (BT)''** must be written before **''EndText (ET)''** and must enclose certain text operators; they cannot be nested etc. etc.
   * implement a GraphicsState object to track the changes to it. With this, unneccessary operators can be avoided (this is on my todo list).   * implement a GraphicsState object to track the changes to it. With this, unneccessary operators can be avoided (this is on my todo list).
  
 In any case, it is good to have operators referable in the development image. In any case, it is good to have operators referable in the development image.
- 
-Operators have a name and arguments, the operands. There are subclasses for each group of operators. They don't add state, but allow for different behavior (which is not exploited yet). An operator is created by sending the appropriate class message to the corresponding Operator class. 
-<code smalltalk> 
-TextPositioningOperator Td 
-</code> 
-The operands are added with 
-<code smalltalk> 
-<operator> operands: <anArrayOfValues> 
-</code> 
-which returns a copy of the operator with the operands. 
- 
-I am not sure that this design will stand the time. I will see when I use it in ernest. 
  
 Secondly, this clumsy interface is meant to be used as backend by a higher level graphics framework. It is expected that you have an abstraction of **Text** which can render itself using the PDF primitives. In [[http://www.smallcharts.com|smallCharts]] I have Texts like Secondly, this clumsy interface is meant to be used as backend by a higher level graphics framework. It is expected that you have an abstraction of **Text** which can render itself using the PDF primitives. In [[http://www.smallcharts.com|smallCharts]] I have Texts like
Line 147: Line 135:
 I like to develop my abstractions from the bottom up and try to keep them as simple as possible. Maybe, over time, users will develop abstractions which are generally useful. In the end it should be a community discussion and consensus of what should be included. So far, only the bare metal on the spec will be available and you have to evolve your own abstractions. I like to develop my abstractions from the bottom up and try to keep them as simple as possible. Maybe, over time, users will develop abstractions which are generally useful. In the end it should be a community discussion and consensus of what should be included. So far, only the bare metal on the spec will be available and you have to evolve your own abstractions.
  
-==== Comments ====+===== Comments =====
  
-=== Higher level abstractions ===+==== Higher level abstractions ====
  
 Submitted by bobcalco on Tue, 2012-01-24 10:32. Submitted by bobcalco on Tue, 2012-01-24 10:32.
Line 161: Line 149:
 I know about this because I used an earlier version of Prawn to code a PDF generation feature of a content delivery system, which I am now needing to replace in Smalltalk, having decided to make the switch. I am a bit sad at the state of PDF generation in Smalltalk. There are so many other strengths in Smalltalk for the kind of distributed system I am building that wooed me over, but this deficiency is going to cost me some late nights and lamp oil. I know about this because I used an earlier version of Prawn to code a PDF generation feature of a content delivery system, which I am now needing to replace in Smalltalk, having decided to make the switch. I am a bit sad at the state of PDF generation in Smalltalk. There are so many other strengths in Smalltalk for the kind of distributed system I am building that wooed me over, but this deficiency is going to cost me some late nights and lamp oil.
  
-=== Here is a PDF manual ===+==== Here is a PDF manual ====
  
 Submitted by bobcalco on Tue, 2012-01-24 12:03. Submitted by bobcalco on Tue, 2012-01-24 12:03.
Line 169: Line 157:
 http://prawn.majesticseacreature.com/manual.pdf external http://prawn.majesticseacreature.com/manual.pdf external
  
-=== Re: Higher level abstractions ===+==== Re: Higher level abstractions ====
  
 Submitted by ChristianHaider on Tue, 2012-01-24 11:58. Submitted by ChristianHaider on Tue, 2012-01-24 11:58.
Line 175: Line 163:
 Interesting. I am curious what experiences you have while porting from Prawn to PDF4Smalltalk. Maybe some good concepts can be integrated... If you have any questions, please ask in the forum - sometimes I am responsive :-) Interesting. I am curious what experiences you have while porting from Prawn to PDF4Smalltalk. Maybe some good concepts can be integrated... If you have any questions, please ask in the forum - sometimes I am responsive :-)
  
-=== Thanks! ===+==== Thanks! ====
  
 Submitted by bobcalco on Tue, 2012-01-24 12:06. Submitted by bobcalco on Tue, 2012-01-24 12:06.
/var/www/virtual/code4hl/html/dokuwiki/data/attic/pdf/paintingapage.1427977498.txt.gz · Last modified: 2015/04/02 14:24 by christian